Unified · Split
| @@ -1,4 +1,4 @@ | ||
| 1 | −Lua COPYRIGHT NOTICE | |
| 1 | +Lua Copyright Notice | |
| 2 | 2 | -------------------- |
| 3 | 3 | |
| 4 | 4 | Lua is free and non-proprietary. |
| @@ -8,44 +8,47 @@ Lua (probably) qualifies as Open Source software. · 3 unmodified lines | ||
| 8 | 8 | Nevertheless, Lua is not in the public domain and TeCGraf keeps its copyright. |
| 9 | 9 | |
| 10 | 10 | If you use Lua, please give us credit (a nice way to do this is to include a |
| 11 | −logo in a web page for your product), but we would appreciate *not* receiving | |
| 12 | −lengthy legal documents to sign. | |
| 11 | +Lua logo in a web page for your product), but we would appreciate *not* | |
| 12 | +receiving lengthy legal documents to sign. | |
| 13 | 13 | |
| 14 | 14 | The legal details are below. |
| 15 | 15 | |
| 16 | 16 | =============================================================================== |
| 17 | 17 | |
| 18 | −Copyright (c) 1994-1999 TeCGraf, PUC-Rio. All rights reserved. | |
| 18 | +Copyright (C) 1994-2000 TeCGraf, PUC-Rio. All rights reserved. | |
| 19 | 19 | |
| 20 | 20 | Permission is hereby granted, without written agreement and without license |
| 21 | −or royalty fees, to use, copy, modify, and distribute this software and its | |
| 22 | −documentation for any purpose, including commercial applications, subject to | |
| 21 | +or royalty fees, to use, copy, modify, translate, and distribute | |
| 22 | +this software and its documentation (hereby called the "package") | |
| 23 | +for any purpose, including commercial applications, subject to | |
| 23 | 24 | the following conditions: |
| 24 | 25 | |
| 25 | 26 | * The above copyright notice and this permission notice shall appear in all |
| 26 | − copies or substantial portions of this software. | |
| 27 | + copies or substantial portions of this package. | |
| 27 | 28 | |
| 28 | − * The origin of this software must not be misrepresented; you must not | |
| 29 | − claim that you wrote the original software. If you use this software in a | |
| 29 | + * The origin of this package must not be misrepresented; you must not | |
| 30 | + claim that you wrote the original package. If you use this package in a | |
| 30 | 31 | product, an acknowledgment in the product documentation would be greatly |
| 31 | 32 | appreciated (but it is not required). |
| 32 | 33 | |
| 33 | 34 | * Altered source versions must be plainly marked as such, and must not be |
| 34 | − misrepresented as being the original software. | |
| 35 | + misrepresented as being the original package. | |
| 35 | 36 | |
| 36 | 37 | The authors specifically disclaim any warranties, including, but not limited |
| 37 | 38 | to, the implied warranties of merchantability and fitness for a particular |
| 38 | −purpose. The software provided hereunder is on an "as is" basis, and the | |
| 39 | +purpose. The package provided hereunder is on an "as is" basis, and the | |
| 39 | 40 | authors have no obligation to provide maintenance, support, updates, |
| 40 | 41 | enhancements, or modifications. In no event shall TeCGraf, PUC-Rio, or the |
| 41 | 42 | authors be held liable to any party for direct, indirect, special, |
| 42 | −incidental, or consequential damages arising out of the use of this software | |
| 43 | +incidental, or consequential damages arising out of the use of this package | |
| 43 | 44 | and its documentation. |
| 44 | 45 | |
| 45 | 46 | The Lua language and this implementation have been entirely designed and written |
| 46 | 47 | by Waldemar Celes, Roberto Ierusalimschy, and Luiz Henrique de Figueiredo |
| 47 | −at TeCGraf, PUC-Rio. | |
| 48 | +at TeCGraf, PUC-Rio in Brazil. | |
| 48 | 49 | |
| 49 | 50 | This implementation contains no third-party code. |
| 50 | 51 | |
| 51 | 52 | =============================================================================== |
| 53 | + | |
| 54 | +(end of COPYRIGHT) | |
| @@ -1,4 +1,32 @@ | ||
| 1 | −This is Lua 3.2 | |
| 1 | +This is Lua 4.0. | |
| 2 | + | |
| 3 | +* Changes from version 3.2 to 4.0 | |
| 4 | + ------------------------------- | |
| 5 | + Language: | |
| 6 | + + new "break" and "for" statements (both numerical and for tables). | |
| 7 | + + uniform treatment of globals: globals are now stored in a Lua table. | |
| 8 | + + improved error messages. | |
| 9 | + + no more '$debug': full speed *and* full debug information. | |
| 10 | + + new read form: read(N) for next N bytes. | |
| 11 | + + general read patterns now deprecated. | |
| 12 | + (still available with -DCOMPAT_READPATTERNS.) | |
| 13 | + + all return values are passed as arguments for the last function | |
| 14 | + (old semantics still available with -DLUA_COMPAT_ARGRET) | |
| 15 | + + garbage collection tag methods for tables now deprecated. | |
| 16 | + + there is now only one tag method for order. | |
| 17 | + API: | |
| 18 | + + New API: fully re-entrant, simpler, and more efficient. | |
| 19 | + + New debug API. | |
| 20 | + Implementation: | |
| 21 | + + cleaner virtual machine -- at least 20% faster. | |
| 22 | + + non-recursive garbage-collector algorithm. | |
| 23 | + + reduced memory usage for programs with many strings. | |
| 24 | + + improved treatment for memory allocation errors. | |
| 25 | + + improved support for 16-bit machines (we hope). | |
| 26 | + + code now compiles unmodified as both ANSI C and C++. | |
| 27 | + + numbers in bases other than 10 are converted using strtoul. | |
| 28 | + + new -f option in Lua to support #! scripts. | |
| 29 | + + luac can now combine text and binaries. | |
| 2 | 30 | |
| 3 | 31 | * Changes from version 3.1 to 3.2 |
| 4 | 32 | ------------------------------- |
| @@ -79,3 +107,5 @@ This is Lua 3.2 · 74 unmodified lines | ||
| 79 | 107 | + fallbacks |
| 80 | 108 | + simplified syntax for tables |
| 81 | 109 | + many internal improvements |
| 110 | + | |
| 111 | +(end of HISTORY) | |
| @@ -1,11 +1,14 @@ | ||
| 1 | −This is Lua 3.2 | |
| 1 | +This is Lua 4.0. | |
| 2 | 2 | |
| 3 | 3 | * Installation |
| 4 | 4 | ------------ |
| 5 | 5 | Building Lua on a Unix system should be very easy: |
| 6 | 6 | |
| 7 | 7 | 1. Edit "config" to suit your platform, if at all necessary. |
| 8 | − 2. Then, type "make". | |
| 8 | + 2. Do "make". | |
| 9 | + 3. If you want to install Lua in an "official" place in your system, | |
| 10 | + then do "make install". The official place and the way to install | |
| 11 | + files are defined in "config". You may have to be root to do this. | |
| 9 | 12 | |
| 10 | 13 | See below for instructions for Windows and Macintosh. |
| 11 | 14 | |
| @@ -17,55 +20,53 @@ This is Lua 3.2 · 5 unmodified lines | ||
| 17 | 20 | * include files in ./include. |
| 18 | 21 | These are the only directories you need for development. |
| 19 | 22 | |
| 20 | − There is a reference manual in html in ./doc, some sample code in ./test, | |
| 21 | − and some useful stuff in ./etc. | |
| 22 | − You don't need these directories for development. | |
| 23 | + There man pages for lua and luac in both nroff and html, and a reference | |
| 24 | + manual in html in ./doc, some sample code in ./test, and some useful stuff | |
| 25 | + in ./etc. You don't need these directories for development. | |
| 23 | 26 | |
| 24 | 27 | See also the README files in the various subdirectories. |
| 25 | − A convenient staring point is ./doc/readme.html. | |
| 28 | + A convenient starting point is ./doc/readme.html. | |
| 26 | 29 | |
| 27 | 30 | * If you have problems (and solutions!) |
| 28 | 31 | ------------------------------------- |
| 29 | 32 | If "make" fails, please let us know (lua@tecgraf.puc-rio.br). |
| 30 | − If you make changes to "config", please send them to us. | |
| 33 | + If you make changes to "config" or to the Makefiles, please send them to us. | |
| 31 | 34 | |
| 32 | 35 | * Shared libraries |
| 33 | 36 | ---------------- |
| 34 | − If you are running SunOs 4.x, type the following after "make" succeeds: | |
| 35 | − ld -o lib/liblua.so.3.2 src/*.o | |
| 36 | − ld -o lib/liblualib.so.3.2 src/lib/*.o | |
| 37 | + If you are running Linux, do "make so" after "make" succeeds. | |
| 38 | + This will create shared libraries in ./lib. It's probably better to | |
| 39 | + build shared libraries before "make install". | |
| 37 | 40 | |
| 38 | − If you are running Linux, type the following after "make" succeeds: | |
| 39 | − ld -o lib/liblua.so.3.2 -shared src/*.o | |
| 40 | − ld -o lib/liblualib.so.3.2 -shared src/lib/*.o | |
| 41 | − cd lib | |
| 42 | − ln -s liblua.so.3.2 liblua.so | |
| 43 | − ln -s liblualib.so.3.2 liblualib.so.3.2 | |
| 41 | + If you want the interpreter and the compiler to use shared libraries, | |
| 42 | + then do "make sobin" too. | |
| 44 | 43 | |
| 45 | − If you want the interpreter to use shared libraries, then do this too: | |
| 46 | − rm bin/lua | |
| 47 | − cd src/lua; make | |
| 48 | − You may need to include lib/ in the LD_LIBRAY_PATH environment variable. | |
| 44 | + You may need to include lib/ in the LD_LIBRAY_PATH environment variable | |
| 45 | + to link programs that use the shared libraries if you don't put them in | |
| 46 | + the "official" places with "make install". | |
| 49 | 47 | |
| 50 | − Building shared libraries in other systems is similar but details differ. | |
| 48 | + Building shared libraries in other systems is similar but details differ; | |
| 49 | + you may need to fix a few details in the top-level Makefile. | |
| 51 | 50 | |
| 52 | 51 | * Installation on Windows or Macintosh |
| 53 | 52 | ------------------------------------ |
| 54 | 53 | The instructions for building Lua on a Mac or Windows machine depend on |
| 55 | 54 | the particular compiler you are using. |
| 56 | 55 | The simplest way is to create a folder with all .c and .h files. |
| 57 | − Then create projects for the basic library, the standard library, | |
| 58 | − the interpreter and the compiler, as follows: | |
| 56 | + Then create projects for the core library, the standard library, | |
| 57 | + the interpreter, and the compiler, as follows: | |
| 59 | 58 | |
| 60 | − basic lib: lapi.c lauxlib.c lbuffer.c lbuiltin.c ldo.c lfunc.c lgc.c | |
| 61 | − llex.c lmem.c lobject.c lparser.c lstate.c lstring.c ltable.c | |
| 59 | + core lib: lapi.c lcode.c ldebug.c ldo.c lfunc.c lgc.c llex.c lmem.c | |
| 60 | + lobject.c lparser.c lstate.c lstring.c ltable.c ltests.c | |
| 62 | 61 | ltm.c lundump.c lvm.c lzio.c |
| 63 | 62 | |
| 64 | − standard lib: linit.c ldblib.c liolib.c lmathlib.c lstrlib.c | |
| 63 | + standard lib: lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c lstrlib.c | |
| 65 | 64 | |
| 66 | − interpreter: basic lib, standard lib, lua.c | |
| 65 | + interpreter: core lib, standard lib, lua.c | |
| 67 | 66 | |
| 68 | − compiler: basic lib, dump.c luac.c opcode.c opt.c print.c stubs.c test.c | |
| 67 | + compiler: core lib, dump.c luac.c opt.c print.c stubs.c | |
| 69 | 68 | |
| 70 | 69 | Of course, to use Lua as a library, you'll have to know how to create |
| 71 | 70 | and use libraries with your compiler. |
| 71 | + | |
| 72 | +(end of INSTALL) | |
| @@ -1,4 +1,4 @@ | ||
| 1 | −MANIFEST contents of Lua 3.2 distribution on Thu Jul 8 10:34:45 EST 1999 | |
| 1 | +MANIFEST contents of Lua 4.0 distribution on Mon Nov 6 19:15:16 EDT 2000 | |
| 2 | 2 | lua |
| 3 | 3 | lua/COPYRIGHT |
| 4 | 4 | lua/HISTORY |
| @@ -11,16 +11,24 @@ lua/config · 6 unmodified lines | ||
| 11 | 11 | lua/doc |
| 12 | 12 | lua/doc/idx.html |
| 13 | 13 | lua/doc/index.html |
| 14 | +lua/doc/logo.gif | |
| 15 | +lua/doc/lua.1 | |
| 16 | +lua/doc/lua.html | |
| 17 | +lua/doc/luac.1 | |
| 14 | 18 | lua/doc/luac.html |
| 15 | −lua/doc/luac.man | |
| 16 | 19 | lua/doc/manual.html |
| 17 | 20 | lua/doc/readme.html |
| 18 | 21 | lua/etc |
| 19 | 22 | lua/etc/Makefile |
| 20 | 23 | lua/etc/README |
| 21 | 24 | lua/etc/bin2c.c |
| 25 | +lua/etc/def.lua | |
| 26 | +lua/etc/lua.ico | |
| 27 | +lua/etc/lua.magic | |
| 28 | +lua/etc/lua.xpm | |
| 22 | 29 | lua/etc/min.c |
| 23 | 30 | lua/etc/setfallback.lua |
| 31 | +lua/etc/stdcall.lua | |
| 24 | 32 | lua/etc/trace.c |
| 25 | 33 | lua/include |
| 26 | 34 | lua/include/Makefile |
| @@ -33,10 +41,10 @@ lua/src · 6 unmodified lines | ||
| 33 | 41 | lua/src/Makefile |
| 34 | 42 | lua/src/lapi.c |
| 35 | 43 | lua/src/lapi.h |
| 36 | −lua/src/lauxlib.c | |
| 37 | −lua/src/lbuffer.c | |
| 38 | −lua/src/lbuiltin.c | |
| 39 | −lua/src/lbuiltin.h | |
| 44 | +lua/src/lcode.c | |
| 45 | +lua/src/lcode.h | |
| 46 | +lua/src/ldebug.c | |
| 47 | +lua/src/ldebug.h | |
| 40 | 48 | lua/src/ldo.c |
| 41 | 49 | lua/src/ldo.h |
| 42 | 50 | lua/src/lfunc.c |
| @@ -46,13 +54,15 @@ lua/src/lgc.h · 3 unmodified lines | ||
| 46 | 54 | lua/src/lib |
| 47 | 55 | lua/src/lib/Makefile |
| 48 | 56 | lua/src/lib/README |
| 57 | +lua/src/lib/lauxlib.c | |
| 58 | +lua/src/lib/lbaselib.c | |
| 49 | 59 | lua/src/lib/ldblib.c |
| 50 | −lua/src/lib/linit.c | |
| 51 | 60 | lua/src/lib/liolib.c |
| 52 | 61 | lua/src/lib/lmathlib.c |
| 53 | 62 | lua/src/lib/lstrlib.c |
| 54 | 63 | lua/src/llex.c |
| 55 | 64 | lua/src/llex.h |
| 65 | +lua/src/llimits.h | |
| 56 | 66 | lua/src/lmem.c |
| 57 | 67 | lua/src/lmem.h |
| 58 | 68 | lua/src/lobject.c |
| @@ -66,6 +76,7 @@ lua/src/lstring.c · 7 unmodified lines | ||
| 66 | 76 | lua/src/lstring.h |
| 67 | 77 | lua/src/ltable.c |
| 68 | 78 | lua/src/ltable.h |
| 79 | +lua/src/ltests.c | |
| 69 | 80 | lua/src/ltm.c |
| 70 | 81 | lua/src/ltm.h |
| 71 | 82 | lua/src/lua |
| @@ -78,12 +89,10 @@ lua/src/luac/README · 6 unmodified lines | ||
| 78 | 89 | lua/src/luac/dump.c |
| 79 | 90 | lua/src/luac/luac.c |
| 80 | 91 | lua/src/luac/luac.h |
| 81 | −lua/src/luac/opcode.c | |
| 82 | −lua/src/luac/opcode.h | |
| 83 | 92 | lua/src/luac/opt.c |
| 84 | 93 | lua/src/luac/print.c |
| 94 | +lua/src/luac/print.h | |
| 85 | 95 | lua/src/luac/stubs.c |
| 86 | −lua/src/luac/test.c | |
| 87 | 96 | lua/src/lundump.c |
| 88 | 97 | lua/src/lundump.h |
| 89 | 98 | lua/src/lvm.c |
| @@ -92,8 +101,8 @@ lua/src/lzio.c · 2 unmodified lines | ||
| 92 | 101 | lua/src/lzio.h |
| 93 | 102 | lua/test |
| 94 | 103 | lua/test/README |
| 95 | −lua/test/array.lua | |
| 96 | 104 | lua/test/bisect.lua |
| 105 | +lua/test/cf-for.lua | |
| 97 | 106 | lua/test/cf.lua |
| 98 | 107 | lua/test/examples |
| 99 | 108 | lua/test/examples/ps |
| @@ -108,9 +117,17 @@ lua/test/factorial.lua · 8 unmodified lines | ||
| 108 | 117 | lua/test/fib.lua |
| 109 | 118 | lua/test/globals.lua |
| 110 | 119 | lua/test/hello.lua |
| 120 | +lua/test/life.lua | |
| 121 | +lua/test/lisp.lua | |
| 111 | 122 | lua/test/lua |
| 112 | 123 | lua/test/luac |
| 124 | +lua/test/old.lua | |
| 125 | +lua/test/qp.lua | |
| 113 | 126 | lua/test/save.lua |
| 114 | 127 | lua/test/sort.lua |
| 115 | −lua/test/trace.lua | |
| 128 | +lua/test/table.lua | |
| 129 | +lua/test/trace-calls.lua | |
| 130 | +lua/test/trace-globals.lua | |
| 131 | +lua/test/undefined.lua | |
| 132 | +lua/test/webform.lua | |
| 116 | 133 | END OF MANIFEST |
| @@ -1,11 +1,41 @@ | ||
| 1 | −# makefile for lua hierarchy | |
| 1 | +# makefile for Lua hierarchy | |
| 2 | +# see INSTALL for installation instructions | |
| 3 | +# see file "config" for customization instructions | |
| 2 | 4 | |
| 3 | −all co clean klean: | |
| 5 | +LUA= . | |
| 6 | + | |
| 7 | +include $(LUA)/config | |
| 8 | + | |
| 9 | +# primary targets (only "all" and "clean" are useful after distribution) | |
| 10 | +all clean co klean: | |
| 4 | 11 | cd include; $(MAKE) $@ |
| 5 | 12 | cd src; $(MAKE) $@ |
| 6 | 13 | cd src/luac; $(MAKE) $@ |
| 7 | 14 | cd src/lib; $(MAKE) $@ |
| 8 | 15 | cd src/lua; $(MAKE) $@ |
| 9 | 16 | |
| 17 | +# remove debug information from binaries | |
| 10 | 18 | strip: |
| 11 | − strip bin/lua* | |
| 19 | + strip bin/lua bin/luac | |
| 20 | + | |
| 21 | +# official installation | |
| 22 | +install: all strip | |
| 23 | + mkdir -p $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) | |
| 24 | + $(INSTALL_EXEC) bin/* $(INSTALL_BIN) | |
| 25 | + $(INSTALL_DATA) include/*.h $(INSTALL_INC) | |
| 26 | + $(INSTALL_DATA) lib/lib* $(INSTALL_LIB) | |
| 27 | + $(INSTALL_DATA) doc/*.1 $(INSTALL_MAN) | |
| 28 | + | |
| 29 | +# shared libraries (for Linux) | |
| 30 | +so: | |
| 31 | + ld -o lib/liblua.so.$V -shared src/*.o | |
| 32 | + ld -o lib/liblualib.so.$V -shared src/lib/*.o | |
| 33 | + cd lib; ln -s liblua.so.$V liblua.so; ln -s liblualib.so.$V liblualib.so | |
| 34 | + | |
| 35 | +# binaries using shared libraries | |
| 36 | +sobin: | |
| 37 | + rm -f bin/lua bin/luac | |
| 38 | + cd src/lua; $(MAKE) | |
| 39 | + cd src/luac; $(MAKE) | |
| 40 | + | |
| 41 | +# (end of Makefile) | |
| @@ -1,37 +1,53 @@ | ||
| 1 | −This is Lua 3.2 | |
| 1 | +This is Lua 4.0. | |
| 2 | +See HISTORY for a summary of changes since the last version. | |
| 2 | 3 | |
| 3 | 4 | * What is Lua? |
| 4 | 5 | ------------ |
| 5 | − Lua is a programming language originally designed for extending applications, | |
| 6 | − but also frequently used as a general-purpose, stand-alone language. | |
| 6 | + Lua is a powerful, light-weight programming language designed for extending | |
| 7 | + applications. Lua is also frequently used as a general-purpose, stand-alone | |
| 8 | + language. | |
| 9 | + | |
| 7 | 10 | Lua combines simple procedural syntax (similar to Pascal) with powerful |
| 8 | 11 | data description constructs based on associative arrays and extensible |
| 9 | 12 | semantics. Lua is dynamically typed, interpreted from bytecodes, and has |
| 10 | 13 | automatic memory management, making it ideal for configuration, scripting, |
| 11 | 14 | and rapid prototyping. |
| 12 | 15 | |
| 16 | + Lua is a language engine that you can embed into your application. | |
| 17 | + This means that, besides syntax and semantics, Lua has an API that | |
| 18 | + allows the application to exchange data with Lua programs and also to | |
| 19 | + extend Lua with C functions. In this sense, Lua can be regarded as a | |
| 20 | + language framework for building domain-specific languages. | |
| 21 | + | |
| 13 | 22 | Lua is implemented as a small library of C functions, written in ANSI C, |
| 14 | 23 | and compiles unmodified in all known platforms. The implementation goals |
| 15 | 24 | are simplicity, efficiency, portability, and low embedding cost. |
| 25 | + The result is a fast language engine with small footprint, making it | |
| 26 | + ideal in embedded systems too. | |
| 16 | 27 | |
| 17 | − Lua was awarded the first prize (technological category) in the Second Compaq | |
| 18 | − Award for Research and Development in Computer Science in 1997. This award | |
| 19 | − is a joint venture of Compaq Computer in Brazil, the Brazilian Ministry of | |
| 20 | − Science and Technology, and the Brazilian Academy of Sciences. | |
| 28 | + Lua was awarded the first prize (technological category) in the | |
| 29 | + Second Compaq Award for Research and Development in Computer Science in 1997. | |
| 30 | + This award was a joint venture of Compaq Computer in Brazil, the Brazilian | |
| 31 | + Ministry of Science and Technology, and the Brazilian Academy of Sciences. | |
| 32 | + | |
| 33 | + Lua has been used in many different projects around the world. | |
| 34 | + For a short list, see http://www.tecgraf.puc-rio.br/lua/uses.html . | |
| 21 | 35 | |
| 22 | 36 | * Availability |
| 23 | 37 | ------------ |
| 24 | 38 | Lua is freely available for both academic and commercial purposes and |
| 25 | 39 | can be downloaded from the sites below. See COPYRIGHT for details. |
| 26 | 40 | |
| 27 | − Home page: http://www.tecgraf.puc-rio.br/lua/ | |
| 28 | − http://csg.uwaterloo.ca/~lhf/lua/ | |
| 29 | − In Brazil: ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz | |
| 30 | − In Canada: ftp://csg.uwaterloo.ca/pub/lhf/lua/lua.tar.gz | |
| 31 | − In the US: ftp://ftp.cdrom.com/pub/languages/lua/lua.tar.gz | |
| 32 | − In Germany: ftp://ftp.uni-trier.de/pub/languages/lua/lua.tar.gz | |
| 33 | − In Germany: ftp://ftp.gwdg.de/pub/languages/lua/lua.tar.gz | |
| 34 | − In Greece: ftp://ftp.ntua.gr/pub/lang/lua/lua.tar.gz | |
| 41 | + Home page: http://www.tecgraf.puc-rio.br/lua/ | |
| 42 | + http://csg.uwaterloo.ca/~lhf/lua/ | |
| 43 | + In Brazil: ftp://ftp.tecgraf.puc-rio.br/pub/lua/ | |
| 44 | + In Canada: ftp://csg.uwaterloo.ca/pub/lhf/lua/ | |
| 45 | + In the US: ftp://ftp.freesoftware.com/pub/languages/lua/ | |
| 46 | + In Germany: ftp://ftp.uni-trier.de/pub/languages/lua/ | |
| 47 | + In Germany: ftp://ftp.gwdg.de/pub/languages/lua/ | |
| 48 | + In Greece: ftp://ftp.ntua.gr/pub/lang/lua/ | |
| 49 | + In Japan: ftp://ftp.u-aizu.ac.jp/pub/lang/lua/ | |
| 50 | + In Denmark: ftp://ftp.ucore.com/lua/dist | |
| 35 | 51 | |
| 36 | 52 | * Installation |
| 37 | 53 | ------------ |
| @@ -39,16 +55,18 @@ This is Lua 3.2 · 1 unmodified line | ||
| 39 | 55 | |
| 40 | 56 | * Contacting the authors |
| 41 | 57 | ---------------------- |
| 42 | − Lua has been designed and implemented by Waldemar Celes, | |
| 43 | − Roberto Ierusalimschy and Luiz Henrique de Figueiredo. | |
| 58 | + Lua was designed and implemented by Waldemar Celes, Roberto Ierusalimschy | |
| 59 | + and Luiz Henrique de Figueiredo. | |
| 44 | 60 | They can be contacted by email at lua@tecgraf.puc-rio.br. |
| 45 | 61 | |
| 46 | − Send your comments, bug reports and anything else to lua@tecgraf.puc-rio.br. | |
| 62 | + Send your comments, questions, and bug reports to lua@tecgraf.puc-rio.br. | |
| 47 | 63 | For reporting bugs, try also the mailing list: lua-l@tecgraf.puc-rio.br. |
| 48 | − To subscribe to this list, send "subscribe lua-l YOUR-NAME" to | |
| 49 | − listproc@tecgraf.puc-rio.br in the body of the message (not in the subject). | |
| 64 | + For more information about this list, including instructions on how to | |
| 65 | + subscribe, see http://www.tecgraf.puc-rio.br/lua/lua-l.html . | |
| 50 | 66 | |
| 51 | − Lua has been developed at TeCGraf, the Computer Graphics Technology Group | |
| 67 | + Lua is developed at TeCGraf, the Computer Graphics Technology Group | |
| 52 | 68 | of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro in Brazil). |
| 53 | 69 | TeCGraf is a laboratory of the Department of Computer Science. |
| 54 | 70 | Dozens of industrial products developed by TeCGraf use Lua. |
| 71 | + | |
| 72 | +(end of README) | |
| @@ -1,68 +1,100 @@ | ||
| 1 | 1 | # configuration file for making Lua |
| 2 | +# see INSTALL for installation instructions | |
| 2 | 3 | |
| 3 | 4 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= |
| 4 | 5 | |
| 5 | 6 | # ------------------------------------------------------------------ Lua |
| 6 | 7 | |
| 7 | −# if you need compatibility with version 2.5 or older, uncomment the line below. | |
| 8 | −#COMPAT= -DLUA_COMPAT2_5 | |
| 9 | − | |
| 10 | 8 | # Lua uses double for numbers. To change this, uncomment one of the lines below. |
| 11 | 9 | #NUMBER= -DLUA_NUM_TYPE=double |
| 12 | 10 | #NUMBER= -DLUA_NUM_TYPE=float |
| 13 | 11 | #NUMBER= -DLUA_NUM_TYPE=long |
| 12 | +# Optionally, you may also want change how numbers are converted to strings, | |
| 13 | +# and vice-versa. Look for LUA_NUMBER in llimits.h and in the rest of the code. | |
| 14 | 14 | |
| 15 | −# if you want support for pipes, uncomment the following line. | |
| 15 | +# If you want support for pipes, uncomment the following line. | |
| 16 | +# You need popen in your C library. | |
| 16 | 17 | #POPEN= -DPOPEN |
| 17 | 18 | |
| 19 | +# If you need compatibility with previous versions, edit and uncomment the | |
| 20 | +# definition of COMPAT below. | |
| 21 | +# Use -DLUA_COMPAT_READPATTERN if you need complex read patterns. | |
| 22 | +# Use -DLUA_COMPAT_ARGRET if you need the old semantics that used only the | |
| 23 | +# first value returned by a function when it is called as the last parameter. | |
| 24 | +# Use -DLUA_DEPRECATEDFUNCS if you need the obsolete functions in the standard | |
| 25 | +# Lua library (not recommended). | |
| 26 | +#COMPAT= -DLUA_COMPAT_READPATTERN -DLUA_COMPAT_ARGRET -DLUA_DEPRECATEDFUNCS | |
| 27 | + | |
| 18 | 28 | # ------------------------------------------------------------------ C compiler |
| 19 | 29 | |
| 20 | −# you need an ANSI C compiler. gcc is a popular one. | |
| 30 | +# You need an ANSI C compiler. gcc is a popular one. | |
| 21 | 31 | CC= gcc |
| 22 | −WARN= -ansi -Wall | |
| 32 | +WARN= -ansi -pedantic -Wall | |
| 23 | 33 | |
| 24 | −# on IRIX, cc is a good ANSI compiler. | |
| 34 | +# On IRIX, cc is a good ANSI compiler. | |
| 25 | 35 | #CC= cc |
| 26 | 36 | #WARN= -ansi -fullwarn |
| 27 | 37 | |
| 28 | −# on Solaris, cc is optional. you may have to add -Dsparc if you use -Xc. | |
| 38 | +# On Solaris, cc is optional. You may have to add -Dsparc if you use -Xc. | |
| 29 | 39 | #CC= cc |
| 30 | 40 | #WARN= -Xc # -Dsparc |
| 31 | 41 | |
| 32 | 42 | # ------------------------------------------------------------------ C library |
| 33 | 43 | |
| 34 | −# if your C library is not POSIX compliant, comment the following line. | |
| 44 | +# If your C library is not POSIX compliant, comment the following line. | |
| 35 | 45 | POSIX= -D_POSIX_SOURCE |
| 36 | 46 | |
| 37 | −# if your C library does not have the newer ANSI functions memmove, strerror, | |
| 47 | +# If your C library does not have the newer ANSI functions strerror, strcoll, | |
| 38 | 48 | # and locale support, uncomment the following line. SunOs 4.1.x is one example. |
| 39 | 49 | #OLD_ANSI= -DOLD_ANSI |
| 40 | 50 | |
| 41 | −# in SunOs 4.1.x, standard headers in /usr/include are not ANSI, | |
| 51 | +# In SunOs 4.1.x, standard headers in /usr/include are not ANSI, | |
| 42 | 52 | # so uncomment the following line to avoid prototypes warnings. |
| 43 | −#EXTRA_INCS= -I/usr/5include | |
| 53 | +#EXTRA_INCS= -I/usr/5include | |
| 54 | + | |
| 55 | +# The stand-alone Lua interpreter needs the math functions, which are usually | |
| 56 | +# in libm.a (-lm). If your C library already includes the math functions, | |
| 57 | +# or if you are using a modified interpreter that does not need them, | |
| 58 | +# then comment the following line. | |
| 59 | +EXTRA_LIBS= -lm | |
| 44 | 60 | |
| 45 | 61 | # ------------------------------------------------------------------ librarian |
| 46 | 62 | |
| 47 | −# this should work in all unix systems. | |
| 63 | +# This should work in all Unix systems. | |
| 48 | 64 | AR= ar rcu |
| 49 | 65 | |
| 50 | −# if your system doesn't have (or need) ranlib, use RANLIB=true. | |
| 51 | −# on some systems, "ar s" does what ranlib would do. | |
| 66 | +# If your system doesn't have (or need) ranlib, use RANLIB=true. | |
| 67 | +# On some systems, "ar s" does what ranlib would do. | |
| 52 | 68 | RANLIB= ranlib |
| 53 | 69 | #RANLIB= ar s |
| 54 | 70 | #RANLIB= true |
| 55 | 71 | |
| 56 | −# == END OF USER SETTINGS. DO NOT CHANGE ANYTHING BELOW THIS LINE ============= | |
| 72 | +# ------------------------------------------------------------------ install | |
| 73 | + | |
| 74 | +# Locations for "make install". You may need to be root do "make install". | |
| 75 | +INSTALL_ROOT= /usr/local | |
| 76 | +INSTALL_BIN= $(INSTALL_ROOT)/bin | |
| 77 | +INSTALL_INC= $(INSTALL_ROOT)/include | |
| 78 | +INSTALL_LIB= $(INSTALL_ROOT)/lib | |
| 79 | +INSTALL_MAN= $(INSTALL_ROOT)/man/man1 | |
| 57 | 80 | |
| 58 | −VERSION= 3.2 | |
| 81 | +# You might prefer to use "install" if you have it. | |
| 82 | +INSTALL_EXEC= cp | |
| 83 | +INSTALL_DATA= cp | |
| 84 | +#INSTALL_EXEC= install -m 0755 | |
| 85 | +#INSTALL_DATA= install -m 0644 | |
| 59 | 86 | |
| 87 | +# == END OF USER SETTINGS. DO NOT CHANGE ANYTHING BELOW THIS LINE ============= | |
| 88 | + | |
| 89 | +BIN= $(LUA)/bin | |
| 60 | 90 | INC= $(LUA)/include |
| 61 | 91 | LIB= $(LUA)/lib |
| 62 | −BIN= $(LUA)/bin | |
| 63 | 92 | |
| 64 | 93 | INCS= -I$(INC) $(EXTRA_INCS) |
| 65 | −DEFS= $(COMPAT) $(NUMBER) $(OLD_ANSI) $(EXTRALIB) $(EXTRA_DEFS) | |
| 94 | +DEFS= $(COMPAT) $(NUMBER) $(OLD_ANSI) $(EXTRA_DEFS) | |
| 66 | 95 | |
| 67 | 96 | CFLAGS= -O2 $(WARN) $(INCS) $(DEFS) |
| 68 | 97 | |
| 98 | +V=4.0 | |
| 99 | + | |
| 100 | +# (end of config) | |
| @@ -1,282 +1,409 @@ | ||
| 1 | 1 | <HTML> |
| 2 | 2 | <HEAD> |
| 3 | −<TITLE>Lua 3.2 Reference Manual - Word Index</TITLE> | |
| 3 | +<TITLE>Lua 4.0 Reference Manual - Word Index</TITLE> | |
| 4 | 4 | </HEAD> |
| 5 | 5 | |
| 6 | 6 | <BODY BGCOLOR="#FFFFFF"> |
| 7 | 7 | |
| 8 | −<H1>Index</H1> | |
| 8 | +<HR> | |
| 9 | +<H1> | |
| 10 | +<IMG SRC="logo.gif" ALT="Lua" ALIGN="bottom"> | |
| 11 | +<A HREF="index.html">Reference manual</A> | |
| 12 | +- word index | |
| 13 | +</H1> | |
| 9 | 14 | |
| 10 | −<A HREF="manual.html#..">..</A><BR> | |
| 11 | −<A HREF="manual.html#Adjustment">Adjustment</A><BR> | |
| 12 | −<A HREF="manual.html#Assignment">Assignment</A><BR> | |
| 13 | −<A HREF="manual.html#Basic Expressions">Basic Expressions</A><BR> | |
| 14 | −<A HREF="manual.html#C pointers">C pointers</A><BR> | |
| 15 | −<A HREF="manual.html#C2lua">C2lua</A><BR> | |
| 16 | −<A HREF="manual.html#Coercion">Coercion</A><BR> | |
| 17 | −<A HREF="manual.html#Comments">Comments</A><BR> | |
| 18 | −<A HREF="manual.html#Expressions">Expressions</A><BR> | |
| 19 | −<A HREF="manual.html#Function Definitions">Function Definitions</A><BR> | |
| 20 | −<A HREF="manual.html#Global variables">Global variables</A><BR> | |
| 21 | −<A HREF="manual.html#Identifiers">Identifiers</A><BR> | |
| 22 | −<A HREF="manual.html#LUA_ANYTAG">LUA_ANYTAG</A><BR> | |
| 23 | −<A HREF="manual.html#LUA_NOOBJECT">LUA_NOOBJECT</A><BR> | |
| 24 | −<A HREF="manual.html#Literal strings">Literal strings</A><BR> | |
| 25 | −<A HREF="manual.html#Local variables">Local variables</A><BR> | |
| 26 | −<A HREF="manual.html#Lua Stand-alone">Lua Stand-alone</A><BR> | |
| 27 | −<A HREF="manual.html#Numerical constants">Numerical constants</A><BR> | |
| 28 | −<A HREF="manual.html#Operator precedence">Operator precedence</A><BR> | |
| 29 | −<A HREF="manual.html#PI">PI</A><BR> | |
| 30 | −<A HREF="manual.html#Pre-processor">Pre-processor</A><BR> | |
| 31 | −<A HREF="manual.html#Types and Tags">Types and Tags</A><BR> | |
| 32 | −<A HREF="manual.html#Upvalues">Upvalues</A><BR> | |
| 33 | −<A HREF="manual.html#Visibility">Visibility</A><BR> | |
| 34 | −<A HREF="manual.html#_ERRORMESSAGE">_ERRORMESSAGE</A><BR> | |
| 35 | −<A HREF="manual.html#_INPUT">_INPUT</A><BR> | |
| 36 | −<A HREF="manual.html#_OUTPUT">_OUTPUT</A><BR> | |
| 37 | −<A HREF="manual.html#_STDERR">_STDERR</A><BR> | |
| 38 | −<A HREF="manual.html#_STDIN">_STDIN</A><BR> | |
| 39 | −<A HREF="manual.html#_STDOUT">_STDOUT</A><BR> | |
| 40 | −<A HREF="manual.html#abs">abs</A><BR> | |
| 41 | −<A HREF="manual.html#acos">acos</A><BR> | |
| 42 | −<A HREF="manual.html#add event">add event</A><BR> | |
| 43 | −<A HREF="manual.html#alert">alert</A><BR> | |
| 15 | +<A HREF="manual.html#.."><TT>..</TT></A><BR> | |
| 16 | +<A HREF="manual.html#_ALERT"><TT>_ALERT</TT></A><BR> | |
| 17 | +<A HREF="manual.html#_ERRORMESSAGE"><TT>_ERRORMESSAGE</TT></A><BR> | |
| 18 | +<A HREF="manual.html#_INPUT"><TT>_INPUT</TT></A><BR> | |
| 19 | +<A HREF="manual.html#_OUTPUT"><TT>_OUTPUT</TT></A><BR> | |
| 20 | +<A HREF="manual.html#_PROMPT"><TT>_PROMPT</TT></A><BR> | |
| 21 | +<A HREF="manual.html#_STDERR"><TT>_STDERR</TT></A><BR> | |
| 22 | +<A HREF="manual.html#_STDIN"><TT>_STDIN</TT></A><BR> | |
| 23 | +<A HREF="manual.html#_STDOUT"><TT>_STDOUT</TT></A><BR> | |
| 24 | + | |
| 25 | + <P> | |
| 26 | + | |
| 27 | +<A HREF="manual.html#abs"><TT>abs</TT></A><BR> | |
| 28 | +<A HREF="manual.html#acceptable index">acceptable index</A><BR> | |
| 29 | +<A HREF="manual.html#acos"><TT>acos</TT></A><BR> | |
| 30 | +<A HREF="manual.html#add event">``add'' event</A><BR> | |
| 31 | +<A HREF="manual.html#Adjustment">adjustment</A><BR> | |
| 32 | +<A HREF="manual.html#alert"><TT>alert</TT></A><BR> | |
| 44 | 33 | <A HREF="manual.html#and">and</A><BR> |
| 45 | −<A HREF="manual.html#appendto">appendto</A><BR> | |
| 34 | +<A HREF="manual.html#appendto"><TT>appendto</TT></A><BR> | |
| 35 | +<A HREF="manual.html#arg"><TT>arg</TT></A><BR> | |
| 46 | 36 | <A HREF="manual.html#arguments">arguments</A><BR> |
| 47 | −<A HREF="manual.html#arg">arg</A><BR> | |
| 48 | 37 | <A HREF="manual.html#arithmetic operators">arithmetic operators</A><BR> |
| 49 | 38 | <A HREF="manual.html#arrays">arrays</A><BR> |
| 50 | −<A HREF="manual.html#asin">asin</A><BR> | |
| 51 | −<A HREF="manual.html#assert">assert</A><BR> | |
| 39 | +<A HREF="manual.html#asin"><TT>asin</TT></A><BR> | |
| 40 | +<A HREF="manual.html#assert"><TT>assert</TT></A><BR> | |
| 41 | +<A HREF="manual.html#Assignment">assignment</A><BR> | |
| 52 | 42 | <A HREF="manual.html#associative arrays">associative arrays</A><BR> |
| 53 | −<A HREF="manual.html#atan2">atan2</A><BR> | |
| 54 | −<A HREF="manual.html#atan">atan</A><BR> | |
| 43 | +<A HREF="manual.html#atan"><TT>atan</TT></A><BR> | |
| 44 | +<A HREF="manual.html#atan2"><TT>atan2</TT></A><BR> | |
| 45 | + | |
| 46 | + <P> | |
| 47 | + | |
| 48 | +<A HREF="manual.html#Basic Expressions">basic expressions</A><BR> | |
| 55 | 49 | <A HREF="manual.html#basic types">basic types</A><BR> |
| 56 | 50 | <A HREF="manual.html#block">block</A><BR> |
| 57 | −<A HREF="manual.html#call">call</A><BR> | |
| 51 | +<A HREF="manual.html#break statement">break statement</A><BR> | |
| 52 | + | |
| 53 | + <P> | |
| 54 | + | |
| 55 | +<A HREF="manual.html#C API">C API</A><BR> | |
| 56 | +....... <A HREF="manual.html#LUA_ANYTAG"><TT>LUA_ANYTAG</TT></A><BR> | |
| 57 | +....... <A HREF="manual.html#lua_baselibopen"><TT>lua_baselibopen</TT></A><BR> | |
| 58 | +....... <A HREF="manual.html#lua_call"><TT>lua_call</TT></A><BR> | |
| 59 | +....... <A HREF="manual.html#lua_CFunction"><TT>lua_CFunction</TT></A><BR> | |
| 60 | +....... <A HREF="manual.html#lua_close"><TT>lua_close</TT></A><BR> | |
| 61 | +....... <A HREF="manual.html#lua_concat"><TT>lua_concat</TT></A><BR> | |
| 62 | +....... <A HREF="manual.html#lua_copytagmethods"><TT>lua_copytagmethods</TT></A><BR> | |
| 63 | +....... <A HREF="manual.html#lua_dblibopen"><TT>lua_dblibopen</TT></A><BR> | |
| 64 | +....... <A HREF="manual.html#lua_Debug"><TT>lua_Debug</TT></A><BR> | |
| 65 | +....... <A HREF="manual.html#lua_dobuffer"><TT>lua_dobuffer</TT></A><BR> | |
| 66 | +....... <A HREF="manual.html#lua_dofile"><TT>lua_dofile</TT></A><BR> | |
| 67 | +....... <A HREF="manual.html#lua_dostring"><TT>lua_dostring</TT></A><BR> | |
| 68 | +....... <A HREF="manual.html#lua_equal"><TT>lua_equal</TT></A><BR> | |
| 69 | +....... <A HREF="manual.html#LUA_ERRERR"><TT>LUA_ERRERR</TT></A><BR> | |
| 70 | +....... <A HREF="manual.html#LUA_ERRFILE"><TT>LUA_ERRFILE</TT></A><BR> | |
| 71 | +....... <A HREF="manual.html#LUA_ERRMEM"><TT>LUA_ERRMEM</TT></A><BR> | |
| 72 | +....... <A HREF="manual.html#lua_error"><TT>lua_error</TT></A><BR> | |
| 73 | +....... <A HREF="manual.html#LUA_ERRRUN"><TT>LUA_ERRRUN</TT></A><BR> | |
| 74 | +....... <A HREF="manual.html#LUA_ERRSYNTAX"><TT>LUA_ERRSYNTAX</TT></A><BR> | |
| 75 | +....... <A HREF="manual.html#lua_getgccount"><TT>lua_getgccount</TT></A><BR> | |
| 76 | +....... <A HREF="manual.html#lua_getgcthreshold"><TT>lua_getgcthreshold</TT></A><BR> | |
| 77 | +....... <A HREF="manual.html#lua_getglobal"><TT>lua_getglobal</TT></A><BR> | |
| 78 | +....... <A HREF="manual.html#lua_getglobals"><TT>lua_getglobals</TT></A><BR> | |
| 79 | +....... <A HREF="manual.html#lua_getinfo"><TT>lua_getinfo</TT></A><BR> | |
| 80 | +....... <A HREF="manual.html#lua_getlocal"><TT>lua_getlocal</TT></A><BR> | |
| 81 | +....... <A HREF="manual.html#lua_getn"><TT>lua_getn</TT></A><BR> | |
| 82 | +....... <A HREF="manual.html#lua_getref"><TT>lua_getref</TT></A><BR> | |
| 83 | +....... <A HREF="manual.html#lua_getregistry"><TT>lua_getregistry</TT></A><BR> | |
| 84 | +....... <A HREF="manual.html#lua_getstack"><TT>lua_getstack</TT></A><BR> | |
| 85 | +....... <A HREF="manual.html#lua_gettable"><TT>lua_gettable</TT></A><BR> | |
| 86 | +....... <A HREF="manual.html#lua_gettagmethod"><TT>lua_gettagmethod</TT></A><BR> | |
| 87 | +....... <A HREF="manual.html#lua_gettop"><TT>lua_gettop</TT></A><BR> | |
| 88 | +....... <A HREF="manual.html#lua_Hook"><TT>lua_Hook</TT></A><BR> | |
| 89 | +....... <A HREF="manual.html#lua_insert"><TT>lua_insert</TT></A><BR> | |
| 90 | +....... <A HREF="manual.html#lua_iolibopen"><TT>lua_iolibopen</TT></A><BR> | |
| 91 | +....... <A HREF="manual.html#lua_iscfunction"><TT>lua_iscfunction</TT></A><BR> | |
| 92 | +....... <A HREF="manual.html#lua_isfunction"><TT>lua_isfunction</TT></A><BR> | |
| 93 | +....... <A HREF="manual.html#lua_isnil"><TT>lua_isnil</TT></A><BR> | |
| 94 | +....... <A HREF="manual.html#lua_isnumber"><TT>lua_isnumber</TT></A><BR> | |
| 95 | +....... <A HREF="manual.html#lua_isstring"><TT>lua_isstring</TT></A><BR> | |
| 96 | +....... <A HREF="manual.html#lua_istable"><TT>lua_istable</TT></A><BR> | |
| 97 | +....... <A HREF="manual.html#lua_isuserdata"><TT>lua_isuserdata</TT></A><BR> | |
| 98 | +....... <A HREF="manual.html#lua_lessthan"><TT>lua_lessthan</TT></A><BR> | |
| 99 | +....... <A HREF="manual.html#lua_mathlibopen"><TT>lua_mathlibopen</TT></A><BR> | |
| 100 | +....... <A HREF="manual.html#LUA_MINSTACK"><TT>LUA_MINSTACK</TT></A><BR> | |
| 101 | +....... <A HREF="manual.html#LUA_MULTRET"><TT>LUA_MULTRET</TT></A><BR> | |
| 102 | +....... <A HREF="manual.html#lua_newtable"><TT>lua_newtable</TT></A><BR> | |
| 103 | +....... <A HREF="manual.html#lua_newtag"><TT>lua_newtag</TT></A><BR> | |
| 104 | +....... <A HREF="manual.html#lua_next"><TT>lua_next</TT></A><BR> | |
| 105 | +....... <A HREF="manual.html#LUA_NOREF"><TT>LUA_NOREF</TT></A><BR> | |
| 106 | +....... <A HREF="manual.html#lua_open"><TT>lua_open</TT></A><BR> | |
| 107 | +....... <A HREF="manual.html#lua_pushcclosure"><TT>lua_pushcclosure</TT></A><BR> | |
| 108 | +....... <A HREF="manual.html#lua_pushcfunction"><TT>lua_pushcfunction</TT></A><BR> | |
| 109 | +....... <A HREF="manual.html#lua_pushlstring"><TT>lua_pushlstring</TT></A><BR> | |
| 110 | +....... <A HREF="manual.html#lua_pushnil"><TT>lua_pushnil</TT></A><BR> | |
| 111 | +....... <A HREF="manual.html#lua_pushnumber"><TT>lua_pushnumber</TT></A><BR> | |
| 112 | +....... <A HREF="manual.html#lua_pushstring"><TT>lua_pushstring</TT></A><BR> | |
| 113 | +....... <A HREF="manual.html#lua_pushuserdata"><TT>lua_pushuserdata</TT></A><BR> | |
| 114 | +....... <A HREF="manual.html#lua_pushusertag"><TT>lua_pushusertag</TT></A><BR> | |
| 115 | +....... <A HREF="manual.html#lua_pushvalue"><TT>lua_pushvalue</TT></A><BR> | |
| 116 | +....... <A HREF="manual.html#lua_rawcall"><TT>lua_rawcall</TT></A><BR> | |
| 117 | +....... <A HREF="manual.html#lua_rawget"><TT>lua_rawget</TT></A><BR> | |
| 118 | +....... <A HREF="manual.html#lua_rawgeti"><TT>lua_rawgeti</TT></A><BR> | |
| 119 | +....... <A HREF="manual.html#lua_rawset"><TT>lua_rawset</TT></A><BR> | |
| 120 | +....... <A HREF="manual.html#lua_rawseti"><TT>lua_rawseti</TT></A><BR> | |
| 121 | +....... <A HREF="manual.html#lua_ref"><TT>lua_ref</TT></A><BR> | |
| 122 | +....... <A HREF="manual.html#LUA_REFNIL"><TT>LUA_REFNIL</TT></A><BR> | |
| 123 | +....... <A HREF="manual.html#LUA_REFREGISTRY"><TT>LUA_REFREGISTRY</TT></A><BR> | |
| 124 | +....... <A HREF="manual.html#lua_register"><TT>lua_register</TT></A><BR> | |
| 125 | +....... <A HREF="manual.html#lua_remove"><TT>lua_remove</TT></A><BR> | |
| 126 | +....... <A HREF="manual.html#lua_setcallhook"><TT>lua_setcallhook</TT></A><BR> | |
| 127 | +....... <A HREF="manual.html#lua_setgcthreshold"><TT>lua_setgcthreshold</TT></A><BR> | |
| 128 | +....... <A HREF="manual.html#lua_setglobal"><TT>lua_setglobal</TT></A><BR> | |
| 129 | +....... <A HREF="manual.html#lua_setglobals"><TT>lua_setglobals</TT></A><BR> | |
| 130 | +....... <A HREF="manual.html#lua_setlinehook"><TT>lua_setlinehook</TT></A><BR> | |
| 131 | +....... <A HREF="manual.html#lua_setlocal"><TT>lua_setlocal</TT></A><BR> | |
| 132 | +....... <A HREF="manual.html#lua_settable"><TT>lua_settable</TT></A><BR> | |
| 133 | +....... <A HREF="manual.html#lua_settag"><TT>lua_settag</TT></A><BR> | |
| 134 | +....... <A HREF="manual.html#lua_settagmethod"><TT>lua_settagmethod</TT></A><BR> | |
| 135 | +....... <A HREF="manual.html#lua_settop"><TT>lua_settop</TT></A><BR> | |
| 136 | +....... <A HREF="manual.html#lua_stackspace"><TT>lua_stackspace</TT></A><BR> | |
| 137 | +....... <A HREF="manual.html#lua_State"><TT>lua_State</TT></A><BR> | |
| 138 | +....... <A HREF="manual.html#lua_strlen"><TT>lua_strlen</TT></A><BR> | |
| 139 | +....... <A HREF="manual.html#lua_strlibopen"><TT>lua_strlibopen</TT></A><BR> | |
| 140 | +....... <A HREF="manual.html#lua_tag"><TT>lua_tag</TT></A><BR> | |
| 141 | +....... <A HREF="manual.html#lua_tocfunction"><TT>lua_tocfunction</TT></A><BR> | |
| 142 | +....... <A HREF="manual.html#lua_tonumber"><TT>lua_tonumber</TT></A><BR> | |
| 143 | +....... <A HREF="manual.html#lua_tostring"><TT>lua_tostring</TT></A><BR> | |
| 144 | +....... <A HREF="manual.html#lua_touserdata"><TT>lua_touserdata</TT></A><BR> | |
| 145 | +....... <A HREF="manual.html#lua_type"><TT>lua_type</TT></A><BR> | |
| 146 | +....... <A HREF="manual.html#lua_typename"><TT>lua_typename</TT></A><BR> | |
| 147 | +....... <A HREF="manual.html#lua_unref"><TT>lua_unref</TT></A><BR> | |
| 148 | +<A HREF="manual.html#C closure">C closure</A><BR> | |
| 149 | +<A HREF="manual.html#C pointers">C pointers</A><BR> | |
| 150 | +<A HREF="manual.html#call"><TT>call</TT></A><BR> | |
| 58 | 151 | <A HREF="manual.html#captures">captures</A><BR> |
| 59 | −<A HREF="manual.html#ceil">ceil</A><BR> | |
| 152 | +<A HREF="manual.html#ceil"><TT>ceil</TT></A><BR> | |
| 60 | 153 | <A HREF="manual.html#character class">character class</A><BR> |
| 61 | 154 | <A HREF="manual.html#chunk">chunk</A><BR> |
| 62 | −<A HREF="manual.html#clock">clock</A><BR> | |
| 63 | −<A HREF="manual.html#closefile">closefile</A><BR> | |
| 155 | +<A HREF="manual.html#clock"><TT>clock</TT></A><BR> | |
| 156 | +<A HREF="manual.html#closefile"><TT>closefile</TT></A><BR> | |
| 64 | 157 | <A HREF="manual.html#closing a file">closing a file</A><BR> |
| 65 | −<A HREF="manual.html#collectgarbage">collectgarbage</A><BR> | |
| 66 | −<A HREF="manual.html#concatenation event">concatenation event</A><BR> | |
| 158 | +<A HREF="manual.html#Coercion">coercion</A><BR> | |
| 159 | +<A HREF="manual.html#collectgarbage"><TT>collectgarbage</TT></A><BR> | |
| 160 | +<A HREF="manual.html#Comments">comments</A><BR> | |
| 67 | 161 | <A HREF="manual.html#concatenation">concatenation</A><BR> |
| 162 | +<A HREF="manual.html#concatenation event">``concatenation'' event</A><BR> | |
| 68 | 163 | <A HREF="manual.html#condition expression">condition expression</A><BR> |
| 69 | 164 | <A HREF="manual.html#constructors">constructors</A><BR> |
| 70 | −<A HREF="manual.html#copytagmethods">copytagmethods</A><BR> | |
| 71 | −<A HREF="manual.html#cos">cos</A><BR> | |
| 72 | −<A HREF="manual.html#date">date</A><BR> | |
| 73 | −<A HREF="manual.html#debug pragma">debug pragma</A><BR> | |
| 74 | −<A HREF="manual.html#deg">deg</A><BR> | |
| 75 | −<A HREF="manual.html#div event">div event</A><BR> | |
| 76 | −<A HREF="manual.html#dofile">dofile</A><BR> | |
| 77 | −<A HREF="manual.html#dostring">dostring</A><BR> | |
| 165 | +<A HREF="manual.html#copytagmethods"><TT>copytagmethods</TT></A><BR> | |
| 166 | +<A HREF="manual.html#cos"><TT>cos</TT></A><BR> | |
| 167 | + | |
| 168 | + <P> | |
| 169 | + | |
| 170 | +<A HREF="manual.html#date"><TT>date</TT></A><BR> | |
| 171 | +<A HREF="manual.html#def"><TT>def</TT></A><BR> | |
| 172 | +<A HREF="manual.html#div event">``div'' event</A><BR> | |
| 173 | +<A HREF="manual.html#dofile"><TT>dofile</TT></A><BR> | |
| 174 | +<A HREF="manual.html#dostring"><TT>dostring</TT></A><BR> | |
| 175 | + | |
| 176 | + <P> | |
| 177 | + | |
| 78 | 178 | <A HREF="manual.html#eight-bit clean">eight-bit clean</A><BR> |
| 79 | −<A HREF="manual.html#error">error</A><BR> | |
| 179 | +<A HREF="manual.html#error"><TT>error</TT></A><BR> | |
| 80 | 180 | <A HREF="manual.html#event">event</A><BR> |
| 81 | −<A HREF="manual.html#execute">execute</A><BR> | |
| 82 | −<A HREF="manual.html#exit">exit</A><BR> | |
| 181 | +<A HREF="manual.html#execute"><TT>execute</TT></A><BR> | |
| 182 | +<A HREF="manual.html#exit"><TT>exit</TT></A><BR> | |
| 183 | +<A HREF="manual.html#exp"><TT>exp</TT></A><BR> | |
| 83 | 184 | <A HREF="manual.html#exponentiation">exponentiation</A><BR> |
| 185 | +<A HREF="manual.html#Expressions">expressions</A><BR> | |
| 186 | + | |
| 187 | + <P> | |
| 188 | + | |
| 84 | 189 | <A HREF="manual.html#file handles">file handles</A><BR> |
| 85 | −<A HREF="manual.html#floor">floor</A><BR> | |
| 86 | −<A HREF="manual.html#flush">flush</A><BR> | |
| 87 | −<A HREF="manual.html#foreachi">foreachi</A><BR> | |
| 88 | −<A HREF="manual.html#foreachvar">foreachvar</A><BR> | |
| 89 | −<A HREF="manual.html#foreach">foreach</A><BR> | |
| 90 | −<A HREF="manual.html#format">format</A><BR> | |
| 91 | −<A HREF="manual.html#frexp">frexp</A><BR> | |
| 92 | −<A HREF="manual.html#funcinfo">funcinfo</A><BR> | |
| 93 | −<A HREF="manual.html#function call">function call</A><BR> | |
| 94 | −<A HREF="manual.html#function event">function event</A><BR> | |
| 190 | +<A HREF="manual.html#floor"><TT>floor</TT></A><BR> | |
| 191 | +<A HREF="manual.html#flush"><TT>flush</TT></A><BR> | |
| 192 | +<A HREF="manual.html#for statement">for statement</A><BR> | |
| 193 | +<A HREF="manual.html#foreach"><TT>foreach</TT></A><BR> | |
| 194 | +<A HREF="manual.html#foreachi"><TT>foreachi</TT></A><BR> | |
| 195 | +<A HREF="manual.html#format"><TT>format</TT></A><BR> | |
| 196 | +<A HREF="manual.html#frexp"><TT>frexp</TT></A><BR> | |
| 95 | 197 | <A HREF="manual.html#function">function</A><BR> |
| 96 | −<A HREF="manual.html#gc event">gc event</A><BR> | |
| 97 | −<A HREF="manual.html#ge event">ge event</A><BR> | |
| 98 | −<A HREF="manual.html#getenv">getenv</A><BR> | |
| 99 | −<A HREF="manual.html#getglobal event">getglobal event</A><BR> | |
| 100 | −<A HREF="manual.html#getglobal">getglobal</A><BR> | |
| 101 | −<A HREF="manual.html#getlocal">getlocal</A><BR> | |
| 102 | −<A HREF="manual.html#getn">getn</A><BR> | |
| 103 | −<A HREF="manual.html#getstack">getstack</A><BR> | |
| 104 | −<A HREF="manual.html#gettable event">gettable event</A><BR> | |
| 105 | −<A HREF="manual.html#gettagmethod">gettagmethod</A><BR> | |
| 106 | −<A HREF="manual.html#gettagmethod">gettagmethod</A><BR> | |
| 198 | +<A HREF="manual.html#function call">function call</A><BR> | |
| 199 | +<A HREF="manual.html#Function Definitions">function definitions</A><BR> | |
| 200 | +<A HREF="manual.html#function event">``function'' event</A><BR> | |
| 201 | + | |
| 202 | + <P> | |
| 203 | + | |
| 204 | +<A HREF="manual.html#gc event">``gc'' event</A><BR> | |
| 205 | +<A HREF="manual.html#getargs"><TT>getargs</TT></A><BR> | |
| 206 | +<A HREF="manual.html#getenv"><TT>getenv</TT></A><BR> | |
| 207 | +<A HREF="manual.html#getglobal"><TT>getglobal</TT></A><BR> | |
| 208 | +<A HREF="manual.html#getglobal event">``getglobal'' event</A><BR> | |
| 209 | +<A HREF="manual.html#getinfo"><TT>getinfo</TT></A><BR> | |
| 210 | +<A HREF="manual.html#getlocal"><TT>getlocal</TT></A><BR> | |
| 211 | +<A HREF="manual.html#getn"><TT>getn</TT></A><BR> | |
| 212 | +<A HREF="manual.html#gettable event">``gettable'' event</A><BR> | |
| 213 | +<A HREF="manual.html#gettagmethod"><TT>gettagmethod</TT></A><BR> | |
| 107 | 214 | <A HREF="manual.html#global environment">global environment</A><BR> |
| 108 | −<A HREF="manual.html#gsub">gsub</A><BR> | |
| 109 | −<A HREF="manual.html#gt event">gt event</A><BR> | |
| 110 | −<A HREF="manual.html#if-then-else">if-then-else</A><BR> | |
| 111 | −<A HREF="manual.html#index event">index event</A><BR> | |
| 112 | −<A HREF="manual.html#ldexp">ldexp</A><BR> | |
| 113 | −<A HREF="manual.html#le event">le event</A><BR> | |
| 114 | −<A HREF="manual.html#log10">log10</A><BR> | |
| 215 | +<A HREF="manual.html#Global variables">global variables</A><BR> | |
| 216 | +<A HREF="manual.html#globals"><TT>globals</TT></A><BR> | |
| 217 | +<A HREF="manual.html#grammar">grammar</A><BR> | |
| 218 | +....... <A HREF="manual.html#args">args</A><BR> | |
| 219 | +....... <A HREF="manual.html#binop">binop</A><BR> | |
| 220 | +....... <A HREF="manual.html#block">block</A><BR> | |
| 221 | +....... <A HREF="manual.html#chunk">chunk</A><BR> | |
| 222 | +....... <A HREF="manual.html#declist">declist</A><BR> | |
| 223 | +....... <A HREF="manual.html#exp">exp</A><BR> | |
| 224 | +....... <A HREF="manual.html#exp1">exp1</A><BR> | |
| 225 | +....... <A HREF="manual.html#explist1">explist1</A><BR> | |
| 226 | +....... <A HREF="manual.html#ffield">ffield</A><BR> | |
| 227 | +....... <A HREF="manual.html#ffieldlist">ffieldlist</A><BR> | |
| 228 | +....... <A HREF="manual.html#ffieldlist1">ffieldlist1</A><BR> | |
| 229 | +....... <A HREF="manual.html#fieldlist">fieldlist</A><BR> | |
| 230 | +....... <A HREF="manual.html#funcname">funcname</A><BR> | |
| 231 | +....... <A HREF="manual.html#function">function</A><BR> | |
| 232 | +....... <A HREF="manual.html#functioncall">functioncall</A><BR> | |
| 233 | +....... <A HREF="manual.html#init">init</A><BR> | |
| 234 | +....... <A HREF="manual.html#lfieldlist">lfieldlist</A><BR> | |
| 235 | +....... <A HREF="manual.html#lfieldlist1">lfieldlist1</A><BR> | |
| 236 | +....... <A HREF="manual.html#parlist1">parlist1</A><BR> | |
| 237 | +....... <A HREF="manual.html#stat">stat</A><BR> | |
| 238 | +....... <A HREF="manual.html#tableconstructor">tableconstructor</A><BR> | |
| 239 | +....... <A HREF="manual.html#unop">unop</A><BR> | |
| 240 | +....... <A HREF="manual.html#upvalue">upvalue</A><BR> | |
| 241 | +....... <A HREF="manual.html#var">var</A><BR> | |
| 242 | +....... <A HREF="manual.html#varlist1">varlist1</A><BR> | |
| 243 | +....... <A HREF="manual.html#varorfunc">varorfunc</A><BR> | |
| 244 | +<A HREF="manual.html#gsub"><TT>gsub</TT></A><BR> | |
| 245 | + | |
| 246 | + <P> | |
| 247 | + | |
| 248 | +<A HREF="manual.html#Identifiers">identifiers</A><BR> | |
| 249 | +<A HREF="manual.html#if-then-else statement">if-then-else statement</A><BR> | |
| 250 | +<A HREF="manual.html#index event">``index'' event</A><BR> | |
| 251 | + | |
| 252 | + <P> | |
| 253 | + | |
| 254 | +<A HREF="manual.html#ldexp"><TT>ldexp</TT></A><BR> | |
| 255 | +<A HREF="manual.html#Literal strings">literal strings</A><BR> | |
| 256 | +<A HREF="manual.html#Local variables">local variables</A><BR> | |
| 257 | +<A HREF="manual.html#log"><TT>log</TT></A><BR> | |
| 258 | +<A HREF="manual.html#log10"><TT>log10</TT></A><BR> | |
| 115 | 259 | <A HREF="manual.html#logical operators">logical operators</A><BR> |
| 116 | −<A HREF="manual.html#log">log</A><BR> | |
| 117 | −<A HREF="manual.html#lt event">lt event</A><BR> | |
| 118 | −<A HREF="manual.html#lua2C">lua2C</A><BR> | |
| 119 | −<A HREF="manual.html#lua_CFunction">lua_CFunction</A><BR> | |
| 120 | −<A HREF="manual.html#lua_Object">lua_Object</A><BR> | |
| 121 | −<A HREF="manual.html#lua_callfunction">lua_callfunction</A><BR> | |
| 122 | −<A HREF="manual.html#lua_close">lua_close</A><BR> | |
| 123 | −<A HREF="manual.html#lua_collectgarbage">lua_collectgarbage</A><BR> | |
| 124 | −<A HREF="manual.html#lua_copytagmethods">lua_copytagmethods</A><BR> | |
| 125 | −<A HREF="manual.html#lua_createtable">lua_createtable</A><BR> | |
| 126 | −<A HREF="manual.html#lua_dobuffer">lua_dobuffer</A><BR> | |
| 127 | −<A HREF="manual.html#lua_dofile">lua_dofile</A><BR> | |
| 128 | −<A HREF="manual.html#lua_dostring">lua_dostring</A><BR> | |
| 129 | −<A HREF="manual.html#lua_error">lua_error</A><BR> | |
| 130 | −<A HREF="manual.html#lua_getcfunction">lua_getcfunction</A><BR> | |
| 131 | −<A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR> | |
| 132 | −<A HREF="manual.html#lua_getnumber">lua_getnumber</A><BR> | |
| 133 | −<A HREF="manual.html#lua_getparam">lua_getparam</A><BR> | |
| 134 | −<A HREF="manual.html#lua_getref">lua_getref</A><BR> | |
| 135 | −<A HREF="manual.html#lua_getresult">lua_getresult</A><BR> | |
| 136 | −<A HREF="manual.html#lua_getstring">lua_getstring</A><BR> | |
| 137 | −<A HREF="manual.html#lua_gettable">lua_gettable</A><BR> | |
| 138 | −<A HREF="manual.html#lua_gettagmethod">lua_gettagmethod</A><BR> | |
| 139 | −<A HREF="manual.html#lua_getuserdata">lua_getuserdata</A><BR> | |
| 140 | −<A HREF="manual.html#lua_iolibopen">lua_iolibopen</A><BR> | |
| 141 | −<A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR> | |
| 142 | −<A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR> | |
| 143 | −<A HREF="manual.html#lua_isnil">lua_isnil</A><BR> | |
| 144 | −<A HREF="manual.html#lua_isnumber">lua_isnumber</A><BR> | |
| 145 | −<A HREF="manual.html#lua_isstring">lua_isstring</A><BR> | |
| 146 | −<A HREF="manual.html#lua_istable">lua_istable</A><BR> | |
| 147 | −<A HREF="manual.html#lua_isuserdata">lua_isuserdata</A><BR> | |
| 148 | −<A HREF="manual.html#lua_lua2C">lua_lua2C</A><BR> | |
| 149 | −<A HREF="manual.html#lua_mathlibopen">lua_mathlibopen</A><BR> | |
| 150 | −<A HREF="manual.html#lua_newtag">lua_newtag</A><BR> | |
| 151 | −<A HREF="manual.html#lua_open">lua_open</A><BR> | |
| 152 | −<A HREF="manual.html#lua_pop">lua_pop</A><BR> | |
| 153 | −<A HREF="manual.html#lua_pushcclosure">lua_pushcclosure</A><BR> | |
| 154 | −<A HREF="manual.html#lua_pushcfunction">lua_pushcfunction</A><BR> | |
| 155 | −<A HREF="manual.html#lua_pushlstring">lua_pushlstring</A><BR> | |
| 156 | −<A HREF="manual.html#lua_pushnil">lua_pushnil</A><BR> | |
| 157 | −<A HREF="manual.html#lua_pushnumber">lua_pushnumber</A><BR> | |
| 158 | −<A HREF="manual.html#lua_pushobject">lua_pushobject</A><BR> | |
| 159 | −<A HREF="manual.html#lua_pushstring">lua_pushstring</A><BR> | |
| 160 | −<A HREF="manual.html#lua_pushuserdata">lua_pushuserdata</A><BR> | |
| 161 | −<A HREF="manual.html#lua_pushusertag">lua_pushusertag</A><BR> | |
| 162 | −<A HREF="manual.html#lua_rawgetglobal">lua_rawgetglobal</A><BR> | |
| 163 | −<A HREF="manual.html#lua_rawgetglobal">lua_rawgetglobal</A><BR> | |
| 164 | −<A HREF="manual.html#lua_rawgetglobal">lua_rawgetglobal</A><BR> | |
| 165 | −<A HREF="manual.html#lua_rawsettable">lua_rawsettable</A><BR> | |
| 166 | −<A HREF="manual.html#lua_ref">lua_ref</A><BR> | |
| 167 | −<A HREF="manual.html#lua_register">lua_register</A><BR> | |
| 168 | −<A HREF="manual.html#lua_setglobal">lua_setglobal</A><BR> | |
| 169 | −<A HREF="manual.html#lua_setstate">lua_setstate</A><BR> | |
| 170 | −<A HREF="manual.html#lua_settable">lua_settable</A><BR> | |
| 171 | −<A HREF="manual.html#lua_settagmethod">lua_settagmethod</A><BR> | |
| 172 | −<A HREF="manual.html#lua_settag">lua_settag</A><BR> | |
| 173 | −<A HREF="manual.html#lua_state">lua_state</A><BR> | |
| 174 | −<A HREF="manual.html#lua_strlen">lua_strlen</A><BR> | |
| 175 | −<A HREF="manual.html#lua_strlibopen">lua_strlibopen</A><BR> | |
| 176 | −<A HREF="manual.html#lua_tag">lua_tag</A><BR> | |
| 177 | −<A HREF="manual.html#lua_unref">lua_unref</A><BR> | |
| 178 | −<A HREF="manual.html#luac">luac</A><BR> | |
| 179 | −<A HREF="manual.html#luac">luac</A><BR> | |
| 180 | −<A HREF="manual.html#max">max</A><BR> | |
| 260 | +<A HREF="manual.html#lt event">``lt'' event</A><BR> | |
| 261 | +<A HREF="manual.html#Lua Stand-alone">Lua stand-alone</A><BR> | |
| 262 | +<A HREF="manual.html#luac"><TT>luac</TT></A><BR> | |
| 263 | + | |
| 264 | + <P> | |
| 265 | + | |
| 266 | +<A HREF="manual.html#max"><TT>max</TT></A><BR> | |
| 181 | 267 | <A HREF="manual.html#methods">methods</A><BR> |
| 182 | −<A HREF="manual.html#min">min</A><BR> | |
| 183 | −<A HREF="manual.html#mod">mod</A><BR> | |
| 184 | −<A HREF="manual.html#mul event">mul event</A><BR> | |
| 268 | +<A HREF="manual.html#min"><TT>min</TT></A><BR> | |
| 269 | +<A HREF="manual.html#mod"><TT>mod</TT></A><BR> | |
| 270 | +<A HREF="manual.html#mul event">``mul'' event</A><BR> | |
| 185 | 271 | <A HREF="manual.html#multiple assignment">multiple assignment</A><BR> |
| 186 | −<A HREF="manual.html#newtag">newtag</A><BR> | |
| 187 | −<A HREF="manual.html#nextvar">nextvar</A><BR> | |
| 188 | −<A HREF="manual.html#next">next</A><BR> | |
| 272 | + | |
| 273 | + <P> | |
| 274 | + | |
| 275 | +<A HREF="manual.html#newtag"><TT>newtag</TT></A><BR> | |
| 276 | +<A HREF="manual.html#next"><TT>next</TT></A><BR> | |
| 189 | 277 | <A HREF="manual.html#nil">nil</A><BR> |
| 190 | 278 | <A HREF="manual.html#not">not</A><BR> |
| 191 | 279 | <A HREF="manual.html#number">number</A><BR> |
| 192 | −<A HREF="manual.html#openfile">openfile</A><BR> | |
| 280 | +<A HREF="manual.html#Numerical constants">numerical constants</A><BR> | |
| 281 | + | |
| 282 | + <P> | |
| 283 | + | |
| 284 | +<A HREF="manual.html#openfile"><TT>openfile</TT></A><BR> | |
| 285 | +<A HREF="manual.html#Operator precedence">operator precedence</A><BR> | |
| 193 | 286 | <A HREF="manual.html#or">or</A><BR> |
| 194 | −<A HREF="manual.html#packed results">packed results</A><BR> | |
| 195 | −<A HREF="manual.html#pattern item">pattern item</A><BR> | |
| 287 | + | |
| 288 | + <P> | |
| 289 | + | |
| 196 | 290 | <A HREF="manual.html#pattern">pattern</A><BR> |
| 291 | +<A HREF="manual.html#pattern item">pattern item</A><BR> | |
| 292 | +<A HREF="manual.html#PI"><TT>PI</TT></A><BR> | |
| 197 | 293 | <A HREF="manual.html#piped input">piped input</A><BR> |
| 198 | −<A HREF="manual.html#piped output">piped output</A><BR> | |
| 199 | −<A HREF="manual.html#popen">popen</A><BR> | |
| 200 | −<A HREF="manual.html#popen">popen</A><BR> | |
| 201 | −<A HREF="manual.html#pow event">pow event</A><BR> | |
| 294 | +<A HREF="manual.html#popen"><TT>popen</TT></A><BR> | |
| 295 | +<A HREF="manual.html#pow event">``pow'' event</A><BR> | |
| 202 | 296 | <A HREF="manual.html#pre-compilation">pre-compilation</A><BR> |
| 203 | −<A HREF="manual.html#predefined functions">predefined functions</A><BR> | |
| 204 | −<A HREF="manual.html#print">print</A><BR> | |
| 297 | +<A HREF="manual.html#print"><TT>print</TT></A><BR> | |
| 205 | 298 | <A HREF="manual.html#protected calls">protected calls</A><BR> |
| 206 | −<A HREF="manual.html#rad">rad</A><BR> | |
| 207 | −<A HREF="manual.html#randomseed">randomseed</A><BR> | |
| 208 | −<A HREF="manual.html#random">random</A><BR> | |
| 209 | −<A HREF="manual.html#rawgetglobal">rawgetglobal</A><BR> | |
| 210 | −<A HREF="manual.html#rawgettable">rawgettable</A><BR> | |
| 211 | −<A HREF="manual.html#rawsetglobal">rawsetglobal</A><BR> | |
| 212 | −<A HREF="manual.html#rawsettable">rawsettable</A><BR> | |
| 213 | −<A HREF="manual.html#read pattern">read pattern</A><BR> | |
| 214 | −<A HREF="manual.html#readfrom">readfrom</A><BR> | |
| 215 | −<A HREF="manual.html#read">read</A><BR> | |
| 299 | + | |
| 300 | + <P> | |
| 301 | + | |
| 302 | +<A HREF="manual.html#rad"><TT>rad</TT></A><BR> | |
| 303 | +<A HREF="manual.html#random"><TT>random</TT></A><BR> | |
| 304 | +<A HREF="manual.html#randomseed"><TT>randomseed</TT></A><BR> | |
| 305 | +<A HREF="manual.html#rawget"><TT>rawget</TT></A><BR> | |
| 306 | +<A HREF="manual.html#rawset"><TT>rawset</TT></A><BR> | |
| 307 | +<A HREF="manual.html#read"><TT>read</TT></A><BR> | |
| 308 | +<A HREF="manual.html#readfrom"><TT>readfrom</TT></A><BR> | |
| 216 | 309 | <A HREF="manual.html#records">records</A><BR> |
| 217 | 310 | <A HREF="manual.html#reference">reference</A><BR> |
| 218 | −<A HREF="manual.html#reflexivity">reflexivity</A><BR> | |
| 219 | 311 | <A HREF="manual.html#relational operators">relational operators</A><BR> |
| 220 | −<A HREF="manual.html#remove">remove</A><BR> | |
| 221 | −<A HREF="manual.html#rename">rename</A><BR> | |
| 222 | −<A HREF="manual.html#repeat-until">repeat-until</A><BR> | |
| 312 | +<A HREF="manual.html#remove"><TT>remove</TT></A><BR> | |
| 313 | +<A HREF="manual.html#rename"><TT>rename</TT></A><BR> | |
| 314 | +<A HREF="manual.html#repeat-until statement">repeat-until statement</A><BR> | |
| 223 | 315 | <A HREF="manual.html#reserved words">reserved words</A><BR> |
| 224 | 316 | <A HREF="manual.html#return statement">return statement</A><BR> |
| 225 | −<A HREF="manual.html#return">return</A><BR> | |
| 226 | −<A HREF="manual.html#seek">seek</A><BR> | |
| 227 | −<A HREF="manual.html#self">self</A><BR> | |
| 228 | −<A HREF="manual.html#setcallhook">setcallhook</A><BR> | |
| 229 | −<A HREF="manual.html#setglobal event">setglobal event</A><BR> | |
| 230 | −<A HREF="manual.html#setglobal">setglobal</A><BR> | |
| 231 | −<A HREF="manual.html#setlinehook">setlinehook</A><BR> | |
| 232 | −<A HREF="manual.html#setlocale">setlocale</A><BR> | |
| 233 | −<A HREF="manual.html#setlocal">setlocal</A><BR> | |
| 234 | −<A HREF="manual.html#settable event">settable event</A><BR> | |
| 235 | −<A HREF="manual.html#settagmethod">settagmethod</A><BR> | |
| 236 | −<A HREF="manual.html#settagmethod">settagmethod</A><BR> | |
| 237 | −<A HREF="manual.html#settag">settag</A><BR> | |
| 317 | + | |
| 318 | + <P> | |
| 319 | + | |
| 320 | +<A HREF="manual.html#seek"><TT>seek</TT></A><BR> | |
| 321 | +<A HREF="manual.html#self"><TT>self</TT></A><BR> | |
| 322 | +<A HREF="manual.html#setcallhook"><TT>setcallhook</TT></A><BR> | |
| 323 | +<A HREF="manual.html#setglobal"><TT>setglobal</TT></A><BR> | |
| 324 | +<A HREF="manual.html#setglobal event">``setglobal'' event</A><BR> | |
| 325 | +<A HREF="manual.html#setlinehook"><TT>setlinehook</TT></A><BR> | |
| 326 | +<A HREF="manual.html#setlocal"><TT>setlocal</TT></A><BR> | |
| 327 | +<A HREF="manual.html#setlocale"><TT>setlocale</TT></A><BR> | |
| 328 | +<A HREF="manual.html#settable event">``settable'' event</A><BR> | |
| 329 | +<A HREF="manual.html#settag"><TT>settag</TT></A><BR> | |
| 330 | +<A HREF="manual.html#settagmethod"><TT>settagmethod</TT></A><BR> | |
| 238 | 331 | <A HREF="manual.html#short-cut evaluation">short-cut evaluation</A><BR> |
| 239 | −<A HREF="manual.html#sin">sin</A><BR> | |
| 240 | −<A HREF="manual.html#skips">skips</A><BR> | |
| 241 | −<A HREF="manual.html#sort">sort</A><BR> | |
| 242 | −<A HREF="manual.html#sqrt">sqrt</A><BR> | |
| 332 | +<A HREF="manual.html#sin"><TT>sin</TT></A><BR> | |
| 333 | +<A HREF="manual.html#sort"><TT>sort</TT></A><BR> | |
| 334 | +<A HREF="manual.html#sqrt"><TT>sqrt</TT></A><BR> | |
| 335 | +<A HREF="manual.html#stack index">stack index</A><BR> | |
| 336 | +<A HREF="manual.html#state">state</A><BR> | |
| 243 | 337 | <A HREF="manual.html#statements">statements</A><BR> |
| 244 | −<A HREF="manual.html#stderr">stderr</A><BR> | |
| 245 | −<A HREF="manual.html#strbyte">strbyte</A><BR> | |
| 246 | −<A HREF="manual.html#strchar">strchar</A><BR> | |
| 247 | −<A HREF="manual.html#strfind">strfind</A><BR> | |
| 338 | +<A HREF="manual.html#stderr"><TT>stderr</TT></A><BR> | |
| 339 | +<A HREF="manual.html#strbyte"><TT>strbyte</TT></A><BR> | |
| 340 | +<A HREF="manual.html#strchar"><TT>strchar</TT></A><BR> | |
| 341 | +<A HREF="manual.html#strfind"><TT>strfind</TT></A><BR> | |
| 248 | 342 | <A HREF="manual.html#string">string</A><BR> |
| 249 | −<A HREF="manual.html#strlen">strlen</A><BR> | |
| 250 | −<A HREF="manual.html#strlower">strlower</A><BR> | |
| 251 | −<A HREF="manual.html#strrep">strrep</A><BR> | |
| 252 | −<A HREF="manual.html#strsub">strsub</A><BR> | |
| 253 | −<A HREF="manual.html#strupper">strupper</A><BR> | |
| 254 | −<A HREF="manual.html#sub event">sub event</A><BR> | |
| 343 | +<A HREF="manual.html#strlen"><TT>strlen</TT></A><BR> | |
| 344 | +<A HREF="manual.html#strlower"><TT>strlower</TT></A><BR> | |
| 345 | +<A HREF="manual.html#strrep"><TT>strrep</TT></A><BR> | |
| 346 | +<A HREF="manual.html#strsub"><TT>strsub</TT></A><BR> | |
| 347 | +<A HREF="manual.html#strupper"><TT>strupper</TT></A><BR> | |
| 348 | +<A HREF="manual.html#sub event">``sub'' event</A><BR> | |
| 349 | + | |
| 350 | + <P> | |
| 351 | + | |
| 255 | 352 | <A HREF="manual.html#table">table</A><BR> |
| 256 | −<A HREF="manual.html#tag methods">tag methods</A><BR> | |
| 257 | 353 | <A HREF="manual.html#tag">tag</A><BR> |
| 258 | −<A HREF="manual.html#tag">tag</A><BR> | |
| 259 | −<A HREF="manual.html#tan">tan</A><BR> | |
| 260 | −<A HREF="manual.html#tinsert">tinsert</A><BR> | |
| 261 | −<A HREF="manual.html#tmpname">tmpname</A><BR> | |
| 354 | +<A HREF="manual.html#tag"><TT>tag</TT></A><BR> | |
| 355 | +<A HREF="manual.html#tag method">tag method</A><BR> | |
| 356 | +....... <A HREF="manual.html#add">add</A><BR> | |
| 357 | +....... <A HREF="manual.html#concatenation">concatenation</A><BR> | |
| 358 | +....... <A HREF="manual.html#div">div</A><BR> | |
| 359 | +....... <A HREF="manual.html#function">function</A><BR> | |
| 360 | +....... <A HREF="manual.html#gc">gc</A><BR> | |
| 361 | +....... <A HREF="manual.html#getglobal">getglobal</A><BR> | |
| 362 | +....... <A HREF="manual.html#gettable">gettable</A><BR> | |
| 363 | +....... <A HREF="manual.html#index">index</A><BR> | |
| 364 | +....... <A HREF="manual.html#lt">lt</A><BR> | |
| 365 | +....... <A HREF="manual.html#mul">mul</A><BR> | |
| 366 | +....... <A HREF="manual.html#pow">pow</A><BR> | |
| 367 | +....... <A HREF="manual.html#setglobal">setglobal</A><BR> | |
| 368 | +....... <A HREF="manual.html#settable">settable</A><BR> | |
| 369 | +....... <A HREF="manual.html#sub">sub</A><BR> | |
| 370 | +....... <A HREF="manual.html#unm">unm</A><BR> | |
| 371 | +<A HREF="manual.html#tan"><TT>tan</TT></A><BR> | |
| 372 | +<A HREF="manual.html#tinsert"><TT>tinsert</TT></A><BR> | |
| 373 | +<A HREF="manual.html#tmpname"><TT>tmpname</TT></A><BR> | |
| 262 | 374 | <A HREF="manual.html#tokens">tokens</A><BR> |
| 263 | −<A HREF="manual.html#tonumber">tonumber</A><BR> | |
| 264 | −<A HREF="manual.html#tostring">tostring</A><BR> | |
| 265 | −<A HREF="manual.html#tremove">tremove</A><BR> | |
| 266 | −<A HREF="manual.html#type">type</A><BR> | |
| 267 | −<A HREF="manual.html#unm event">unm event</A><BR> | |
| 375 | +<A HREF="manual.html#tonumber"><TT>tonumber</TT></A><BR> | |
| 376 | +<A HREF="manual.html#tostring"><TT>tostring</TT></A><BR> | |
| 377 | +<A HREF="manual.html#tremove"><TT>tremove</TT></A><BR> | |
| 378 | +<A HREF="manual.html#type"><TT>type</TT></A><BR> | |
| 379 | +<A HREF="manual.html#Types and Tags">types and tags</A><BR> | |
| 380 | + | |
| 381 | + <P> | |
| 382 | + | |
| 383 | +<A HREF="manual.html#unm event">``unm'' event</A><BR> | |
| 384 | +<A HREF="manual.html#upvalues">upvalues</A><BR> | |
| 268 | 385 | <A HREF="manual.html#userdata">userdata</A><BR> |
| 269 | −<A HREF="manual.html#vararg">vararg</A><BR> | |
| 270 | −<A HREF="manual.html#version 3.0">version 3.0</A><BR> | |
| 271 | −<A HREF="manual.html#version 3.1">version 3.1</A><BR> | |
| 272 | −<A HREF="manual.html#while-do">while-do</A><BR> | |
| 273 | −<A HREF="manual.html#writeto">writeto</A><BR> | |
| 274 | −<A HREF="manual.html#write">write</A><BR> | |
| 386 | + | |
| 387 | + <P> | |
| 388 | + | |
| 389 | +<A HREF="manual.html#valid index">valid index</A><BR> | |
| 390 | +<A HREF="manual.html#vararg function">vararg function</A><BR> | |
| 391 | +<A HREF="manual.html#version 3.2">version 3.2</A><BR> | |
| 392 | +<A HREF="manual.html#visibility">visibility</A><BR> | |
| 393 | + | |
| 394 | + <P> | |
| 395 | + | |
| 396 | +<A HREF="manual.html#while-do statement">while-do statement</A><BR> | |
| 397 | +<A HREF="manual.html#write"><TT>write</TT></A><BR> | |
| 398 | +<A HREF="manual.html#writeto"><TT>writeto</TT></A><BR> | |
| 399 | + | |
| 400 | + <P> | |
| 401 | + | |
| 275 | 402 | |
| 276 | 403 | <HR> |
| 277 | 404 | <SMALL> |
| 278 | 405 | Last update: |
| 279 | −Wed Jul 7 13:36:24 EST 1999 | |
| 406 | +Mon Nov 6 17:35:51 EDT 2000 | |
| 280 | 407 | by <A HREF="http://www.tecgraf.puc-rio.br/~lhf/">lhf</A>. |
| 281 | 408 | </SMALL> |
| 282 | 409 | |
| @@ -1,30 +1,23 @@ | ||
| 1 | 1 | <HTML> |
| 2 | 2 | <HEAD> |
| 3 | −<TITLE>Lua 3.2 Reference Manual - Contents</TITLE> | |
| 3 | +<TITLE>Lua: reference manual - contents</TITLE> | |
| 4 | 4 | </HEAD> |
| 5 | 5 | |
| 6 | 6 | <BODY BGCOLOR="#FFFFFF"> |
| 7 | 7 | |
| 8 | 8 | <HR> |
| 9 | −<H1>Reference Manual of the Programming Language | |
| 10 | −<A HREF="http://www.tecgraf.puc-rio.br/lua/">Lua</A> | |
| 11 | −3.2</H1> | |
| 12 | −<P> | |
| 13 | −<A HREF="http://www.inf.puc-rio.br/~roberto/">Roberto Ierusalimschy</A>, | |
| 14 | −<A HREF="http://www.tecgraf.puc-rio.br/~lhf/">Luiz Henrique de Figueiredo</A>, | |
| 15 | −<A HREF="http://www.tecgraf.puc-rio.br/~celes/">Waldemar Celes</A> | |
| 16 | −<BR> | |
| 17 | −<A HREF="mailto:lua@tecgraf.puc-rio.br">lua@tecgraf.puc-rio.br</A><BR> | |
| 18 | −<A HREF="http://www.tecgraf.puc-rio.br">TeCGraf</A>, | |
| 19 | −<A HREF="http://www.inf.puc-rio.br">Computer Science Department</A>, | |
| 20 | −<A HREF="http://www.puc-rio.br">PUC-Rio</A> | |
| 21 | −<P> | |
| 9 | +<H1> | |
| 10 | +<IMG SRC="logo.gif" ALT="Lua" ALIGN="bottom"> | |
| 11 | +Reference manual | |
| 12 | +</H1> | |
| 22 | 13 | |
| 14 | +<A HREF="manual.html"> | |
| 15 | +Reference Manual of the Programming Language | |
| 16 | +<A HREF="http://www.tecgraf.puc-rio.br/lua/">Lua</A> | |
| 17 | +4.0</A> | |
| 23 | 18 | [ |
| 24 | 19 | <A HREF="manual.html">top</A> |
| 25 | 20 | | |
| 26 | −<A HREF="#contents">contents</A> | |
| 27 | −| | |
| 28 | 21 | <A HREF="idx.html">index</A> |
| 29 | 22 | | |
| 30 | 23 | <A HREF="ftp://ftp.tecgraf.puc-rio.br/pub/lua/refman.ps.gz">ps</A> |
| @@ -33,7 +26,7 @@ · 2 unmodified lines | ||
| 33 | 26 | | |
| 34 | 27 | <A HREF="old/">old versions</A> |
| 35 | 28 | ] |
| 36 | −<HR> | |
| 29 | +<P> | |
| 37 | 30 | <A NAME="contents"></A> |
| 38 | 31 | <UL> |
| 39 | 32 | <LI><A HREF="manual.html#1.">1 - Introduction</A> |
| @@ -42,50 +35,57 @@ · 2 unmodified lines | ||
| 42 | 35 | <LI><A HREF="manual.html#4.">4 - The Language</A> |
| 43 | 36 | <UL> |
| 44 | 37 | <LI><A HREF="manual.html#4.1">4.1 - Lexical Conventions</A> |
| 45 | − <LI><A HREF="manual.html#4.2">4.2 - The Pre-processor</A> | |
| 46 | − <LI><A HREF="manual.html#4.3">4.3 - Coercion</A> | |
| 47 | − <LI><A HREF="manual.html#4.4">4.4 - Adjustment</A> | |
| 48 | − <LI><A HREF="manual.html#4.5">4.5 - Statements</A> | |
| 49 | − <LI><A HREF="manual.html#4.6">4.6 - Expressions</A> | |
| 50 | − <LI><A HREF="manual.html#4.7">4.7 - Visibility and Upvalues</A> | |
| 38 | + <LI><A HREF="manual.html#4.2">4.2 - Coercion</A> | |
| 39 | + <LI><A HREF="manual.html#4.3">4.3 - Adjustment</A> | |
| 40 | + <LI><A HREF="manual.html#4.4">4.4 - Statements</A> | |
| 41 | + <LI><A HREF="manual.html#4.5">4.5 - Expressions</A> | |
| 42 | + <LI><A HREF="manual.html#4.6">4.6 - Visibility and Upvalues</A> | |
| 43 | + <LI><A HREF="manual.html#4.7">4.7 - Error Handling</A> | |
| 51 | 44 | <LI><A HREF="manual.html#4.8">4.8 - Tag Methods</A> |
| 52 | − <LI><A HREF="manual.html#4.9">4.9 - Error Handling</A> | |
| 53 | 45 | </UL> |
| 54 | 46 | <LI><A HREF="manual.html#5.">5 - The Application Program Interface</A> |
| 55 | 47 | <UL> |
| 56 | − <LI><A HREF="manual.html#5.1">5.1 - Managing States</A> | |
| 57 | − <LI><A HREF="manual.html#5.2">5.2 - Exchanging Values between C and Lua</A> | |
| 58 | − <LI><A HREF="manual.html#5.3">5.3 - Garbage Collection</A> | |
| 59 | − <LI><A HREF="manual.html#5.4">5.4 - Executing Lua Code</A> | |
| 60 | − <LI><A HREF="manual.html#5.5">5.5 - Manipulating Lua Objects</A> | |
| 61 | − <LI><A HREF="manual.html#5.6">5.6 - Calling Lua Functions</A> | |
| 62 | − <LI><A HREF="manual.html#5.7">5.7 - C Functions</A> | |
| 63 | − <LI><A HREF="manual.html#5.8">5.8 - References to Lua Objects</A> | |
| 48 | + <LI><A HREF="manual.html#5.1">5.1 - States</A> | |
| 49 | + <LI><A HREF="manual.html#5.2">5.2 - The Stack and Indices</A> | |
| 50 | + <LI><A HREF="manual.html#5.3">5.3 - Stack Manipulation</A> | |
| 51 | + <LI><A HREF="manual.html#5.4">5.4 - Querying the Stack</A> | |
| 52 | + <LI><A HREF="manual.html#5.5">5.5 - Pushing values onto the Stack</A> | |
| 53 | + <LI><A HREF="manual.html#5.6">5.6 - Garbage Collection</A> | |
| 54 | + <LI><A HREF="manual.html#5.7">5.7 - Userdata and Tags</A> | |
| 55 | + <LI><A HREF="manual.html#5.8">5.8 - Executing Lua Code</A> | |
| 56 | + <LI><A HREF="manual.html#5.9">5.9 - Manipulating Global Variables in Lua</A> | |
| 57 | + <LI><A HREF="manual.html#5.10">5.10 - Manipulating Tables in Lua</A> | |
| 58 | + <LI><A HREF="manual.html#5.11">5.11 - Using Tables as Arrays</A> | |
| 59 | + <LI><A HREF="manual.html#5.12">5.12 - Calling Lua Functions</A> | |
| 60 | + <LI><A HREF="manual.html#5.13">5.13 - Defining C Functions</A> | |
| 61 | + <LI><A HREF="manual.html#5.14">5.14 - References to Lua Objects</A> | |
| 64 | 62 | </UL> |
| 65 | −<LI><A HREF="manual.html#6.">6 - Predefined Functions and Libraries</A> | |
| 63 | +<LI><A HREF="manual.html#6.">6 - Standard Libraries</A> | |
| 66 | 64 | <UL> |
| 67 | − <LI><A HREF="manual.html#6.1">6.1 - Predefined Functions</A> | |
| 65 | + <LI><A HREF="manual.html#6.1">6.1 - Basic Functions</A> | |
| 68 | 66 | <LI><A HREF="manual.html#6.2">6.2 - String Manipulation</A> |
| 69 | 67 | <LI><A HREF="manual.html#6.3">6.3 - Mathematical Functions</A> |
| 70 | 68 | <LI><A HREF="manual.html#6.4">6.4 - I/O Facilities</A> |
| 69 | + <LI><A HREF="manual.html#6.5">6.5 - System Facilities</A> | |
| 71 | 70 | </UL> |
| 72 | −<LI><A HREF="manual.html#7.">7 - The Debugger Interface</A> | |
| 71 | +<LI><A HREF="manual.html#7.">7 - The Debug Interface</A> | |
| 73 | 72 | <UL> |
| 74 | 73 | <LI><A HREF="manual.html#7.1">7.1 - Stack and Function Information</A> |
| 75 | 74 | <LI><A HREF="manual.html#7.2">7.2 - Manipulating Local Variables</A> |
| 76 | 75 | <LI><A HREF="manual.html#7.3">7.3 - Hooks</A> |
| 77 | − <LI><A HREF="manual.html#7.4">7.4 - The Reflexive Debugger Interface</A> | |
| 76 | + <LI><A HREF="manual.html#7.4">7.4 - The Reflexive Debug Interface</A> | |
| 78 | 77 | </UL> |
| 79 | 78 | <LI><A HREF="manual.html#8.">8 - Lua Stand-alone</A> |
| 80 | 79 | <LI><A HREF="manual.html#Acknowledgments">Acknowledgments</A> |
| 81 | 80 | <LI><A HREF="manual.html#Incompatibilities">Incompatibilities with Previous Versions</A> |
| 81 | +<LI><A HREF="manual.html#BNF">The Complete Syntax of Lua</A> | |
| 82 | 82 | <LI><A HREF="idx.html">Index</A> |
| 83 | 83 | </UL> |
| 84 | 84 | |
| 85 | 85 | <HR> |
| 86 | 86 | <SMALL> |
| 87 | 87 | Last update: |
| 88 | −Wed Jul 7 13:36:24 EST 1999 | |
| 88 | +Mon Nov 6 17:36:08 EDT 2000 | |
| 89 | 89 | by <A HREF="http://www.tecgraf.puc-rio.br/~lhf/">lhf</A>. |
| 90 | 90 | </SMALL> |
| 91 | 91 | |
Binary file not shown.
| @@ -0,0 +1,143 @@ | ||
| 1 | +.\" lua.man,v 1.3 2000/09/04 21:41:28 lhf Exp | |
| 2 | +.TH LUA 1 "2000/09/04 21:41:28" | |
| 3 | +.SH NAME | |
| 4 | +lua \- Lua interpreter | |
| 5 | +.SH SYNOPSIS | |
| 6 | +.B lua | |
| 7 | +[ | |
| 8 | +.I arguments | |
| 9 | +] | |
| 10 | +.SH DESCRIPTION | |
| 11 | +.B lua | |
| 12 | +is the stand-alone Lua interpreter. | |
| 13 | +It loads and executes Lua programs, | |
| 14 | +either in textual source form or | |
| 15 | +in precompiled binary form, | |
| 16 | +as output by | |
| 17 | +.BR luac , | |
| 18 | +the Lua compiler. | |
| 19 | +.B lua | |
| 20 | +can be used as a batch interpreter and also interactively. | |
| 21 | +.LP | |
| 22 | +The | |
| 23 | +.I arguments | |
| 24 | +can be options, assignments, or filenames, | |
| 25 | +and are processed in order, | |
| 26 | +from left to right. | |
| 27 | +.LP | |
| 28 | +Options start with | |
| 29 | +.B \- | |
| 30 | +and are described below. | |
| 31 | +.LP | |
| 32 | +An assignment is an argument of the form | |
| 33 | +.BR a=b , | |
| 34 | +which assigns the string | |
| 35 | +.RB ` b ' | |
| 36 | +to the global variable | |
| 37 | +.BR a . | |
| 38 | +Note that no quotes are needed around the string if it does not contain spaces | |
| 39 | +or other characters special to the shell. | |
| 40 | +This is for convenience only. | |
| 41 | +(In general, | |
| 42 | +you should be careful when using quotes and spaces on the command line | |
| 43 | +because they are usually handled by the shell.) | |
| 44 | +.LP | |
| 45 | +If the argument is neither an option nor an assignment, | |
| 46 | +then it is assumed to be a filename, | |
| 47 | +which is then loaded and executed. | |
| 48 | +.LP | |
| 49 | +If no arguments are given, | |
| 50 | +then | |
| 51 | +.B "\-v \-i" | |
| 52 | +is assumed when the standard input is a terminal; | |
| 53 | +otherwise, | |
| 54 | +.B \- | |
| 55 | +is assumed. | |
| 56 | +.SH OPTIONS | |
| 57 | +.TP | |
| 58 | +.B \- | |
| 59 | +load the standard input as a file, | |
| 60 | +that is, | |
| 61 | +not interactively, | |
| 62 | +even when the standard input is a terminal. | |
| 63 | +.TP | |
| 64 | +.B \-c | |
| 65 | +close Lua before exiting. | |
| 66 | +.TP | |
| 67 | +.BI \-e " stat" | |
| 68 | +execute statement | |
| 69 | +.IR stat . | |
| 70 | +You will need to quote | |
| 71 | +.I stat | |
| 72 | +if it contains spaces or quotes. | |
| 73 | +.TP | |
| 74 | +.BI \-f " file" | |
| 75 | +collect all remaining arguments as strings into a global table named | |
| 76 | +.B arg | |
| 77 | +and then execute | |
| 78 | +.IR file . | |
| 79 | +The arguments in | |
| 80 | +.B arg | |
| 81 | +start at 0, | |
| 82 | +which contains the string | |
| 83 | +.RI ` file '. | |
| 84 | +The index of the last argument is stored in | |
| 85 | +.BR "arg.n" . | |
| 86 | +.TP | |
| 87 | +.B \-i | |
| 88 | +enter interactive mode, | |
| 89 | +displaying a prompt. | |
| 90 | +In this mode, | |
| 91 | +.B lua | |
| 92 | +reads lines from the standard input and executes them as they are read. | |
| 93 | +Each line must contain a complete statement. | |
| 94 | +To span a statement across several lines, end each line with a backslash | |
| 95 | +.BR `\e' . | |
| 96 | +The prompt shown is the value of the global variable | |
| 97 | +.BR _PROMPT , | |
| 98 | +if this value is a string. | |
| 99 | +So, | |
| 100 | +to change the prompt, | |
| 101 | +set | |
| 102 | +.B _PROMPT | |
| 103 | +to a string of your choice. | |
| 104 | +You can do that after calling the interpreter | |
| 105 | +or on the command line with | |
| 106 | +.BR "_PROMPT=\'lua: \'" , | |
| 107 | +for example. | |
| 108 | +(Note the need for quotes, because the string contains a space.) | |
| 109 | +The default prompt is ``> ''. | |
| 110 | +.TP | |
| 111 | +.B \-q | |
| 112 | +enter interactive mode, | |
| 113 | +but without displaying a prompt. | |
| 114 | +.TP | |
| 115 | +.BI \-s n | |
| 116 | +set the stack size to | |
| 117 | +.IB n . | |
| 118 | +If present, | |
| 119 | +this must be the first option. | |
| 120 | +Note that | |
| 121 | +.I n | |
| 122 | +is in the same argument as | |
| 123 | +.BR -s . | |
| 124 | +For example, | |
| 125 | +to specify a stack size of 2000, | |
| 126 | +use | |
| 127 | +.BR -s2000 . | |
| 128 | +.TP | |
| 129 | +.B \-v | |
| 130 | +print version information. | |
| 131 | +.SH "SEE ALSO" | |
| 132 | +.BR luac (1) | |
| 133 | +.br | |
| 134 | +http://www.tecgraf.puc-rio.br/lua/ | |
| 135 | +.SH DIAGNOSTICS | |
| 136 | +Error messages should be self explanatory. | |
| 137 | +.SH AUTHORS | |
| 138 | +R. Ierusalimschy, | |
| 139 | +L. H. de Figueiredo, | |
| 140 | +and | |
| 141 | +W. Celes | |
| 142 | +(lua@tecgraf.puc-rio.br) | |
| 143 | +.\" EOF | |
| @@ -0,0 +1,151 @@ | ||
| 1 | +<!-- lua.man,v 1.3 2000/09/04 21:41:28 lhf Exp --> | |
| 2 | +<HTML> | |
| 3 | +<HEAD> | |
| 4 | +<TITLE>LUA man page</TITLE> | |
| 5 | +</HEAD> | |
| 6 | + | |
| 7 | +<BODY BGCOLOR="#FFFFFF"> | |
| 8 | + | |
| 9 | +<H1>NAME</H1> | |
| 10 | +lua - Lua interpreter | |
| 11 | +<H1>SYNOPSIS</H1> | |
| 12 | +<B>lua</B> | |
| 13 | +[ | |
| 14 | +<I>arguments</I> | |
| 15 | +] | |
| 16 | +<H1>DESCRIPTION</H1> | |
| 17 | +<B>lua</B> | |
| 18 | +is the stand-alone Lua interpreter. | |
| 19 | +It loads and executes Lua programs, | |
| 20 | +either in textual source form or | |
| 21 | +in precompiled binary form, | |
| 22 | +as output by | |
| 23 | +<B>luac</B>, | |
| 24 | +the Lua compiler. | |
| 25 | +<B>lua</B> | |
| 26 | +can be used as a batch interpreter and also interactively. | |
| 27 | +<P> | |
| 28 | +The | |
| 29 | +<I>arguments</I> | |
| 30 | +can be options, assignments, or filenames, | |
| 31 | +and are processed in order, | |
| 32 | +from left to right. | |
| 33 | +<P> | |
| 34 | +Options start with | |
| 35 | +<B>-</B> | |
| 36 | +and are described below. | |
| 37 | +<P> | |
| 38 | +An assignment is an argument of the form | |
| 39 | +<B>a=b</B>, | |
| 40 | +which assigns the string | |
| 41 | +.RB ` b ' | |
| 42 | +to the global variable | |
| 43 | +<B>a</B>. | |
| 44 | +Note that no quotes are needed around the string if it does not contain spaces | |
| 45 | +or other characters special to the shell. | |
| 46 | +This is for convenience only. | |
| 47 | +(In general, | |
| 48 | +you should be careful when using quotes and spaces on the command line | |
| 49 | +because they are usually handled by the shell.) | |
| 50 | +<P> | |
| 51 | +If the argument is neither an option nor an assignment, | |
| 52 | +then it is assumed to be a filename, | |
| 53 | +which is then loaded and executed. | |
| 54 | +<P> | |
| 55 | +If no arguments are given, | |
| 56 | +then | |
| 57 | +<B>"-v -i"</B> | |
| 58 | +is assumed when the standard input is a terminal; | |
| 59 | +otherwise, | |
| 60 | +<B>-</B> | |
| 61 | +is assumed. | |
| 62 | +<H1>OPTIONS</H1> | |
| 63 | +<P> | |
| 64 | +<B>-</B> | |
| 65 | +load the standard input as a file, | |
| 66 | +that is, | |
| 67 | +not interactively, | |
| 68 | +even when the standard input is a terminal. | |
| 69 | +<P> | |
| 70 | +<B>-c</B> | |
| 71 | +close Lua before exiting. | |
| 72 | +<P> | |
| 73 | +<B>-e "</B><I>stat"</I> | |
| 74 | +execute statement | |
| 75 | +<I>stat</I>. | |
| 76 | +You will need to quote | |
| 77 | +<I>stat </I> | |
| 78 | +if it contains spaces or quotes. | |
| 79 | +<P> | |
| 80 | +<B>-f "</B><I>file"</I> | |
| 81 | +collect all remaining arguments as strings into a global table named | |
| 82 | +<B>arg</B> | |
| 83 | +and then execute | |
| 84 | +<I>file</I>. | |
| 85 | +The arguments in | |
| 86 | +<B>arg</B> | |
| 87 | +start at 0, | |
| 88 | +which contains the string | |
| 89 | +.RI ` file '. | |
| 90 | +The index of the last argument is stored in | |
| 91 | +<B>"arg.n"</B>. | |
| 92 | +<P> | |
| 93 | +<B>-i</B> | |
| 94 | +enter interactive mode, | |
| 95 | +displaying a prompt. | |
| 96 | +In this mode, | |
| 97 | +<B>lua</B> | |
| 98 | +reads lines from the standard input and executes them as they are read. | |
| 99 | +Each line must contain a complete statement. | |
| 100 | +To span a statement across several lines, end each line with a backslash | |
| 101 | +<B>`\e'</B>. | |
| 102 | +The prompt shown is the value of the global variable | |
| 103 | +<B>_PROMPT</B>, | |
| 104 | +if this value is a string. | |
| 105 | +So, | |
| 106 | +to change the prompt, | |
| 107 | +set | |
| 108 | +<B>_PROMPT</B> | |
| 109 | +to a string of your choice. | |
| 110 | +You can do that after calling the interpreter | |
| 111 | +or on the command line with | |
| 112 | +<B>"_PROMPT=\'lua: \'"</B>, | |
| 113 | +for example. | |
| 114 | +(Note the need for quotes, because the string contains a space.) | |
| 115 | +The default prompt is ``> ''. | |
| 116 | +<P> | |
| 117 | +<B>-q</B> | |
| 118 | +enter interactive mode, | |
| 119 | +but without displaying a prompt. | |
| 120 | +<P> | |
| 121 | +<B>-s</B><I>n</I> | |
| 122 | +set the stack size to | |
| 123 | +.IB n . | |
| 124 | +If present, | |
| 125 | +this must be the first option. | |
| 126 | +Note that | |
| 127 | +<I>n</I> | |
| 128 | +is in the same argument as | |
| 129 | +<B>-s</B>. | |
| 130 | +For example, | |
| 131 | +to specify a stack size of 2000, | |
| 132 | +use | |
| 133 | +<B>-s2000</B>. | |
| 134 | +<P> | |
| 135 | +<B>-v</B> | |
| 136 | +print version information. | |
| 137 | +<H1>SEE ALSO</H1> | |
| 138 | +<B>luac</B>(1) | |
| 139 | +<BR> | |
| 140 | +<A HREF="http://www.tecgraf.puc-rio.br/lua/">http://www.tecgraf.puc-rio.br/lua/</A> | |
| 141 | +<H1>DIAGNOSTICS</H1> | |
| 142 | +Error messages should be self explanatory. | |
| 143 | +<H1>AUTHORS</H1> | |
| 144 | +R. Ierusalimschy, | |
| 145 | +L. H. de Figueiredo, | |
| 146 | +and | |
| 147 | +W. Celes | |
| 148 | +(<A HREF="mailto:lua@tecgraf.puc-rio.br">lua@tecgraf.puc-rio.br</A>) | |
| 149 | +<!-- EOF --> | |
| 150 | +</BODY> | |
| 151 | +</HTML> | |
| @@ -0,0 +1,139 @@ | ||
| 1 | +.\" luac.man,v 1.20 2000/10/06 15:11:21 lhf Exp | |
| 2 | +.TH LUAC 1 "2000/10/06 15:11:21" | |
| 3 | +.SH NAME | |
| 4 | +luac \- Lua compiler | |
| 5 | +.SH SYNOPSIS | |
| 6 | +.B luac | |
| 7 | +[ | |
| 8 | +.I options | |
| 9 | +] [ | |
| 10 | +.I filenames | |
| 11 | +] | |
| 12 | +.SH DESCRIPTION | |
| 13 | +.B luac | |
| 14 | +is the Lua compiler. | |
| 15 | +It translates programs written in the Lua programming language | |
| 16 | +into binary files that can be loaded and executed with | |
| 17 | +.B lua_dofile | |
| 18 | +in C or with | |
| 19 | +.B dofile | |
| 20 | +in Lua. | |
| 21 | +.LP | |
| 22 | +The main advantages of precompiling chunks are: | |
| 23 | +faster loading, | |
| 24 | +protecting source code from user changes, | |
| 25 | +and | |
| 26 | +off-line syntax error detection. | |
| 27 | +.LP | |
| 28 | +Pre-compiling does not imply faster execution | |
| 29 | +because in Lua chunks are always compiled into bytecodes before being executed. | |
| 30 | +.B luac | |
| 31 | +simply allows those bytecodes to be saved in a file for later execution. | |
| 32 | +.LP | |
| 33 | +.B luac | |
| 34 | +produces a single output file containing the bytecodes | |
| 35 | +for all source files given. | |
| 36 | +By default, | |
| 37 | +the output file is named | |
| 38 | +.BR luac.out , | |
| 39 | +but you can change this with the | |
| 40 | +.B \-o | |
| 41 | +option. | |
| 42 | +.LP | |
| 43 | +The binary files created by | |
| 44 | +.B luac | |
| 45 | +are portable to all architectures with the same word size. | |
| 46 | +This means that | |
| 47 | +binary files created on a 32-bit platform (such as Intel) | |
| 48 | +can be read without change in another 32-bit platform (such as Sparc), | |
| 49 | +even if the byte order (``endianess'') is different. | |
| 50 | +On the other hand, | |
| 51 | +binary files created on a 16-bit platform cannot be read in a 32-bit platform. | |
| 52 | +.LP | |
| 53 | +In the command line, | |
| 54 | +you can mix | |
| 55 | +text files containing Lua source and | |
| 56 | +binary files containing precompiled chunks. | |
| 57 | +This is useful to combine several precompiled chunks, | |
| 58 | +even from different (but compatible) platforms, | |
| 59 | +into a single precompiled chunk. | |
| 60 | +.LP | |
| 61 | +You can use | |
| 62 | +.B "\-" | |
| 63 | +to indicate | |
| 64 | +.I stdin | |
| 65 | +as a source file. | |
| 66 | +.LP | |
| 67 | +The internal format of the binary files produced by | |
| 68 | +.B luac | |
| 69 | +may change when a new version of Lua is released. | |
| 70 | +We try to maintain compatibility even for binary files, | |
| 71 | +but it is not always possible. | |
| 72 | +So, | |
| 73 | +save the source files of all Lua programs that you precompile. | |
| 74 | +.LP | |
| 75 | +.SH OPTIONS | |
| 76 | +Options must be separate. | |
| 77 | +.TP | |
| 78 | +.B \-l | |
| 79 | +produce a listing of the compiled bytecode for Lua's virtual machine. | |
| 80 | +Listing bytecodes is useful to learn about Lua's virtual machine. | |
| 81 | +If no files are given, then | |
| 82 | +.B luac | |
| 83 | +loads | |
| 84 | +.B luac.out | |
| 85 | +and lists its contents. | |
| 86 | +.TP | |
| 87 | +.BI \-o " file" | |
| 88 | +output to | |
| 89 | +.IR file , | |
| 90 | +instead of the default | |
| 91 | +.BR luac.out . | |
| 92 | +The output file can be a source file because | |
| 93 | +all files are loaded before the output file is written. | |
| 94 | +.TP | |
| 95 | +.B \-p | |
| 96 | +load files but do not generate any output file. | |
| 97 | +Used mainly for syntax checking or testing precompiled chunks: | |
| 98 | +corrupted files will probably generate errors when loaded. | |
| 99 | +For a thourough integrity test, | |
| 100 | +use | |
| 101 | +.BR \-t . | |
| 102 | +.TP | |
| 103 | +.B \-s | |
| 104 | +strip debug information before writing the output file. | |
| 105 | +This saves some space in very large chunks, | |
| 106 | +but if errors occur when running these chunks, | |
| 107 | +then the error messages might not contain the full information they usually do. | |
| 108 | +.TP | |
| 109 | +.B \-t | |
| 110 | +perform a thourough integrity test of precompiled chunks. | |
| 111 | +Code that passes this test is completely safe, | |
| 112 | +in the sense that it will not break the interpreter. | |
| 113 | +However, | |
| 114 | +there is no guarantee that such code does anything sensible. | |
| 115 | +(None can be given, because the halting problem is unsolvable.) | |
| 116 | +If no files are given, then | |
| 117 | +.B luac | |
| 118 | +loads | |
| 119 | +.B luac.out | |
| 120 | +and tests its contents. | |
| 121 | +.TP | |
| 122 | +.B \-v | |
| 123 | +print version information. | |
| 124 | +.SH FILES | |
| 125 | +.TP 15 | |
| 126 | +.B luac.out | |
| 127 | +default output file | |
| 128 | +.SH "SEE ALSO" | |
| 129 | +.BR lua (1) | |
| 130 | +.br | |
| 131 | +http://www.tecgraf.puc-rio.br/lua/ | |
| 132 | +.SH DIAGNOSTICS | |
| 133 | +Error messages should be self explanatory. | |
| 134 | +.SH AUTHORS | |
| 135 | +L. H. de Figueiredo, | |
| 136 | +R. Ierusalimschy and | |
| 137 | +W. Celes | |
| 138 | +(lua@tecgraf.puc-rio.br) | |
| 139 | +.\" EOF | |
| @@ -1,4 +1,4 @@ | ||
| 1 | −<!-- luac.man,v 1.17 1999/07/07 16:02:07 lhf Exp --> | |
| 1 | +<!-- luac.man,v 1.20 2000/10/06 15:11:21 lhf Exp --> | |
| 2 | 2 | <HTML> |
| 3 | 3 | <HEAD> |
| 4 | 4 | <TITLE>LUAC man page</TITLE> |
| @@ -25,14 +25,11 @@ in C or with · 20 unmodified lines | ||
| 25 | 25 | <B>dofile</B> |
| 26 | 26 | in Lua. |
| 27 | 27 | <P> |
| 28 | −The main advantages of pre-compiling chunks are: | |
| 28 | +The main advantages of precompiling chunks are: | |
| 29 | 29 | faster loading, |
| 30 | 30 | protecting source code from user changes, |
| 31 | 31 | and |
| 32 | 32 | off-line syntax error detection. |
| 33 | −The binary files created by | |
| 34 | −<B>luac</B> | |
| 35 | −are portable to all architectures. | |
| 36 | 33 | <P> |
| 37 | 34 | Pre-compiling does not imply faster execution |
| 38 | 35 | because in Lua chunks are always compiled into bytecodes before being executed. |
| @@ -49,126 +46,87 @@ but you can change this with the · 10 unmodified lines | ||
| 49 | 46 | <B>-o</B> |
| 50 | 47 | option. |
| 51 | 48 | <P> |
| 49 | +The binary files created by | |
| 50 | +<B>luac</B> | |
| 51 | +are portable to all architectures with the same word size. | |
| 52 | +This means that | |
| 53 | +binary files created on a 32-bit platform (such as Intel) | |
| 54 | +can be read without change in another 32-bit platform (such as Sparc), | |
| 55 | +even if the byte order (``endianess'') is different. | |
| 56 | +On the other hand, | |
| 57 | +binary files created on a 16-bit platform cannot be read in a 32-bit platform. | |
| 58 | +<P> | |
| 59 | +In the command line, | |
| 60 | +you can mix | |
| 61 | +text files containing Lua source and | |
| 62 | +binary files containing precompiled chunks. | |
| 63 | +This is useful to combine several precompiled chunks, | |
| 64 | +even from different (but compatible) platforms, | |
| 65 | +into a single precompiled chunk. | |
| 66 | +<P> | |
| 52 | 67 | You can use |
| 53 | 68 | <B>"-"</B> |
| 54 | 69 | to indicate |
| 55 | 70 | <I>stdin</I> |
| 56 | 71 | as a source file. |
| 57 | 72 | <P> |
| 58 | −<B>luac</B> | |
| 59 | −can also load and list binary files with the | |
| 60 | −<B>-u</B> | |
| 61 | −option. | |
| 62 | −<P> | |
| 63 | −Binary files produced by differents runs of | |
| 64 | −<B>luac</B> | |
| 65 | −(even in different machines) | |
| 66 | −can be combined into one large file, | |
| 67 | −using | |
| 68 | −<B>cat</B>(1). | |
| 69 | −The result is still a valid binary file | |
| 70 | −and can be loaded with a single call to | |
| 71 | −<B>lua_dofile</B> | |
| 72 | −or | |
| 73 | −<B>dofile</B>. | |
| 74 | −<P> | |
| 75 | 73 | The internal format of the binary files produced by |
| 76 | 74 | <B>luac</B> |
| 77 | 75 | may change when a new version of Lua is released. |
| 78 | 76 | We try to maintain compatibility even for binary files, |
| 79 | −but sometimes it cannot be done. | |
| 77 | +but it is not always possible. | |
| 80 | 78 | So, |
| 81 | 79 | save the source files of all Lua programs that you precompile. |
| 82 | 80 | <P> |
| 83 | 81 | <H1>OPTIONS</H1> |
| 84 | 82 | Options must be separate. |
| 85 | 83 | <P> |
| 86 | −<B>-c</B> | |
| 87 | −compile (this is the default). | |
| 88 | −<P> | |
| 89 | −<B>-u</B> | |
| 90 | −undump, i.e., load and list the given binary files. | |
| 91 | −If no files are given, then luac undumps | |
| 92 | −<B>luac.out</B>. | |
| 93 | −Listing a binary file is useful to learn Lua's virtual machine. | |
| 94 | −Listing is also useful to test the integrity of binary files: | |
| 95 | −corrupted files will probably generate errors when undumped. | |
| 96 | −To test without listing, use | |
| 97 | −<B>-q</B>. | |
| 98 | −For a thourough integrity test, | |
| 99 | −use | |
| 100 | −<B>-t</B>. | |
| 101 | −<P> | |
| 102 | −<B>-d</B> | |
| 103 | −turn debugging on. | |
| 104 | −Individual chunks may | |
| 105 | −still control the generation of debug information with | |
| 106 | −$debug and $nodebug. | |
| 107 | −If debugging is on, then listings show the names of the local variables. | |
| 108 | −<P> | |
| 109 | −<B>-D "</B><I>name"</I> | |
| 110 | −predefine symbol | |
| 111 | −<I>name</I> | |
| 112 | −for conditional compilation. | |
| 113 | −By default, | |
| 114 | −<B>luac</B> | |
| 115 | −does | |
| 116 | −<I>not</I> | |
| 117 | −predefine any symbols, | |
| 118 | −not even the built-in functions. | |
| 119 | −<P> | |
| 120 | 84 | <B>-l</B> |
| 121 | 85 | produce a listing of the compiled bytecode for Lua's virtual machine. |
| 122 | −This is the default when undumping. | |
| 123 | −<P> | |
| 124 | −<B>-n</B> | |
| 125 | −Save numbers in native format. | |
| 126 | −By default, | |
| 127 | −numbers are saved in text form, | |
| 128 | −for maximum portability. | |
| 129 | −Binary files with numbers in native format are slightly faster to load, | |
| 130 | −but are not completely portable. | |
| 86 | +Listing bytecodes is useful to learn about Lua's virtual machine. | |
| 87 | +If no files are given, then | |
| 88 | +<B>luac</B> | |
| 89 | +loads | |
| 90 | +<B>luac.out</B> | |
| 91 | +and lists its contents. | |
| 131 | 92 | <P> |
| 132 | −<B>-o "</B><I>filename"</I> | |
| 93 | +<B>-o "</B><I>file"</I> | |
| 133 | 94 | output to |
| 134 | −<I>filename</I>, | |
| 95 | +<I>file</I>, | |
| 135 | 96 | instead of the default |
| 136 | 97 | <B>luac.out</B>. |
| 137 | −The output file cannot be a source file. | |
| 138 | −<P> | |
| 139 | −<B>-O</B> | |
| 140 | −optimize. | |
| 141 | −Debug information is removed | |
| 142 | −and | |
| 143 | −duplicate constants are coalesced. | |
| 98 | +The output file can be a source file because | |
| 99 | +all files are loaded before the output file is written. | |
| 144 | 100 | <P> |
| 145 | 101 | <B>-p</B> |
| 146 | −parse sources files but do not generate any output file. | |
| 147 | −Used mainly for syntax checking. | |
| 102 | +load files but do not generate any output file. | |
| 103 | +Used mainly for syntax checking or testing precompiled chunks: | |
| 104 | +corrupted files will probably generate errors when loaded. | |
| 105 | +For a thourough integrity test, | |
| 106 | +use | |
| 107 | +<B>-t</B>. | |
| 148 | 108 | <P> |
| 149 | −<B>-q</B> | |
| 150 | −quiet; produces no listing. | |
| 151 | −This is the default when compiling. | |
| 109 | +<B>-s</B> | |
| 110 | +strip debug information before writing the output file. | |
| 111 | +This saves some space in very large chunks, | |
| 112 | +but if errors occur when running these chunks, | |
| 113 | +then the error messages might not contain the full information they usually do. | |
| 152 | 114 | <P> |
| 153 | 115 | <B>-t</B> |
| 154 | −perform a thourough integrity test when undumping. | |
| 116 | +perform a thourough integrity test of precompiled chunks. | |
| 155 | 117 | Code that passes this test is completely safe, |
| 156 | 118 | in the sense that it will not break the interpreter. |
| 157 | 119 | However, |
| 158 | 120 | there is no guarantee that such code does anything sensible. |
| 159 | 121 | (None can be given, because the halting problem is unsolvable.) |
| 160 | −<P> | |
| 161 | −<B>-U "</B><I>name"</I> | |
| 162 | −undefine symbol | |
| 163 | −<I>name</I> | |
| 164 | −for conditional compilation. | |
| 122 | +If no files are given, then | |
| 123 | +<B>luac</B> | |
| 124 | +loads | |
| 125 | +<B>luac.out</B> | |
| 126 | +and tests its contents. | |
| 165 | 127 | <P> |
| 166 | 128 | <B>-v</B> |
| 167 | 129 | print version information. |
| 168 | −<P> | |
| 169 | −<B>-V</B> | |
| 170 | −verbose; | |
| 171 | −print the names of the source files as they are processed. | |
| 172 | 130 | <H1>FILES</H1> |
| 173 | 131 | <P> |
| 174 | 132 | <B>luac.out</B> |
| @@ -176,19 +134,14 @@ default output file · 1 unmodified line | ||
| 176 | 134 | <H1>SEE ALSO</H1> |
| 177 | 135 | <B>lua</B>(1) |
| 178 | 136 | <BR> |
| 179 | −<I>"Reference Manual of the Programming Language Lua"</I> | |
| 180 | −<BR> | |
| 181 | 137 | <A HREF="http://www.tecgraf.puc-rio.br/lua/">http://www.tecgraf.puc-rio.br/lua/</A> |
| 182 | −<BR> | |
| 183 | −"Lua: an extensible extension language", | |
| 184 | −<I>Software: Practice & Experience</I> | |
| 185 | −<B>26</B> | |
| 186 | −#6 (1996) 635-652. | |
| 187 | 138 | <H1>DIAGNOSTICS</H1> |
| 188 | 139 | Error messages should be self explanatory. |
| 189 | 140 | <H1>AUTHORS</H1> |
| 190 | 141 | L. H. de Figueiredo, |
| 191 | 142 | R. Ierusalimschy and |
| 192 | 143 | W. Celes |
| 193 | −<I>(<A HREF="mailto:lua@tecgraf.puc-rio.br">lua@tecgraf.puc-rio.br</A>)</I> | |
| 144 | +(<A HREF="mailto:lua@tecgraf.puc-rio.br">lua@tecgraf.puc-rio.br</A>) | |
| 194 | 145 | <!-- EOF --> |
| 146 | +</BODY> | |
| 147 | +</HTML> | |
| @@ -1,188 +0,0 @@ | ||
| 1 | −.\" luac.man,v 1.17 1999/07/07 16:02:07 lhf Exp | |
| 2 | −.TH LUAC 1 "1999/07/07 16:02:07" | |
| 3 | −.SH NAME | |
| 4 | −luac \- Lua compiler | |
| 5 | −.SH SYNOPSIS | |
| 6 | −.B luac | |
| 7 | −[ | |
| 8 | −.I options | |
| 9 | −] [ | |
| 10 | −.I filenames | |
| 11 | −] | |
| 12 | −.SH DESCRIPTION | |
| 13 | −.B luac | |
| 14 | −is the Lua compiler. | |
| 15 | −It translates programs written in the Lua programming language | |
| 16 | −into binary files that can be loaded and executed with | |
| 17 | −.B lua_dofile | |
| 18 | −in C or with | |
| 19 | −.B dofile | |
| 20 | −in Lua. | |
| 21 | −.LP | |
| 22 | −The main advantages of pre-compiling chunks are: | |
| 23 | −faster loading, | |
| 24 | −protecting source code from user changes, | |
| 25 | −and | |
| 26 | −off-line syntax error detection. | |
| 27 | −The binary files created by | |
| 28 | −.B luac | |
| 29 | −are portable to all architectures. | |
| 30 | −.LP | |
| 31 | −Pre-compiling does not imply faster execution | |
| 32 | −because in Lua chunks are always compiled into bytecodes before being executed. | |
| 33 | −.B luac | |
| 34 | −simply allows those bytecodes to be saved in a file for later execution. | |
| 35 | −.LP | |
| 36 | −.B luac | |
| 37 | −produces a single output file containing the bytecodes | |
| 38 | −for all source files given. | |
| 39 | −By default, | |
| 40 | −the output file is named | |
| 41 | −.BR luac.out , | |
| 42 | −but you can change this with the | |
| 43 | −.B \-o | |
| 44 | −option. | |
| 45 | −.LP | |
| 46 | −You can use | |
| 47 | −.B "\-" | |
| 48 | −to indicate | |
| 49 | −.I stdin | |
| 50 | −as a source file. | |
| 51 | −.LP | |
| 52 | −.B luac | |
| 53 | −can also load and list binary files with the | |
| 54 | −.B \-u | |
| 55 | −option. | |
| 56 | −.LP | |
| 57 | −Binary files produced by differents runs of | |
| 58 | −.B luac | |
| 59 | −(even in different machines) | |
| 60 | −can be combined into one large file, | |
| 61 | −using | |
| 62 | −.BR cat (1). | |
| 63 | −The result is still a valid binary file | |
| 64 | −and can be loaded with a single call to | |
| 65 | −.B lua_dofile | |
| 66 | −or | |
| 67 | −.BR dofile . | |
| 68 | −.LP | |
| 69 | −The internal format of the binary files produced by | |
| 70 | −.B luac | |
| 71 | −may change when a new version of Lua is released. | |
| 72 | −We try to maintain compatibility even for binary files, | |
| 73 | −but sometimes it cannot be done. | |
| 74 | −So, | |
| 75 | −save the source files of all Lua programs that you precompile. | |
| 76 | −.LP | |
| 77 | −.SH OPTIONS | |
| 78 | −Options must be separate. | |
| 79 | −.TP | |
| 80 | −.B \-c | |
| 81 | −compile (this is the default). | |
| 82 | −.TP | |
| 83 | −.B \-u | |
| 84 | −undump, i.e., load and list the given binary files. | |
| 85 | −If no files are given, then luac undumps | |
| 86 | −.BR luac.out . | |
| 87 | −Listing a binary file is useful to learn Lua's virtual machine. | |
| 88 | −Listing is also useful to test the integrity of binary files: | |
| 89 | −corrupted files will probably generate errors when undumped. | |
| 90 | −To test without listing, use | |
| 91 | −.BR \-q . | |
| 92 | −For a thourough integrity test, | |
| 93 | −use | |
| 94 | −.BR \-t . | |
| 95 | −.TP | |
| 96 | −.B \-d | |
| 97 | −turn debugging on. | |
| 98 | −Individual chunks may | |
| 99 | −still control the generation of debug information with | |
| 100 | −$debug and $nodebug. | |
| 101 | −If debugging is on, then listings show the names of the local variables. | |
| 102 | −.TP | |
| 103 | −.BI \-D " name" | |
| 104 | −predefine symbol | |
| 105 | −.I name | |
| 106 | −for conditional compilation. | |
| 107 | −By default, | |
| 108 | −.B luac | |
| 109 | −does | |
| 110 | −.I not | |
| 111 | −predefine any symbols, | |
| 112 | −not even the built-in functions. | |
| 113 | −.TP | |
| 114 | −.B \-l | |
| 115 | −produce a listing of the compiled bytecode for Lua's virtual machine. | |
| 116 | −This is the default when undumping. | |
| 117 | −.TP | |
| 118 | −.B \-n | |
| 119 | −Save numbers in native format. | |
| 120 | −By default, | |
| 121 | −numbers are saved in text form, | |
| 122 | −for maximum portability. | |
| 123 | −Binary files with numbers in native format are slightly faster to load, | |
| 124 | −but are not completely portable. | |
| 125 | −.TP | |
| 126 | −.BI \-o " filename" | |
| 127 | −output to | |
| 128 | −.IR filename , | |
| 129 | −instead of the default | |
| 130 | −.BR luac.out . | |
| 131 | −The output file cannot be a source file. | |
| 132 | −.TP | |
| 133 | −.B \-O | |
| 134 | −optimize. | |
| 135 | −Debug information is removed | |
| 136 | −and | |
| 137 | −duplicate constants are coalesced. | |
| 138 | −.TP | |
| 139 | −.B \-p | |
| 140 | −parse sources files but do not generate any output file. | |
| 141 | −Used mainly for syntax checking. | |
| 142 | −.TP | |
| 143 | −.B \-q | |
| 144 | −quiet; produces no listing. | |
| 145 | −This is the default when compiling. | |
| 146 | −.TP | |
| 147 | −.B \-t | |
| 148 | −perform a thourough integrity test when undumping. | |
| 149 | −Code that passes this test is completely safe, | |
| 150 | −in the sense that it will not break the interpreter. | |
| 151 | −However, | |
| 152 | −there is no guarantee that such code does anything sensible. | |
| 153 | −(None can be given, because the halting problem is unsolvable.) | |
| 154 | −.TP | |
| 155 | −.BI \-U " name" | |
| 156 | −undefine symbol | |
| 157 | −.I name | |
| 158 | −for conditional compilation. | |
| 159 | −.TP | |
| 160 | −.B \-v | |
| 161 | −print version information. | |
| 162 | −.TP | |
| 163 | −.B \-V | |
| 164 | −verbose; | |
| 165 | −print the names of the source files as they are processed. | |
| 166 | −.SH FILES | |
| 167 | −.TP 15 | |
| 168 | −.B luac.out | |
| 169 | −default output file | |
| 170 | −.SH "SEE ALSO" | |
| 171 | −.BR lua (1) | |
| 172 | −.br | |
| 173 | −.I "Reference Manual of the Programming Language Lua" | |
| 174 | −.br | |
| 175 | −http://www.tecgraf.puc-rio.br/lua/ | |
| 176 | −.br | |
| 177 | −"Lua: an extensible extension language", | |
| 178 | −.I Software: Practice & Experience | |
| 179 | −.B 26 | |
| 180 | −#6 (1996) 635-652. | |
| 181 | −.SH DIAGNOSTICS | |
| 182 | −Error messages should be self explanatory. | |
| 183 | −.SH AUTHORS | |
| 184 | −L. H. de Figueiredo, | |
| 185 | −R. Ierusalimschy and | |
| 186 | −W. Celes | |
| 187 | −.I (lua@tecgraf.puc-rio.br) | |
| 188 | −.\" EOF | |
| @@ -1,10 +1,19 @@ | ||
| 1 | +<HTML> | |
| 1 | 2 | <HEAD> |
| 2 | −<TITLE>Lua 3.2 Reference Manual</TITLE> | |
| 3 | +<TITLE>Lua: reference manual 4.0</TITLE> | |
| 3 | 4 | </HEAD> |
| 5 | + | |
| 4 | 6 | <BODY BGCOLOR="#FFFFFF"> |
| 5 | −<h1>Lua 3.2 Reference Manual</h1> | |
| 6 | 7 | |
| 7 | −<!-- $Id: manual.tex,v 1.33 1999/05/27 20:21:03 roberto Exp $ --> | |
| 8 | +<HR> | |
| 9 | +<H1> | |
| 10 | +<IMG SRC="logo.gif" ALT="Lua" ALIGN="bottom"> | |
| 11 | +Reference Manual of the Programming Language | |
| 12 | +<A HREF="http://www.tecgraf.puc-rio.br/lua/">Lua</A> | |
| 13 | +4.0 | |
| 14 | +</H1> | |
| 15 | + | |
| 16 | +<!-- $Id: manual.tex,v 1.45 2000/10/31 18:20:01 roberto Exp roberto $ --> | |
| 8 | 17 | <P> |
| 9 | 18 | <P> |
| 10 | 19 | <!-- ====================================================================== --> |
| @@ -15,7 +24,7 @@ · 4 unmodified lines | ||
| 15 | 24 | Lua is an extension programming language designed to support |
| 16 | 25 | general procedural programming with data description |
| 17 | 26 | facilities. |
| 18 | −Lua is intended to be used as a light-weight, but powerful, | |
| 27 | +Lua is intended to be used as a powerful, light-weight | |
| 19 | 28 | configuration language for any program that needs one. |
| 20 | 29 | <P> |
| 21 | 30 | Lua is implemented as a library, written in C. |
| @@ -24,21 +33,40 @@ it only works <EM>embedded</EM> in a host client, · 2 unmodified lines | ||
| 24 | 33 | called the <EM>embedding</EM> program. |
| 25 | 34 | This host program can invoke functions to execute a piece of |
| 26 | 35 | code in Lua, can write and read Lua variables, |
| 27 | −and can register C functions to be called by Lua code. | |
| 28 | −Through the use of C functions, Lua can be augmented to cope with | |
| 36 | +and can register C functions to be called by Lua code. | |
| 37 | +Through the use of C functions, Lua can be augmented to cope with | |
| 29 | 38 | a wide range of different domains, |
| 30 | 39 | thus creating customized programming languages sharing a syntactical framework. |
| 31 | 40 | <P> |
| 32 | 41 | Lua is free-distribution software, |
| 33 | −and provided as usual with no guarantees, | |
| 34 | −as stated in the copyright notice. | |
| 42 | +and is provided as usual with no guarantees, | |
| 43 | +as stated in its copyright notice. | |
| 35 | 44 | The implementation described in this manual is available |
| 36 | 45 | at the following URL's: |
| 37 | 46 | <PRE> |
| 38 | − <A HREF="http://www.tecgraf.puc-rio.br/lua/">http://www.tecgraf.puc-rio.br/lua/</A> | |
| 39 | − <A HREF="ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz">ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz</A> | |
| 47 | + <A HREF="http://www.tecgraf.puc-rio.br/lua/">http://www.tecgraf.puc-rio.br/lua/</A> | |
| 48 | + <A HREF="ftp://ftp.tecgraf.puc-rio.br/pub/lua/">ftp://ftp.tecgraf.puc-rio.br/pub/lua/</A> | |
| 40 | 49 | </PRE> |
| 41 | 50 | <P> |
| 51 | +Like any other reference manual, | |
| 52 | +this document is dry in places. | |
| 53 | +For a discussion of the decisions behind the design of Lua, | |
| 54 | +see the papers below, | |
| 55 | +which are available at the web site above. | |
| 56 | +<UL> | |
| 57 | +<LI> | |
| 58 | +R. Ierusalimschy, L. H. de Figueiredo, and W. Celes. | |
| 59 | +Lua-an extensible extension language. | |
| 60 | +<EM>Software: Practice & Experience</EM> <B>26</B> #6 (1996) 635--652. | |
| 61 | +<LI> | |
| 62 | +L. H. de Figueiredo, R. Ierusalimschy, and W. Celes. | |
| 63 | +The design and implementation of a language for extending applications. | |
| 64 | +<EM>Proceedings of XXI Brazilian Seminar on Software and Hardware</EM> (1994) 273--283. | |
| 65 | +<LI> | |
| 66 | +L. H. de Figueiredo, R. Ierusalimschy, and W. Celes. | |
| 67 | +Lua: an extensible embedded language. | |
| 68 | +<EM>Dr. Dobb's Journal</EM> <B>21</B> #12 (Dec 1996) 26--33. | |
| 69 | +</UL> | |
| 42 | 70 | <P> |
| 43 | 71 | <!-- ====================================================================== --> |
| 44 | 72 | <HR> |
| @@ -46,43 +74,50 @@ at the following URL's: · 1 unmodified line | ||
| 46 | 74 | <H1>2 - Environment and Chunks</H1> |
| 47 | 75 | <P> |
| 48 | 76 | All statements in Lua are executed in a <A NAME="global environment"><EM>global environment</EM></A>. |
| 49 | −This environment, which keeps all global variables, | |
| 50 | −is initialized with a call from the embedding program to | |
| 77 | +This environment is initialized with a call from the embedding program to | |
| 51 | 78 | <CODE>lua_open</CODE> and |
| 52 | 79 | persists until a call to <CODE>lua_close</CODE>, |
| 53 | 80 | or the end of the embedding program. |
| 54 | −Optionally, a user can create multiple independent global | |
| 55 | −environments (see Section <A HREF="#mangstate">5.1</A>). | |
| 81 | +If necessary, | |
| 82 | +the host programmer can create multiple independent global | |
| 83 | +environments, and freely switch between them (see Section <A HREF="#mangstate">5.1</A>). | |
| 56 | 84 | <P> |
| 57 | 85 | The global environment can be manipulated by Lua code or |
| 58 | 86 | by the embedding program, |
| 59 | 87 | which can read and write global variables |
| 60 | 88 | using API functions from the library that implements Lua. |
| 61 | 89 | <P> |
| 62 | −<A NAME="Global variables">Global variables</A> do not need declaration. | |
| 90 | +<A NAME="Global variables">Global variables</A> in Lua do not need to be declared. | |
| 63 | 91 | Any variable is assumed to be global unless explicitly declared local |
| 64 | −(see Section <A HREF="#localvar">4.5.5</A>). | |
| 65 | −Before the first assignment, the value of a global variable is <B>nil</B>; | |
| 66 | −this default can be changed (see Section <A HREF="#tag-method">4.8</A>). | |
| 92 | +(see Section <A HREF="#localvar">4.4.6</A>). | |
| 93 | +Before the first assignment, the value of a global variable is <B>nil</B> | |
| 94 | +(this default can be changed; see Section <A HREF="#tag-method">4.8</A>). | |
| 95 | +A table is used to keep all global names and values | |
| 96 | +(tables are explained in Section <A HREF="#TypesSec">3</A>). | |
| 67 | 97 | <P> |
| 68 | 98 | The unit of execution of Lua is called a <A NAME="chunk"><EM>chunk</EM></A>. |
| 69 | −A chunk is simply a sequence of statements: | |
| 70 | −<PRE> | |
| 71 | −chunk ::= {stat} [ret] | |
| 72 | −</PRE> | |
| 73 | −Statements are described in Section <A HREF="#stats">4.5</A>. | |
| 74 | −(As usual, {<EM>a</EM>} means 0 or more <EM>a</EM>'s, | |
| 75 | −[<EM>a</EM>] means an optional <EM>a</EM> and ('<EM>a</EM>)+ means | |
| 76 | −one or more <EM>a</EM>'s.) | |
| 77 | −<P> | |
| 78 | −A chunk may be in a file or in a string inside the host program. | |
| 79 | −A chunk may optionally end with a <CODE>return</CODE> statement (see Section <A HREF="#return">4.5.3</A>). | |
| 80 | −When a chunk is executed, first all its code is pre-compiled, | |
| 81 | −then the statements are executed in sequential order. | |
| 99 | +A chunk is simply a sequence of statements, | |
| 100 | +which are executed sequentially. | |
| 101 | +Each statement can be optionally followed by a semicolon: | |
| 102 | +<PRE> | |
| 103 | + chunk ::= {stat [`<B>;</B>']} | |
| 104 | +</PRE> | |
| 105 | +Statements are described in Section <A HREF="#stats">4.4</A>. | |
| 106 | +(The notation above is the usual extended BNF, | |
| 107 | +in which | |
| 108 | +{<EM>a</EM>} means 0 or more <EM>a</EM>'s, | |
| 109 | +[<EM>a</EM>] means an optional <EM>a</EM>, and | |
| 110 | +(<EM>a</EM>)+ means one or more <EM>a</EM>'s. | |
| 111 | +The complete syntax of Lua is given in <A HREF="BNF">BNF</A>). | |
| 112 | +<P> | |
| 113 | +A chunk may be stored in a file or in a string inside the host program. | |
| 114 | +When a chunk is executed, first it is pre-compiled into bytecodes for | |
| 115 | +a virtual machine, and then the statements are executed in sequential order, | |
| 116 | +by simulating the virtual machine. | |
| 82 | 117 | All modifications a chunk effects on the global environment persist |
| 83 | −after the chunk end. | |
| 118 | +after the chunk ends. | |
| 84 | 119 | <P> |
| 85 | −Chunks may also be pre-compiled into binary form; | |
| 120 | +Chunks may also be pre-compiled into binary form and stored in files; | |
| 86 | 121 | see program <A NAME="luac"><TT><A HREF="luac.html">luac</A></TT></A> for details. |
| 87 | 122 | Text files with chunks and their binary pre-compiled forms |
| 88 | 123 | are interchangeable. |
| @@ -95,11 +130,12 @@ Lua automatically detects the file type and acts accordingly. · 6 unmodified lines | ||
| 95 | 130 | <A NAME="3."></A> |
| 96 | 131 | <H1>3 - Types and Tags</H1> |
| 97 | 132 | <P> |
| 98 | −Lua is a dynamically typed language. | |
| 99 | −Variables do not have types; only values do. | |
| 133 | +Lua is a <EM>dynamically typed language</EM>. | |
| 134 | +This means that | |
| 135 | +variables do not have types; only values do. | |
| 100 | 136 | Therefore, there are no type definitions in the language. |
| 101 | 137 | All values carry their own type. |
| 102 | −Besides a type, all values also have a <A NAME="tag">tag</A>. | |
| 138 | +Besides a type, all values also have a <A NAME="tag"><EM>tag</EM></A>. | |
| 103 | 139 | <P> |
| 104 | 140 | There are six <A NAME="basic types">basic types</A> in Lua: <A NAME="nil"><EM>nil</EM></A>, <A NAME="number"><EM>number</EM></A>, |
| 105 | 141 | <A NAME="string"><EM>string</EM></A>, <A NAME="function"><EM>function</EM></A>, <A NAME="userdata"><EM>userdata</EM></A>, and <A NAME="table"><EM>table</EM></A>. |
| @@ -107,26 +143,30 @@ There are six <A NAME="basic types">basic types</A> in Lua: <A NAME="nil"><EM>ni · 1 unmodified line | ||
| 107 | 143 | whose main property is to be different from any other value. |
| 108 | 144 | <EM>Number</EM> represents real (double-precision floating-point) numbers, |
| 109 | 145 | while <EM>string</EM> has the usual meaning. |
| 110 | −Lua is <A NAME="eight-bit clean">eight-bit clean</A>, | |
| 146 | +<A NAME="eight-bit clean"></A> | |
| 147 | +Lua is 8-bit clean, | |
| 111 | 148 | and so strings may contain any 8-bit character, |
| 112 | −<EM>including</EM> embedded zeros (<CODE>'\0'</CODE>). | |
| 113 | −The function <CODE>type</CODE> returns a string describing the type | |
| 149 | +including embedded zeros (<CODE>'\0'</CODE>) (see Section <A HREF="#lexical">4.1</A>). | |
| 150 | +The <CODE>type</CODE> function returns a string describing the type | |
| 114 | 151 | of a given value (see Section <A HREF="#pdf-type">6.1</A>). |
| 115 | 152 | <P> |
| 116 | −Functions are considered first-class values in Lua. | |
| 153 | +Functions are considered <EM>first-class values</EM> in Lua. | |
| 117 | 154 | This means that functions can be stored in variables, |
| 118 | 155 | passed as arguments to other functions, and returned as results. |
| 119 | 156 | Lua can call (and manipulate) functions written in Lua and |
| 120 | 157 | functions written in C. |
| 121 | −They can be distinguished by their tags: | |
| 158 | +The two kinds of functions can be distinguished by their tags: | |
| 122 | 159 | all Lua functions have the same tag, |
| 123 | −and all C functions have the same tag, | |
| 160 | +and all C functions have the same tag, | |
| 124 | 161 | which is different from the tag of Lua functions. |
| 162 | +The <CODE>tag</CODE> function returns the tag | |
| 163 | +of a given value (see Section <A HREF="#pdf-tag">6.1</A>). | |
| 125 | 164 | <P> |
| 126 | 165 | The type <EM>userdata</EM> is provided to allow |
| 127 | −arbitrary <A NAME="C pointers">C pointers</A> to be stored in Lua variables. | |
| 128 | −It corresponds to a <CODE>void*</CODE> and has no pre-defined operations in Lua, | |
| 129 | −besides assignment and equality test. | |
| 166 | +arbitrary <A NAME="C pointers">C pointers</A> to be stored in Lua variables. | |
| 167 | +This type corresponds to a <CODE>void*</CODE> | |
| 168 | +and has no pre-defined operations in Lua, | |
| 169 | +except assignment and equality test. | |
| 130 | 170 | However, by using <EM>tag methods</EM>, |
| 131 | 171 | the programmer can define operations for <EM>userdata</EM> values |
| 132 | 172 | (see Section <A HREF="#tag-method">4.8</A>). |
| @@ -135,100 +175,109 @@ The type <EM>table</EM> implements <A NAME="associative arrays">associative arra · 2 unmodified lines | ||
| 135 | 175 | that is, <A NAME="arrays">arrays</A> that can be indexed not only with numbers, |
| 136 | 176 | but with any value (except <B>nil</B>). |
| 137 | 177 | Therefore, this type may be used not only to represent ordinary arrays, |
| 138 | −but also symbol tables, sets, records, etc. | |
| 178 | +but also symbol tables, sets, records, graphs, trees, etc. | |
| 139 | 179 | Tables are the main data structuring mechanism in Lua. |
| 140 | 180 | To represent <A NAME="records">records</A>, Lua uses the field name as an index. |
| 141 | 181 | The language supports this representation by |
| 142 | 182 | providing <CODE>a.name</CODE> as syntactic sugar for <CODE>a["name"]</CODE>. |
| 143 | −Tables may also carry methods. | |
| 183 | +Tables may also carry <EM>methods</EM>: | |
| 144 | 184 | Because functions are first class values, |
| 145 | 185 | table fields may contain functions. |
| 146 | 186 | The form <CODE>t:f(x)</CODE> is syntactic sugar for <CODE>t.f(t,x)</CODE>, |
| 147 | 187 | which calls the method <CODE>f</CODE> from the table <CODE>t</CODE> passing |
| 148 | −itself as the first parameter (see Section <A HREF="#func-def">4.6.9</A>). | |
| 188 | +the table itself as the first parameter (see Section <A HREF="#func-def">4.5.9</A>). | |
| 149 | 189 | <P> |
| 150 | 190 | Note that tables are <EM>objects</EM>, and not values. |
| 151 | −Variables cannot contain tables, only <EM>references</EM> to them. | |
| 191 | +Variables do not contain tables, only <EM>references</EM> to them. | |
| 152 | 192 | Assignment, parameter passing, and returns always manipulate references |
| 153 | 193 | to tables, and do not imply any kind of copy. |
| 154 | 194 | Moreover, tables must be explicitly created before used |
| 155 | −(see Section <A HREF="#tableconstructor">4.6.7</A>). | |
| 195 | +(see Section <A HREF="#tableconstructor">4.5.7</A>). | |
| 156 | 196 | <P> |
| 157 | −Tags are mainly used to select tag methods when | |
| 197 | +Each of the types <EM>nil</EM>, <EM>number</EM>, and <EM>string</EM> has a different tag. | |
| 198 | +All values of each of these types have the same pre-defined tag. | |
| 199 | +As explained above, | |
| 200 | +values of type <EM>function</EM> can have two different tags, | |
| 201 | +depending on whether they are Lua functions or C functions. | |
| 202 | +Finally, | |
| 203 | +values of type <EM>userdata</EM> and <EM>table</EM> can have variable tags, | |
| 204 | +assigned by the programmer (see Section <A HREF="#tag-method">4.8</A>). | |
| 205 | +The <CODE>tag</CODE> function returns the tag of a given value. | |
| 206 | +User tags are created with the function <CODE>newtag</CODE>. | |
| 207 | +The <CODE>settag</CODE> function | |
| 208 | +is used to change the tag of a table (see Section <A HREF="#pdf-newtag">6.1</A>). | |
| 209 | +The tag of userdata values can only be set from C (see Section <A HREF="#C-tags">5.7</A>). | |
| 210 | +Tags are mainly used to select <EM>tag methods</EM> when | |
| 158 | 211 | some events occur. |
| 159 | 212 | Tag methods are the main mechanism for extending the |
| 160 | 213 | semantics of Lua (see Section <A HREF="#tag-method">4.8</A>). |
| 161 | −Each of the types <EM>nil</EM>, <EM>number</EM> and <EM>string</EM> has a different tag. | |
| 162 | −All values of each of these types have this same pre-defined tag. | |
| 163 | −Values of type <EM>function</EM> can have two different tags, | |
| 164 | −depending on whether they are Lua functions or C functions. | |
| 165 | −Finally, | |
| 166 | −values of type <EM>userdata</EM> and <EM>table</EM> can have | |
| 167 | −as many different tags as needed (see Section <A HREF="#tag-method">4.8</A>). | |
| 168 | −Tags are created with the function <CODE>newtag</CODE>, | |
| 169 | −and the function <CODE>tag</CODE> returns the tag of a given value. | |
| 170 | −To change the tag of a given table, | |
| 171 | −there is the function <CODE>settag</CODE> (see Section <A HREF="#pdf-newtag">6.1</A>). | |
| 172 | −<P> | |
| 173 | 214 | <P> |
| 174 | 215 | <!-- ====================================================================== --> |
| 175 | 216 | <HR> |
| 176 | 217 | <A NAME="4."></A> |
| 177 | 218 | <H1>4 - The Language</H1> |
| 178 | 219 | <P> |
| 179 | −This section describes the lexis, the syntax and the semantics of Lua. | |
| 220 | +This section describes the lexis, the syntax, and the semantics of Lua. | |
| 180 | 221 | <P> |
| 181 | 222 | <P> |
| 182 | 223 | <A NAME="lexical"></A> |
| 183 | 224 | <A NAME="4.1"></A> |
| 184 | 225 | <H2>4.1 - Lexical Conventions</H2> |
| 185 | 226 | <P> |
| 186 | −<A NAME="Identifiers">Identifiers</A> in Lua can be any string of letters, | |
| 227 | +<A NAME="Identifiers"><EM>Identifiers</EM></A> in Lua can be any string of letters, | |
| 187 | 228 | digits, and underscores, |
| 188 | 229 | not beginning with a digit. |
| 189 | −The definition of letter depends on the current locale: | |
| 230 | +This coincides with the definition of identifiers in most languages, | |
| 231 | +except that | |
| 232 | +the definition of letter depends on the current locale: | |
| 190 | 233 | Any character considered alphabetic by the current locale |
| 191 | 234 | can be used in an identifier. |
| 192 | −The following words are reserved, and cannot be used as identifiers: | |
| 235 | +The following words are <EM>reserved</EM>, and cannot be used as identifiers: | |
| 193 | 236 | <A NAME="reserved words"></A> |
| 194 | 237 | <PRE> |
| 195 | − and do else elseif | |
| 196 | − end function if local | |
| 197 | − nil not or repeat | |
| 198 | − return then until while | |
| 238 | + and break do else elseif | |
| 239 | + end for function if in | |
| 240 | + local nil not or repeat | |
| 241 | + return then until while | |
| 199 | 242 | </PRE> |
| 243 | +<P> | |
| 200 | 244 | Lua is a case-sensitive language: |
| 201 | −<TT>and</TT> is a reserved word, but <TT>And</TT> and <TT>\'and</TT> | |
| 202 | −(if the locale permits) are two other different identifiers. | |
| 245 | +<TT>and</TT> is a reserved word, but <TT>And</TT> and <TT>�nd</TT> | |
| 246 | +(if the locale permits) are two different, valid identifiers. | |
| 203 | 247 | As a convention, identifiers starting with underscore followed by |
| 204 | −uppercase letters are reserved for internal variables. | |
| 248 | +uppercase letters (such as <CODE>_INPUT</CODE>) | |
| 249 | +are reserved for internal variables. | |
| 205 | 250 | <P> |
| 206 | 251 | The following strings denote other <A NAME="tokens">tokens</A>: |
| 207 | 252 | <PRE> |
| 208 | − ~= <= >= < > == = + - * / | |
| 209 | − ( ) { } [ ] ; , . .. ... | |
| 253 | + ~= <= >= < > == = + - * / | |
| 254 | + ( ) { } [ ] ; , . .. ... | |
| 210 | 255 | </PRE> |
| 211 | 256 | <P> |
| 212 | −<A NAME="Literal strings">Literal strings</A> can be delimited by matching single or double quotes, | |
| 257 | +<A NAME="Literal strings"><EM>Literal strings</EM></A> | |
| 258 | +can be delimited by matching single or double quotes, | |
| 213 | 259 | and can contain the C-like escape sequences |
| 214 | −<CODE>'\a'</CODE> (bell), | |
| 215 | −<CODE>'\b'</CODE> (backspace), | |
| 216 | −<CODE>'\f'</CODE> (form feed), | |
| 217 | −<CODE>'\n'</CODE> (new line), | |
| 218 | −<CODE>'\r'</CODE> (carriage return), | |
| 219 | −<CODE>'\t'</CODE> (horizontal tab), | |
| 220 | −<CODE>'\v'</CODE> (vertical tab), | |
| 221 | −<CODE>'\\'</CODE>, (backslash), | |
| 222 | −<CODE>'\"'</CODE>, (double quote), | |
| 223 | −and <CODE>'\''</CODE> (single quote). | |
| 260 | +`<CODE>\a</CODE>' (bell), | |
| 261 | +`<CODE>\b</CODE>' (backspace), | |
| 262 | +`<CODE>\f</CODE>' (form feed), | |
| 263 | +`<CODE>\n</CODE>' (newline), | |
| 264 | +`<CODE>\r</CODE>' (carriage return), | |
| 265 | +`<CODE>\t</CODE>' (horizontal tab), | |
| 266 | +`<CODE>\v</CODE>' (vertical tab), | |
| 267 | +`<CODE>\\</CODE>' (backslash), | |
| 268 | +`<CODE>\"</CODE>' (double quote), | |
| 269 | +`<CODE>\'</CODE>' (single quote), | |
| 270 | +and `<CODE>\</CODE><EM>newline</EM>' (that is, a backslash followed by a real newline, | |
| 271 | +which results in a newline in the string). | |
| 224 | 272 | A character in a string may also be specified by its numerical value, |
| 225 | −through the escape sequence <CODE>'\ddd'</CODE>, | |
| 226 | −where <CODE>ddd</CODE> is a sequence of up to three <EM>decimal</EM> digits. | |
| 227 | −Strings in Lua may contain any 8-bit value, including embedded 0. | |
| 273 | +through the escape sequence `<CODE>\</CODE><EM>ddd</EM>', | |
| 274 | +where <EM>ddd</EM> is a sequence of up to three <EM>decimal</EM> digits. | |
| 275 | +Strings in Lua may contain any 8-bit value, including embedded zeros, | |
| 276 | +which can be specified as `<CODE>\000</CODE>'. | |
| 228 | 277 | <P> |
| 229 | −Literal strings can also be delimited by matching <CODE>[[ ... ]]</CODE>. | |
| 278 | +Literal strings can also be delimited by matching <CODE>[[</CODE> ... <CODE>]]</CODE>. | |
| 230 | 279 | Literals in this bracketed form may run for several lines, |
| 231 | −may contain nested <CODE>[[ ... ]]</CODE> pairs, | |
| 280 | +may contain nested <CODE>[[</CODE> ... <CODE>]]</CODE> pairs, | |
| 232 | 281 | and do not interpret escape sequences. |
| 233 | 282 | This form is specially convenient for |
| 234 | 283 | writing strings that contain program pieces or |
| @@ -236,268 +285,363 @@ other quoted strings. · 1 unmodified line | ||
| 236 | 285 | As an example, in a system using ASCII, |
| 237 | 286 | the following three literals are equivalent: |
| 238 | 287 | <PRE> |
| 239 | −1) "alo\n123\"" | |
| 240 | −2) '\97lo\10\04923"' | |
| 241 | −3) [[alo | |
| 242 | − 123"]] | |
| 288 | + 1) "alo\n123\"" | |
| 289 | + 2) '\97lo\10\04923"' | |
| 290 | + 3) [[alo | |
| 291 | + 123"]] | |
| 243 | 292 | </PRE> |
| 244 | 293 | <P> |
| 245 | −<P> | |
| 246 | −<A NAME="Comments">Comments</A> start anywhere outside a string with a | |
| 294 | +<A NAME="Comments"><EM>Comments</EM></A> start anywhere outside a string with a | |
| 247 | 295 | double hyphen (<CODE>--</CODE>) and run until the end of the line. |
| 248 | 296 | Moreover, |
| 249 | 297 | the first line of a chunk is skipped if it starts with <CODE>#</CODE>. |
| 250 | 298 | This facility allows the use of Lua as a script interpreter |
| 251 | 299 | in Unix systems (see Section <A HREF="#lua-sa">8</A>). |
| 252 | 300 | <P> |
| 253 | −<A NAME="Numerical constants">Numerical constants</A> may be written with an optional decimal part, | |
| 301 | +<A NAME="Numerical constants"><EM>Numerical constants</EM></A> may be written with an optional decimal part | |
| 254 | 302 | and an optional decimal exponent. |
| 255 | 303 | Examples of valid numerical constants are |
| 256 | 304 | <PRE> |
| 257 | 305 | 3 3.0 3.1416 314.16e-2 0.31416E1 |
| 258 | 306 | </PRE> |
| 259 | 307 | <P> |
| 260 | −<A NAME="pre-processor"></A> | |
| 261 | −<A NAME="4.2"></A> | |
| 262 | −<H2>4.2 - The Pre-processor</H2> | |
| 263 | −<P> | |
| 264 | −All lines that start with a <CODE>$</CODE> sign are handled by a pre-processor. | |
| 265 | −The <CODE>$</CODE> sign must be immediately | |
| 266 | −followed by one of the following directives: | |
| 267 | −<DL> | |
| 268 | −<DT><B><TT>debug</TT></B><DD> - turn on debugging facilities (see Section <A HREF="#pragma">4.9</A>). | |
| 269 | −<DT><B><TT>nodebug</TT></B><DD> - turn off debugging facilities (see Section <A HREF="#pragma">4.9</A>). | |
| 270 | −<DT><B><TT>if <EM>cond</TT></EM></B><DD> - starts a conditional part. | |
| 271 | −If <EM>cond</EM> is false, then this part is skipped by the lexical analyzer. | |
| 272 | −<DT><B><TT>ifnot <EM>cond</TT></EM></B><DD> - starts a conditional part. | |
| 273 | −If <EM>cond</EM> is true, then this part is skipped by the lexical analyzer. | |
| 274 | −<DT><B><TT>end</TT></B><DD> - ends a conditional part. | |
| 275 | −<DT><B><TT>else</TT></B><DD> - starts an ``else'' conditional part, | |
| 276 | −flipping the ``skip'' status. | |
| 277 | −<DT><B><TT>endinput</TT></B><DD> - ends the lexical parse of the file. | |
| 278 | −</DL> | |
| 279 | −<P> | |
| 280 | −Directives may be freely nested. | |
| 281 | −Particularly, a <CODE>$endinput</CODE> may occur inside a <CODE>$if</CODE>; | |
| 282 | −in that case, even the matching <CODE>$end</CODE> is not parsed. | |
| 283 | −<P> | |
| 284 | −A <EM>cond</EM> part may be | |
| 285 | −<DL> | |
| 286 | −<DT><B><TT>nil</TT></B><DD> - always false. | |
| 287 | −<DT><B><TT>1</TT></B><DD> - always true. | |
| 288 | −<DT><B><EM>name</EM></B><DD> - true if the value of the | |
| 289 | −global variable <EM>name</EM> is different from <B>nil</B>. | |
| 290 | −Note that <EM>name</EM> is evaluated <EM>before</EM> the chunk starts its execution. | |
| 291 | −Therefore, actions in a chunk do not affect its own conditional directives. | |
| 292 | −</DL> | |
| 293 | −<P> | |
| 294 | 308 | <A NAME="coercion"></A> |
| 295 | −<A NAME="4.3"></A> | |
| 296 | −<H2>4.3 - Coercion</H2> | |
| 309 | +<A NAME="4.2"></A> | |
| 310 | +<H2>4.2 - Coercion</H2> | |
| 297 | 311 | <P> |
| 298 | 312 | Lua provides some automatic conversions between values at run time. |
| 299 | 313 | Any arithmetic operation applied to a string tries to convert |
| 300 | 314 | that string to a number, following the usual rules. |
| 301 | 315 | Conversely, whenever a number is used when a string is expected, |
| 302 | 316 | that number is converted to a string, in a reasonable format. |
| 303 | −For complete control on how numbers are converted to strings, | |
| 317 | +The format is chosen so that | |
| 318 | +a conversion from number to string then back to number | |
| 319 | +reproduces the original number <EM>exactly</EM>. | |
| 320 | +Thus, | |
| 321 | +the conversion does not necessarily produces nice-looking text for some numbers. | |
| 322 | +For complete control of how numbers are converted to strings, | |
| 304 | 323 | use the <CODE>format</CODE> function (see Section <A HREF="#format">6.2</A>). |
| 305 | 324 | <P> |
| 306 | 325 | <P> |
| 307 | 326 | <A NAME="adjust"></A> |
| 308 | −<A NAME="4.4"></A> | |
| 309 | −<H2>4.4 - Adjustment</H2> | |
| 327 | +<A NAME="4.3"></A> | |
| 328 | +<H2>4.3 - Adjustment</H2> | |
| 310 | 329 | <P> |
| 311 | 330 | Functions in Lua can return many values. |
| 312 | 331 | Because there are no type declarations, |
| 313 | 332 | when a function is called |
| 314 | −the system does not know how many values a function will return, | |
| 333 | +the system does not know how many values the function will return, | |
| 315 | 334 | or how many parameters it needs. |
| 316 | 335 | Therefore, sometimes, a list of values must be <EM>adjusted</EM>, at run time, |
| 317 | 336 | to a given length. |
| 318 | 337 | If there are more values than are needed, |
| 319 | 338 | then the excess values are thrown away. |
| 320 | −If there are more needs than values, | |
| 339 | +If there are less values than are needed, | |
| 321 | 340 | then the list is extended with as many <B>nil</B>'s as needed. |
| 322 | −Adjustment occurs in multiple assignment (see Section <A HREF="#assignment">4.5.2</A>) | |
| 323 | −and function calls (see Section <A HREF="#functioncall">4.6.8</A>). | |
| 341 | +This adjustment occurs in multiple assignments (see Section <A HREF="#assignment">4.4.2</A>) | |
| 342 | +and in function calls (see Section <A HREF="#functioncall">4.5.8</A>). | |
| 324 | 343 | <P> |
| 325 | 344 | <P> |
| 326 | 345 | <A NAME="stats"></A> |
| 327 | −<A NAME="4.5"></A> | |
| 328 | −<H2>4.5 - Statements</H2> | |
| 346 | +<A NAME="4.4"></A> | |
| 347 | +<H2>4.4 - Statements</H2> | |
| 329 | 348 | <P> |
| 330 | 349 | Lua supports an almost conventional set of <A NAME="statements">statements</A>, |
| 331 | 350 | similar to those in Pascal or C. |
| 332 | 351 | The conventional commands include |
| 333 | −assignment, control structures and procedure calls. | |
| 352 | +assignment, control structures, and procedure calls. | |
| 334 | 353 | Non-conventional commands include table constructors |
| 335 | −(see Section <A HREF="#tableconstructor">4.6.7</A>), | |
| 336 | −and local variable declarations (see Section <A HREF="#localvar">4.5.5</A>). | |
| 354 | +(see Section <A HREF="#tableconstructor">4.5.7</A>) | |
| 355 | +and local variable declarations (see Section <A HREF="#localvar">4.4.6</A>). | |
| 337 | 356 | <P> |
| 338 | −<H3>4.5.1 - Blocks</H3> | |
| 339 | −A <A NAME="block">block</A> is a list of statements, which are executed sequentially. | |
| 340 | −A statement may be optionally followed by a semicolon: | |
| 357 | +<H3>4.4.1 - Blocks</H3> | |
| 358 | +A <A NAME="block">block</A> is a list of statements; | |
| 359 | +syntactically, a block is equal to a chunk: | |
| 341 | 360 | <PRE> |
| 342 | −block ::= {stat sc} [ret] | |
| 343 | −sc ::= ['<B>;</B>'] | |
| 361 | + block ::= chunk | |
| 344 | 362 | </PRE> |
| 345 | −For syntactic reasons, a <A NAME="return"><TT>return</TT></A> statement can only be written | |
| 346 | −as the last statement of a block. | |
| 347 | −This restriction also avoids some ``statement not reached'' conditions. | |
| 348 | 363 | <P> |
| 349 | 364 | A block may be explicitly delimited: |
| 350 | 365 | <PRE> |
| 351 | −stat ::= <B>do</B> block <B>end</B> | |
| 366 | + stat ::= <B>do</B> block <B>end</B> | |
| 352 | 367 | </PRE> |
| 353 | −This is useful to control the scope of local variables (see Section <A HREF="#localvar">4.5.5</A>). | |
| 368 | +Explicit blocks are useful | |
| 369 | +to control the scope of local variables (see Section <A HREF="#localvar">4.4.6</A>). | |
| 370 | +Explicit blocks are also sometimes used to | |
| 371 | +add a <B>return</B> or <B>break</B> statement in the middle | |
| 372 | +of another block (see Section <A HREF="#control">4.4.3</A>). | |
| 354 | 373 | <P> |
| 355 | 374 | <A NAME="assignment"></A> |
| 356 | −<H3>4.5.2 - <A NAME="Assignment</H3>">Assignment</H3></A> | |
| 357 | −The language allows <A NAME="multiple assignment">multiple assignment</A>. | |
| 375 | +<H3>4.4.2 - <A NAME="Assignment</H3>">Assignment</H3></A> | |
| 376 | +Lua allows <A NAME="multiple assignment">multiple assignment</A>. | |
| 358 | 377 | Therefore, the syntax for assignment |
| 359 | −defines a list of variables on the left side, | |
| 378 | +defines a list of variables on the left side | |
| 360 | 379 | and a list of expressions on the right side. |
| 361 | −Both lists have their elements separated by commas: | |
| 380 | +The elements in both lists are separated by commas: | |
| 362 | 381 | <PRE> |
| 363 | −stat ::= varlist1 '<B>=</B>' explist1 | |
| 364 | −varlist1 ::= var {'<B>,</B>' var} | |
| 382 | + stat ::= varlist1 `<B>=</B>' explist1 | |
| 383 | + varlist1 ::= var {`<B>,</B>' var} | |
| 365 | 384 | </PRE> |
| 366 | 385 | This statement first evaluates all values on the right side |
| 367 | 386 | and eventual indices on the left side, |
| 368 | 387 | and then makes the assignments. |
| 369 | −Therefore, it can be used to exchange two values, as in | |
| 388 | +So, the code | |
| 389 | +<PRE> | |
| 390 | + i = 3 | |
| 391 | + i, a[i] = 4, 20 | |
| 392 | +</PRE> | |
| 393 | +sets <CODE>a[3]</CODE> to 20, but does not affect <CODE>a[4]</CODE> | |
| 394 | +because the <CODE>i</CODE> in <CODE>a[i]</CODE> is evaluated | |
| 395 | +before it is assigned <CODE>4</CODE>. | |
| 396 | +<P> | |
| 397 | +Multiple assignment can be used to exchange two values, as in | |
| 370 | 398 | <PRE> |
| 371 | − x, y = y, x | |
| 399 | + x, y = y, x | |
| 372 | 400 | </PRE> |
| 373 | −The two lists may have different lengths. | |
| 374 | −Before the assignment, the list of values is <EM>adjusted</EM> to | |
| 375 | −the length of the list of variables (see Section <A HREF="#adjust">4.4</A>). | |
| 401 | +<P> | |
| 402 | +The two lists in a multiple assignment may have different lengths. | |
| 403 | +Before the assignment, the list of values is adjusted to | |
| 404 | +the length of the list of variables (see Section <A HREF="#adjust">4.3</A>). | |
| 376 | 405 | <P> |
| 377 | 406 | A single name can denote a global variable, a local variable, |
| 378 | 407 | or a formal parameter: |
| 379 | 408 | <PRE> |
| 380 | −var ::= name | |
| 409 | + var ::= name | |
| 381 | 410 | </PRE> |
| 411 | +<P> | |
| 382 | 412 | Square brackets are used to index a table: |
| 383 | 413 | <PRE> |
| 384 | −var ::= simpleexp '<B>[</B>' exp1 '<B>]</B>' | |
| 414 | + var ::= varorfunc `<B>[</B>' exp1 `<B>]</B>' | |
| 415 | + varorfunc ::= var | functioncall | |
| 385 | 416 | </PRE> |
| 386 | −The <EM>simpleexp</EM> should result in a table value, | |
| 387 | −from where the field indexed by the expression | |
| 417 | +The <EM>varorfunc</EM> should result in a table value, | |
| 418 | +from where the field indexed by the expression <EM>exp1</EM> | |
| 388 | 419 | value gets the assigned value. |
| 389 | 420 | <P> |
| 390 | 421 | The syntax <CODE>var.NAME</CODE> is just syntactic sugar for |
| 391 | 422 | <CODE>var["NAME"]</CODE>: |
| 392 | 423 | <PRE> |
| 393 | −var ::= simpleexp '<B>.</B>' name | |
| 424 | + var ::= varorfunc `<B>.</B>' name | |
| 394 | 425 | </PRE> |
| 395 | 426 | <P> |
| 396 | 427 | The meaning of assignments and evaluations of global variables and |
| 397 | 428 | indexed variables can be changed by tag methods (see Section <A HREF="#tag-method">4.8</A>). |
| 398 | 429 | Actually, |
| 399 | 430 | an assignment <CODE>x = val</CODE>, where <CODE>x</CODE> is a global variable, |
| 400 | −is equivalent to a call <CODE>setglobal('x', val)</CODE>; | |
| 431 | +is equivalent to a call <CODE>setglobal("x", val)</CODE> and | |
| 401 | 432 | an assignment <CODE>t[i] = val</CODE> is equivalent to |
| 402 | −<CODE>settable_event(t, i, val)</CODE>. | |
| 403 | −See Section <A HREF="#tag-method">4.8</A> for a complete description of these functions. | |
| 404 | −(Function <CODE>setglobal</CODE> is pre-defined in Lua. | |
| 405 | −Function <TT>settable_event</TT> is used only for explanatory purposes.) | |
| 406 | −<P> | |
| 407 | −<H3>4.5.3 - Control Structures</H3> | |
| 408 | −The <A NAME="condition expression">condition expression</A> of a control structure may return any value. | |
| 433 | +<CODE>settable_event(t,i,val)</CODE>. | |
| 434 | +See Section <A HREF="#tag-method">4.8</A> for a complete description of these functions | |
| 435 | +(<CODE>setglobal</CODE> is in the basic library; | |
| 436 | +<TT>settable_event</TT> is used for explanatory purposes only). | |
| 437 | +<P> | |
| 438 | +<A NAME="control"></A> | |
| 439 | +<H3>4.4.3 - Control Structures</H3> | |
| 440 | +The control structures | |
| 441 | +<B>if</B>, <B>while</B>, and <B>repeat</B> have the usual meaning and | |
| 442 | +familiar syntax | |
| 443 | +<A NAME="while-do statement"></A> | |
| 444 | +<A NAME="repeat-until statement"></A> | |
| 445 | +<A NAME="if-then-else statement"></A> | |
| 446 | +<PRE> | |
| 447 | + stat ::= <B>while</B> exp1 <B>do</B> block <B>end</B> | |
| 448 | + stat ::= <B>repeat</B> block <B>until</B> exp1 | |
| 449 | + stat ::= <B>if</B> exp1 <B>then</B> block {<B>elseif</B> exp1 <B>then</B> block} [<B>else</B> block] <B>end</B> | |
| 450 | +</PRE> | |
| 451 | +The <A NAME="condition expression">condition expression</A> <EM>exp1</EM> of a control structure may return any value. | |
| 409 | 452 | All values different from <B>nil</B> are considered true; |
| 410 | 453 | only <B>nil</B> is considered false. |
| 411 | −<TT>if</TT>'s, <TT>while</TT>'s and <TT>repeat</TT>'s have the usual meaning. | |
| 412 | −<P> | |
| 413 | −<A NAME="while-do"></A><A NAME="repeat-until"></A><A NAME="if-then-else"></A> | |
| 414 | −<PRE> | |
| 415 | −stat ::= <B>while</B> exp1 <B>do</B> block <B>end</B> <BR> | <B>repeat</B> block <B>until</B> exp1 <BR> | <B>if</B> exp1 <B>then</B> block {<B>elseif</B> exp1 <B>then</B> block} [<B>else</B> block] <B>end</B> | |
| 416 | −</PRE> | |
| 417 | 454 | <P> |
| 418 | −A <TT>return</TT> is used to return values from a function or from a chunk. | |
| 455 | +The <B>return</B> statement is used to return values | |
| 456 | +from a function or from a chunk. | |
| 419 | 457 | <A NAME="return"></A> |
| 420 | 458 | |
| 421 | −Because they may return more than one value, | |
| 422 | −the syntax for a <A NAME="return statement">return statement</A> is | |
| 423 | −<PRE> | |
| 424 | −ret ::= <B>return</B> [explist1] [sc] | |
| 425 | −</PRE> | |
| 459 | +<A NAME="return statement"></A> | |
| 460 | +Because functions or chunks may return more than one value, | |
| 461 | +the syntax for the <B>return</B> statement is | |
| 462 | +<PRE> | |
| 463 | + stat ::= <B>return</B> [explist1] | |
| 464 | +</PRE> | |
| 465 | +<P> | |
| 466 | +The <B>break</B> statement can be used to terminate the execution of a loop, | |
| 467 | +skipping to the next statement after the loop: | |
| 468 | +<A NAME="break statement"></A> | |
| 469 | +<PRE> | |
| 470 | + stat ::= <B>break</B> | |
| 471 | +</PRE> | |
| 472 | +A <B>break</B> ends the innermost enclosing loop | |
| 473 | +(<B>while</B>, <B>repeat</B>, or <B>for</B>). | |
| 474 | +<P> | |
| 475 | +For syntactic reasons, <B>return</B> and <B>break</B> | |
| 476 | +statements can only be written as the <EM>last</EM> statements of a block. | |
| 477 | +If it is really necessary to <B>return</B> or <B>break</B> in the | |
| 478 | +middle of a block, | |
| 479 | +an explicit inner block can used, | |
| 480 | +as in the idiom `<CODE>do return end</CODE>', | |
| 481 | +because now <B>return</B> is last statement in the inner block. | |
| 482 | +<P> | |
| 483 | +<A NAME="for"></A> | |
| 484 | +<H3>4.4.4 - For Statement</H3> <A NAME="for statement"></A> | |
| 485 | +<P> | |
| 486 | +The <B>for</B> statement has two forms, | |
| 487 | +one for numbers and one for tables. | |
| 488 | +The numerical <B>for</B> loop has the following syntax: | |
| 489 | +<PRE> | |
| 490 | + stat ::= <B>for</B> name `<B>=</B>' exp1 `<B>,</B>' exp1 [`<B>,</B>' exp1] <B>do</B> block <B>end</B> | |
| 491 | +</PRE> | |
| 492 | +A <B>for</B> statement like | |
| 493 | +<PRE> | |
| 494 | + for var = e1 ,e2, e3 do block end | |
| 495 | +</PRE> | |
| 496 | +is equivalent to the code: | |
| 497 | +<PRE> | |
| 498 | + do | |
| 499 | + local var, _limit, _step = tonumber(e1), tonumber(e2), tonumber(e3) | |
| 500 | + if not (var and _limit and _step) then error() end | |
| 501 | + while (_step>0 and var<=_limit) or (_step<=0 and var>=_limit) do | |
| 502 | + block | |
| 503 | + var = var+_step | |
| 504 | + end | |
| 505 | + end | |
| 506 | +</PRE> | |
| 507 | +Note the following: | |
| 508 | +<UL><LI>sep=0pt | |
| 509 | +<LI><CODE>_limit</CODE> and <CODE>_step</CODE> are invisible variables. | |
| 510 | +The names are here for explanatory purposes only. | |
| 511 | +<LI>The behavior is <EM>undefined</EM> if you assign to <CODE>var</CODE> inside | |
| 512 | +the block. | |
| 513 | +<LI>If the third expression (the step) is absent, then a step of 1 is used. | |
| 514 | +<LI>Both the limit and the step are evaluated only once, | |
| 515 | +before the loop starts. | |
| 516 | +<LI>The variable <CODE>var</CODE> is local to the statement; | |
| 517 | +you cannot use its value after the <B>for</B> ends. | |
| 518 | +<LI>You can use <B>break</B> to exit a <B>for</B>. | |
| 519 | +If you need the value of the index, | |
| 520 | +assign it to another variable before breaking. | |
| 521 | +</UL> | |
| 522 | +<P> | |
| 523 | +The table <B>for</B> statement traverses all pairs | |
| 524 | +(index,value) of a given table. | |
| 525 | +It has the following syntax: | |
| 526 | +<PRE> | |
| 527 | + stat ::= <B>for</B> name `<B>,</B>' name <B>in</B> exp1 <B>do</B> block <B>end</B> | |
| 528 | +</PRE> | |
| 529 | +A <B>for</B> statement like | |
| 530 | +<PRE> | |
| 531 | + for index, value in exp do block end | |
| 532 | +</PRE> | |
| 533 | +is equivalent to the code: | |
| 534 | +<PRE> | |
| 535 | + do | |
| 536 | + local _t = exp | |
| 537 | + local index, value = next(t, nil) | |
| 538 | + while index do | |
| 539 | + block | |
| 540 | + index, value = next(t, index) | |
| 541 | + end | |
| 542 | + end | |
| 543 | +</PRE> | |
| 544 | +Note the following: | |
| 545 | +<UL><LI>sep=0pt | |
| 546 | +<LI><CODE>_t</CODE> is an invisible variable. | |
| 547 | +The name is here for explanatory purposes only. | |
| 548 | +<LI>The behavior is <EM>undefined</EM> if you assign to <CODE>index</CODE> inside | |
| 549 | +the block. | |
| 550 | +<LI>The behavior is <EM>undefined</EM> if you change | |
| 551 | +the table <CODE>_t</CODE> during the traversal. | |
| 552 | +<LI>The variables <CODE>index</CODE> and <CODE>value</CODE> are local to the statement; | |
| 553 | +you cannot use their values after the <B>for</B> ends. | |
| 554 | +<LI>You can use <B>break</B> to exit a <B>for</B>. | |
| 555 | +If you need the value of <CODE>index</CODE> or <CODE>value</CODE>, | |
| 556 | +assign them to other variables before breaking. | |
| 557 | +<LI>The order that table elements are traversed is undefined, | |
| 558 | +<EM>even for numerical indices</EM>. | |
| 559 | +If you want to traverse indices in numerical order, | |
| 560 | +use a numerical <B>for</B>. | |
| 561 | +</UL> | |
| 562 | +<P> | |
| 426 | 563 | <P> |
| 427 | 564 | <A NAME="funcstat"></A> |
| 428 | −<H3>4.5.4 - Function Calls as Statements</H3> | |
| 565 | +<H3>4.4.5 - Function Calls as Statements</H3> | |
| 429 | 566 | Because of possible side-effects, |
| 430 | 567 | function calls can be executed as statements: |
| 431 | 568 | <PRE> |
| 432 | −stat ::= functioncall | |
| 569 | + stat ::= functioncall | |
| 433 | 570 | </PRE> |
| 434 | 571 | In this case, all returned values are thrown away. |
| 435 | −Function calls are explained in Section <A HREF="#functioncall">4.6.8</A>. | |
| 572 | +Function calls are explained in Section <A HREF="#functioncall">4.5.8</A>. | |
| 436 | 573 | <P> |
| 437 | 574 | <A NAME="localvar"></A> |
| 438 | −<H3>4.5.5 - Local Declarations</H3> | |
| 575 | +<H3>4.4.6 - Local Declarations</H3> | |
| 439 | 576 | <A NAME="Local variables">Local variables</A> may be declared anywhere inside a block. |
| 440 | −Their scope begins after the declaration and lasts until the | |
| 441 | −end of the block. | |
| 442 | 577 | The declaration may include an initial assignment: |
| 443 | 578 | <PRE> |
| 444 | −stat ::= <B>local</B> declist [init] | |
| 445 | −declist ::= name {'<B>,</B>' name} | |
| 446 | −init ::= '<B>=</B>' explist1 | |
| 579 | + stat ::= <B>local</B> declist [init] | |
| 580 | + declist ::= name {`<B>,</B>' name} | |
| 581 | + init ::= `<B>=</B>' explist1 | |
| 447 | 582 | </PRE> |
| 448 | 583 | If present, an initial assignment has the same semantics |
| 449 | 584 | of a multiple assignment. |
| 450 | 585 | Otherwise, all variables are initialized with <B>nil</B>. |
| 451 | 586 | <P> |
| 587 | +A chunk is also a block, | |
| 588 | +and so local variables can be declared outside any explicit block. | |
| 452 | 589 | <P> |
| 453 | −<A NAME="4.6"></A> | |
| 454 | −<H2>4.6 - Expressions</H2> | |
| 590 | +The scope of local variables begins <EM>after</EM> | |
| 591 | +the declaration and lasts until the end of the block. | |
| 592 | +Thus, the code | |
| 593 | +<CODE>local print=print</CODE> | |
| 594 | +creates a local variable called <CODE>print</CODE> whose | |
| 595 | +initial value is that of the <EM>global</EM> variable of the same name. | |
| 455 | 596 | <P> |
| 456 | −<H3>4.6.1 - <A NAME="Basic Expressions</H3>">Basic Expressions</H3></A> | |
| 457 | −Basic expressions are | |
| 458 | −<PRE> | |
| 459 | −exp ::= '<B>(</B>' exp '<B>)</B>' | |
| 460 | −exp ::= <B>nil</B> | |
| 461 | −exp ::= '<B>number</B>' | |
| 462 | −exp ::= '<B>literal</B>' | |
| 463 | −exp ::= function | |
| 464 | −exp ::= simpleexp | |
| 465 | −</PRE> | |
| 597 | +<P> | |
| 598 | +<A NAME="4.5"></A> | |
| 599 | +<H2>4.5 - Expressions</H2> | |
| 600 | +<P> | |
| 601 | +<H3>4.5.1 - <A NAME="Basic Expressions</H3>">Basic Expressions</H3></A> | |
| 602 | +The basic expressions in Lua are | |
| 466 | 603 | <PRE> |
| 467 | −simpleexp ::= var | |
| 468 | −simpleexp ::= upvalue | |
| 469 | −simpleexp ::= functioncall | |
| 604 | + exp ::= `<B>(</B>' exp `<B>)</B>' | |
| 605 | + exp ::= <B>nil</B> | |
| 606 | + exp ::= number | |
| 607 | + exp ::= literal | |
| 608 | + exp ::= var | |
| 609 | + exp ::= upvalue | |
| 610 | + exp ::= function | |
| 611 | + exp ::= functioncall | |
| 612 | + exp ::= tableconstructor | |
| 470 | 613 | </PRE> |
| 471 | 614 | <P> |
| 472 | 615 | Numbers (numerical constants) and |
| 473 | −string literals are explained in Section <A HREF="#lexical">4.1</A>; | |
| 474 | −variables are explained in Section <A HREF="#assignment">4.5.2</A>; | |
| 475 | −upvalues are explained in Section <A HREF="#upvalue">4.7</A>; | |
| 476 | −function definitions (<EM>function</EM>) are explained in Section <A HREF="#func-def">4.6.9</A>; | |
| 477 | −function calls are explained in Section <A HREF="#functioncall">4.6.8</A>. | |
| 616 | +literal strings are explained in Section <A HREF="#lexical">4.1</A>; | |
| 617 | +variables are explained in Section <A HREF="#assignment">4.4.2</A>; | |
| 618 | +upvalues are explained in Section <A HREF="#upvalue">4.6</A>; | |
| 619 | +function definitions are explained in Section <A HREF="#func-def">4.5.9</A>; | |
| 620 | +function calls are explained in Section <A HREF="#functioncall">4.5.8</A>. | |
| 621 | +Table constructors are explained in Section <A HREF="#tableconstructor">4.5.7</A>. | |
| 478 | 622 | <P> |
| 479 | 623 | An access to a global variable <CODE>x</CODE> is equivalent to a |
| 480 | −call <CODE>getglobal('x')</CODE>; | |
| 624 | +call <CODE>getglobal("x")</CODE> and | |
| 481 | 625 | an access to an indexed variable <CODE>t[i]</CODE> is equivalent to |
| 482 | −a call <CODE>gettable_event(t, i)</CODE>. | |
| 483 | −See Section <A HREF="#tag-method">4.8</A> for a description of these functions. | |
| 484 | −(Function <CODE>getglobal</CODE> is pre-defined in Lua. | |
| 485 | −Function <TT>gettable_event</TT> is used only for explanatory purposes.) | |
| 626 | +a call <CODE>gettable_event(t,i)</CODE>. | |
| 627 | +See Section <A HREF="#tag-method">4.8</A> for a description of these functions | |
| 628 | +(<CODE>getglobal</CODE> is in the basic library; | |
| 629 | +<TT>gettable_event</TT> is used for explanatory purposes only). | |
| 486 | 630 | <P> |
| 487 | 631 | The non-terminal <EM>exp1</EM> is used to indicate that the values |
| 488 | 632 | returned by an expression must be adjusted to one single value: |
| 489 | 633 | <PRE> |
| 490 | −exp1 ::= exp | |
| 634 | + exp1 ::= exp | |
| 491 | 635 | </PRE> |
| 492 | 636 | <P> |
| 493 | −<H3>4.6.2 - Arithmetic Operators</H3> | |
| 637 | +<H3>4.5.2 - Arithmetic Operators</H3> | |
| 494 | 638 | Lua supports the usual <A NAME="arithmetic operators">arithmetic operators</A>: |
| 495 | 639 | the binary <CODE>+</CODE> (addition), |
| 496 | 640 | <CODE>-</CODE> (subtraction), <CODE>*</CODE> (multiplication), |
| 497 | −<CODE>/</CODE> (division) and <CODE>^</CODE> (exponentiation), | |
| 641 | +<CODE>/</CODE> (division), and <CODE>^</CODE> (exponentiation); | |
| 498 | 642 | and unary <CODE>-</CODE> (negation). |
| 499 | 643 | If the operands are numbers, or strings that can be converted to |
| 500 | −numbers (according to the rules given in Section <A HREF="#coercion">4.3</A>), | |
| 644 | +numbers (according to the rules given in Section <A HREF="#coercion">4.2</A>), | |
| 501 | 645 | then all operations except exponentiation have the usual meaning. |
| 502 | 646 | Otherwise, an appropriate tag method is called (see Section <A HREF="#tag-method">4.8</A>). |
| 503 | 647 | An exponentiation always calls a tag method. |
| @@ -505,196 +649,216 @@ The standard mathematical library redefines this method for numbers, · 1 unmodified line | ||
| 505 | 649 | giving the expected meaning to <A NAME="exponentiation">exponentiation</A> |
| 506 | 650 | (see Section <A HREF="#mathlib">6.3</A>). |
| 507 | 651 | <P> |
| 508 | −<H3>4.6.3 - Relational Operators</H3> | |
| 509 | −Lua provides the following <A NAME="relational operators">relational operators</A>: | |
| 652 | +<H3>4.5.3 - Relational Operators</H3> | |
| 653 | +The <A NAME="relational operators">relational operators</A> in Lua are | |
| 510 | 654 | <PRE> |
| 511 | − < > <= >= ~= == | |
| 655 | + == ~= < > <= >= | |
| 512 | 656 | </PRE> |
| 513 | −All these return <B>nil</B> as false and a value different from <B>nil</B> as true. | |
| 657 | +These operators return <B>nil</B> as false and a value different from <B>nil</B> as true. | |
| 514 | 658 | <P> |
| 515 | −Equality first compares the tags of its operands. | |
| 659 | +Equality (<CODE>==</CODE>) first compares the tags of its operands. | |
| 516 | 660 | If they are different, then the result is <B>nil</B>. |
| 517 | 661 | Otherwise, their values are compared. |
| 518 | 662 | Numbers and strings are compared in the usual way. |
| 519 | −Tables, userdata and functions are compared by reference, | |
| 520 | −that is, two tables are considered equal only if they are the same table. | |
| 663 | +Tables, userdata, and functions are compared by reference, | |
| 664 | +that is, two tables are considered equal only if they are the <EM>same</EM> table. | |
| 521 | 665 | The operator <CODE>~=</CODE> is exactly the negation of equality (<CODE>==</CODE>). |
| 522 | −Note that the conversion rules of Section <A HREF="#coercion">4.3</A> | |
| 666 | +<P> | |
| 667 | +The conversion rules of Section <A HREF="#coercion">4.2</A> | |
| 523 | 668 | <EM>do not</EM> apply to equality comparisons. |
| 524 | −Thus, <CODE>"0"==0</CODE> evaluates to false, | |
| 669 | +Thus, <CODE>"0"==0</CODE> evaluates to <EM>false</EM>, | |
| 525 | 670 | and <CODE>t[0]</CODE> and <CODE>t["0"]</CODE> denote different |
| 526 | 671 | entries in a table. |
| 527 | 672 | <P> |
| 528 | −The other operators work as follows. | |
| 673 | +The order operators work as follows. | |
| 529 | 674 | If both arguments are numbers, then they are compared as such. |
| 530 | 675 | Otherwise, if both arguments are strings, |
| 531 | 676 | then their values are compared using lexicographical order. |
| 532 | −Otherwise, the ``order'' tag method is called (see Section <A HREF="#tag-method">4.8</A>). | |
| 677 | +Otherwise, the ``lt'' tag method is called (see Section <A HREF="#tag-method">4.8</A>). | |
| 533 | 678 | <P> |
| 534 | −<H3>4.6.4 - Logical Operators</H3> | |
| 535 | −The <A NAME="logical operators">logical operators</A> are | |
| 679 | +<H3>4.5.4 - Logical Operators</H3> | |
| 680 | +The <A NAME="logical operators">logical operators</A> in Lua are | |
| 536 | 681 | <A NAME="and"></A><A NAME="or"></A><A NAME="not"></A> |
| 537 | 682 | <PRE> |
| 538 | − and or not | |
| 683 | + and or not | |
| 539 | 684 | </PRE> |
| 540 | −Like control structures, all logical operators | |
| 685 | +Like the control structures, all logical operators | |
| 541 | 686 | consider <B>nil</B> as false and anything else as true. |
| 542 | −The operator <CODE>and</CODE> returns <B>nil</B> if its first argument is <B>nil</B>; | |
| 687 | +<P> | |
| 688 | +The conjunction operator <CODE>and</CODE> returns <B>nil</B> if its first argument is <B>nil</B>; | |
| 543 | 689 | otherwise, it returns its second argument. |
| 544 | −The operator <CODE>or</CODE> returns its first argument | |
| 690 | +The disjunction operator <CODE>or</CODE> returns its first argument | |
| 545 | 691 | if it is different from <B>nil</B>; |
| 546 | 692 | otherwise, it returns its second argument. |
| 547 | 693 | Both <CODE>and</CODE> and <CODE>or</CODE> use <A NAME="short-cut evaluation">short-cut evaluation</A>, |
| 548 | 694 | that is, |
| 549 | −the second operand is evaluated only when necessary. | |
| 695 | +the second operand is evaluated only if necessary. | |
| 550 | 696 | <P> |
| 551 | −A useful Lua idiom is <CODE>x = x or v</CODE>, | |
| 697 | +There are two useful Lua idioms that use logical operators. | |
| 698 | +The first idiom is | |
| 699 | +<PRE> | |
| 700 | + x = x or v | |
| 701 | +</PRE> | |
| 552 | 702 | which is equivalent to |
| 553 | 703 | <PRE> |
| 554 | − if x == nil then x = v end | |
| 704 | + if x == nil then x = v end | |
| 555 | 705 | </PRE> |
| 556 | −i.e., it sets <CODE>x</CODE> to a default value <CODE>v</CODE> when | |
| 557 | −<CODE>x</CODE> is not set. | |
| 706 | +This idiom sets <CODE>x</CODE> to a default value <CODE>v</CODE> when <CODE>x</CODE> is not set. | |
| 558 | 707 | <P> |
| 559 | −<H3>4.6.5 - Concatenation</H3> | |
| 708 | +The second idiom is | |
| 709 | +<PRE> | |
| 710 | + x = a and b or c | |
| 711 | +</PRE> | |
| 712 | +which should be read as <CODE>x = (a and b) or c</CODE>. | |
| 713 | +This idiom is equivalent to | |
| 714 | +<PRE> | |
| 715 | + if a then x = b else x = c end | |
| 716 | +</PRE> | |
| 717 | +provided that <CODE>b</CODE> is not <B>nil</B>. | |
| 718 | +<P> | |
| 719 | +<A NAME="concat"></A> | |
| 720 | +<H3>4.5.5 - Concatenation</H3> | |
| 560 | 721 | The string <A NAME="concatenation">concatenation</A> operator in Lua is |
| 561 | −denoted by ``<A NAME=".."><TT>..</TT></A>''. | |
| 562 | −If both operands are strings or numbers, they are converted to | |
| 563 | −strings according to the rules in Section <A HREF="#coercion">4.3</A>. | |
| 722 | +denoted by two dots (`<A NAME=".."><TT>..</TT></A>'). | |
| 723 | +If both operands are strings or numbers, then they are converted to | |
| 724 | +strings according to the rules in Section <A HREF="#coercion">4.2</A>. | |
| 564 | 725 | Otherwise, the ``concat'' tag method is called (see Section <A HREF="#tag-method">4.8</A>). |
| 565 | 726 | <P> |
| 566 | −<H3>4.6.6 - Precedence</H3> | |
| 567 | −<A NAME="Operator precedence">Operator precedence</A> follows the table below, | |
| 727 | +<H3>4.5.6 - Precedence</H3> | |
| 728 | +<A NAME="Operator precedence">Operator precedence</A> in Lua follows the table below, | |
| 568 | 729 | from the lower to the higher priority: |
| 569 | 730 | <PRE> |
| 570 | − and or | |
| 571 | − < > <= >= ~= == | |
| 572 | − .. | |
| 573 | − + - | |
| 574 | − * / | |
| 575 | − not - (unary) | |
| 576 | − ^ | |
| 731 | + and or | |
| 732 | + < > <= >= ~= == | |
| 733 | + .. | |
| 734 | + + - | |
| 735 | + * / | |
| 736 | + not - (unary) | |
| 737 | + ^ | |
| 577 | 738 | </PRE> |
| 578 | 739 | All binary operators are left associative, |
| 579 | 740 | except for <CODE>^</CODE> (exponentiation), |
| 580 | 741 | which is right associative. |
| 742 | +The pre-compiler may rearrange the order of evaluation of | |
| 743 | +associative operators (such as <CODE>..</CODE> or <CODE>+</CODE>), | |
| 744 | +as long as these optimizations do not change normal results. | |
| 745 | +However, these optimizations may change some results | |
| 746 | +if you define non-associative | |
| 747 | +tag methods for these operators. | |
| 581 | 748 | <P> |
| 582 | 749 | <A NAME="tableconstructor"></A> |
| 583 | −<H3>4.6.7 - Table Constructors</H3> | |
| 750 | +<H3>4.5.7 - Table Constructors</H3> | |
| 584 | 751 | Table <A NAME="constructors">constructors</A> are expressions that create tables; |
| 585 | 752 | every time a constructor is evaluated, a new table is created. |
| 586 | 753 | Constructors can be used to create empty tables, |
| 587 | −or to create a table and initialize some fields. | |
| 588 | −<P> | |
| 754 | +or to create a table and initialize some of its fields. | |
| 589 | 755 | The general syntax for constructors is |
| 590 | 756 | <PRE> |
| 591 | −tableconstructor ::= '<B>{</B>' fieldlist '<B>}</B>' | |
| 592 | −fieldlist ::= lfieldlist | ffieldlist | lfieldlist '<B>;</B>' ffieldlist | ffieldlist '<B>;</B>' lfieldlist | |
| 593 | −lfieldlist ::= [lfieldlist1] | |
| 594 | −ffieldlist ::= [ffieldlist1] | |
| 757 | + tableconstructor ::= `<B>{</B>' fieldlist `<B>}</B>' | |
| 758 | + fieldlist ::= lfieldlist | ffieldlist | lfieldlist `<B>;</B>' ffieldlist | ffieldlist `<B>;</B>' lfieldlist | |
| 759 | + lfieldlist ::= [lfieldlist1] | |
| 760 | + ffieldlist ::= [ffieldlist1] | |
| 595 | 761 | </PRE> |
| 596 | 762 | <P> |
| 597 | 763 | The form <EM>lfieldlist1</EM> is used to initialize lists: |
| 598 | 764 | <PRE> |
| 599 | −lfieldlist1 ::= exp {'<B>,</B>' exp} ['<B>,</B>'] | |
| 765 | + lfieldlist1 ::= exp {`<B>,</B>' exp} [`<B>,</B>'] | |
| 600 | 766 | </PRE> |
| 601 | 767 | The expressions in the list are assigned to consecutive numerical indices, |
| 602 | −starting with 1. | |
| 768 | +starting with 1. | |
| 603 | 769 | For example, |
| 604 | 770 | <PRE> |
| 605 | − a = {"v1", "v2", 34} | |
| 771 | + a = {"v1", "v2", 34} | |
| 606 | 772 | </PRE> |
| 607 | 773 | is equivalent to |
| 608 | 774 | <PRE> |
| 609 | − do | |
| 610 | − local temp = {} | |
| 611 | − temp[1] = "v1" | |
| 612 | − temp[2] = "v2" | |
| 613 | − temp[3] = 34 | |
| 614 | − a = temp | |
| 615 | − end | |
| 775 | + do | |
| 776 | + local temp = {} | |
| 777 | + temp[1] = "v1" | |
| 778 | + temp[2] = "v2" | |
| 779 | + temp[3] = 34 | |
| 780 | + a = temp | |
| 781 | + end | |
| 616 | 782 | </PRE> |
| 617 | 783 | <P> |
| 618 | 784 | The form <EM>ffieldlist1</EM> initializes other fields in a table: |
| 619 | 785 | <PRE> |
| 620 | −ffieldlist1 ::= ffield {'<B>,</B>' ffield} ['<B>,</B>'] | |
| 621 | −ffield ::= '<B>[</B>' exp '<B>]</B>' '<B>=</B>' exp | name '<B>=</B>' exp | |
| 786 | + ffieldlist1 ::= ffield {`<B>,</B>' ffield} [`<B>,</B>'] | |
| 787 | + ffield ::= `<B>[</B>' exp `<B>]</B>' `<B>=</B>' exp | name `<B>=</B>' exp | |
| 622 | 788 | </PRE> |
| 623 | 789 | For example, |
| 624 | 790 | <PRE> |
| 625 | − a = {[f(k)] = g(y), x = 1, y = 3, [0] = b+c} | |
| 791 | + a = {[f(k)] = g(y), x = 1, y = 3, [0] = b+c} | |
| 626 | 792 | </PRE> |
| 627 | 793 | is equivalent to |
| 628 | 794 | <PRE> |
| 629 | − do | |
| 630 | − local temp = {} | |
| 631 | − temp[f(k)] = g(y) | |
| 632 | − temp.x = 1 -- or temp["x"] = 1 | |
| 633 | − temp.y = 3 -- or temp["y"] = 3 | |
| 634 | − temp[0] = b+c | |
| 635 | − a = temp | |
| 636 | − end | |
| 795 | + do | |
| 796 | + local temp = {} | |
| 797 | + temp[f(k)] = g(y) | |
| 798 | + temp.x = 1 -- or temp["x"] = 1 | |
| 799 | + temp.y = 3 -- or temp["y"] = 3 | |
| 800 | + temp[0] = b+c | |
| 801 | + a = temp | |
| 802 | + end | |
| 637 | 803 | </PRE> |
| 638 | 804 | An expression like <CODE>{x = 1, y = 4}</CODE> is |
| 639 | 805 | in fact syntactic sugar for <CODE>{["x"] = 1, ["y"] = 4}</CODE>. |
| 640 | 806 | <P> |
| 641 | 807 | Both forms may have an optional trailing comma, |
| 642 | 808 | and can be used in the same constructor separated by |
| 643 | −a semi-collon. | |
| 644 | −For example, all forms below are correct: | |
| 809 | +a semi-colon. | |
| 810 | +For example, all forms below are correct. | |
| 645 | 811 | <PRE> |
| 646 | − x = {;} | |
| 647 | − x = {'a', 'b',} | |
| 648 | − x = {type='list'; 'a', 'b'} | |
| 649 | − x = {f(0), f(1), f(2),; n=3,} | |
| 812 | + x = {;} | |
| 813 | + x = {"a", "b",} | |
| 814 | + x = {type="list"; "a", "b"} | |
| 815 | + x = {f(0), f(1), f(2),; n=3,} | |
| 650 | 816 | </PRE> |
| 651 | 817 | <P> |
| 652 | 818 | <A NAME="functioncall"></A> |
| 653 | −<H3>4.6.8 - Function Calls</H3> | |
| 654 | −A <A NAME="function call">function call</A> has the following syntax: | |
| 819 | +<H3>4.5.8 - Function Calls</H3> | |
| 820 | +A <A NAME="function call">function call</A> in Lua has the following syntax: | |
| 655 | 821 | <PRE> |
| 656 | −functioncall ::= simpleexp args | |
| 822 | + functioncall ::= varorfunc args | |
| 657 | 823 | </PRE> |
| 658 | −First, <EM>simpleexp</EM> is evaluated. | |
| 824 | +First, <EM>varorfunc</EM> is evaluated. | |
| 659 | 825 | If its value has type <EM>function</EM>, |
| 660 | 826 | then this function is called, |
| 661 | 827 | with the given arguments. |
| 662 | 828 | Otherwise, the ``function'' tag method is called, |
| 663 | −having as first parameter the value of <EM>simpleexp</EM>, | |
| 664 | −and then the original call parameters. | |
| 829 | +having as first parameter the value of <EM>varorfunc</EM>, | |
| 830 | +and then the original call arguments | |
| 831 | +(see Section <A HREF="#tag-method">4.8</A>). | |
| 665 | 832 | <P> |
| 666 | −The form: | |
| 833 | +The form | |
| 667 | 834 | <PRE> |
| 668 | −functioncall ::= simpleexp '<B>:</B>' name args | |
| 835 | + functioncall ::= varorfunc `<B>:</B>' name args | |
| 669 | 836 | </PRE> |
| 670 | 837 | can be used to call ``methods''. |
| 671 | −A call <CODE>simpleexp:name(...)</CODE> | |
| 672 | −is syntactic sugar for | |
| 673 | −<PRE> | |
| 674 | − simpleexp.name(simpleexp, ...) | |
| 675 | −</PRE> | |
| 676 | −except that <CODE>simpleexp</CODE> is evaluated only once. | |
| 838 | +A call <CODE>v:name(...)</CODE> | |
| 839 | +is syntactic sugar for <CODE>v.name(v, ...)</CODE>, | |
| 840 | +except that <CODE>v</CODE> is evaluated only once. | |
| 677 | 841 | <P> |
| 678 | 842 | Arguments have the following syntax: |
| 679 | 843 | <PRE> |
| 680 | −args ::= '<B>(</B>' [explist1] '<B>)</B>' | |
| 681 | −args ::= tableconstructor | |
| 682 | −args ::= '<B>literal</B>' | |
| 683 | −explist1 ::= exp1 {'<B>,</B>' exp1} | |
| 844 | + args ::= `<B>(</B>' [explist1] `<B>)</B>' | |
| 845 | + args ::= tableconstructor | |
| 846 | + args ::= literal | |
| 847 | + explist1 ::= {exp1 `<B>,</B>'} exp | |
| 684 | 848 | </PRE> |
| 685 | 849 | All argument expressions are evaluated before the call. |
| 686 | 850 | A call of the form <CODE>f{...}</CODE> is syntactic sugar for |
| 687 | 851 | <CODE>f({...})</CODE>, that is, |
| 688 | −the parameter list is a single new table. | |
| 852 | +the argument list is a single new table. | |
| 689 | 853 | A call of the form <CODE>f'...'</CODE> |
| 690 | 854 | (or <CODE>f"..."</CODE> or <CODE>f[[...]]</CODE>) is syntactic sugar for |
| 691 | 855 | <CODE>f('...')</CODE>, that is, |
| 692 | −the parameter list is a single literal string. | |
| 856 | +the argument list is a single literal string. | |
| 693 | 857 | <P> |
| 694 | 858 | Because a function can return any number of results |
| 695 | −(see Section <A HREF="#return">4.5.3</A>), | |
| 696 | −the number of results must be adjusted before used. | |
| 697 | −If the function is called as a statement (see Section <A HREF="#funcstat">4.5.4</A>), | |
| 859 | +(see Section <A HREF="#return">4.4.3</A>), | |
| 860 | +the number of results must be adjusted before they are used (see Section <A HREF="#adjust">4.3</A>). | |
| 861 | +If the function is called as a statement (see Section <A HREF="#funcstat">4.4.5</A>), | |
| 698 | 862 | then its return list is adjusted to 0, |
| 699 | 863 | thus discarding all returned values. |
| 700 | 864 | If the function is called in a place that needs a single value |
| @@ -704,166 +868,230 @@ thus discarding all returned values but the first one. · 3 unmodified lines | ||
| 704 | 868 | If the function is called in a place that can hold many values |
| 705 | 869 | (syntactically denoted by the non-terminal <EM>exp</EM>), |
| 706 | 870 | then no adjustment is made. |
| 707 | −Note that the only place that can hold many values | |
| 708 | −is the last (or the only) expression in an assignment | |
| 709 | −or in a return statement; see examples below. | |
| 871 | +The only places that can hold many values | |
| 872 | +is the last (or the only) expression in an assignment, | |
| 873 | +in an argument list, or in the <B>return</B> statement. | |
| 874 | +Here are some examples: | |
| 710 | 875 | <PRE> |
| 711 | − f(); -- adjusted to 0 | |
| 712 | − g(x, f()); -- f() is adjusted to 1 | |
| 713 | − a,b,c = f(), x; -- f() is adjusted to 1 result (and c gets nil) | |
| 714 | − a,b,c = x, f(); -- f() is adjusted to 2 | |
| 715 | − a,b,c = f(); -- f() is adjusted to 3 | |
| 716 | − return f(); -- returns all values returned by f() | |
| 876 | + f() -- adjusted to 0 results | |
| 877 | + g(f(), x) -- f() is adjusted to 1 result | |
| 878 | + g(x, f()) -- g gets x plus all values returned by f() | |
| 879 | + a,b,c = f(), x -- f() is adjusted to 1 result (and c gets nil) | |
| 880 | + a,b,c = x, f() -- f() is adjusted to 2 | |
| 881 | + a,b,c = f() -- f() is adjusted to 3 | |
| 882 | + return f() -- returns all values returned by f() | |
| 883 | + return x,y,f() -- returns a, b, and all values returned by f() | |
| 717 | 884 | </PRE> |
| 718 | 885 | <P> |
| 719 | 886 | <A NAME="func-def"></A> |
| 720 | −<H3>4.6.9 - <A NAME="Function Definitions</H3>">Function Definitions</H3></A> | |
| 887 | +<H3>4.5.9 - <A NAME="Function Definitions</H3>">Function Definitions</H3></A> | |
| 721 | 888 | <P> |
| 722 | 889 | The syntax for function definition is |
| 723 | 890 | <PRE> |
| 724 | −function ::= <B>function</B> '<B>(</B>' [parlist1] '<B>)</B>' block <B>end</B> | |
| 725 | −stat ::= <B>function</B> funcname '<B>(</B>' [parlist1] '<B>)</B>' block <B>end</B> | |
| 726 | −funcname ::= name | name '<B>.</B>' name | |
| 891 | + function ::= <B>function</B> `<B>(</B>' [parlist1] `<B>)</B>' block <B>end</B> | |
| 892 | + stat ::= <B>function</B> funcname `<B>(</B>' [parlist1] `<B>)</B>' block <B>end</B> | |
| 893 | + funcname ::= name | name `<B>.</B>' name | name `<B>:</B>' name | |
| 727 | 894 | </PRE> |
| 728 | 895 | The statement |
| 729 | 896 | <PRE> |
| 730 | − function f (...) | |
| 731 | − ... | |
| 732 | − end | |
| 897 | + function f () ... end | |
| 733 | 898 | </PRE> |
| 734 | 899 | is just syntactic sugar for |
| 735 | 900 | <PRE> |
| 736 | − f = function (...) | |
| 737 | − ... | |
| 738 | − end | |
| 901 | + f = function () ... end | |
| 902 | +</PRE> | |
| 903 | +and the statement | |
| 904 | +<PRE> | |
| 905 | + function v.f () ... end | |
| 906 | +</PRE> | |
| 907 | +is syntactic sugar for | |
| 908 | +<PRE> | |
| 909 | + v.f = function () ... end | |
| 739 | 910 | </PRE> |
| 740 | 911 | <P> |
| 741 | 912 | A function definition is an executable expression, |
| 742 | 913 | whose value has type <EM>function</EM>. |
| 743 | 914 | When Lua pre-compiles a chunk, |
| 744 | −all its function bodies are pre-compiled, too. | |
| 915 | +all its function bodies are pre-compiled too. | |
| 745 | 916 | Then, whenever Lua executes the function definition, |
| 746 | −its upvalues are fixed (see Section <A HREF="#upvalue">4.7</A>), | |
| 747 | −and the function is <EM>instantiated</EM> (or ``closed''). | |
| 748 | −This function instance (or ``closure'') | |
| 917 | +its upvalues are fixed (see Section <A HREF="#upvalue">4.6</A>), | |
| 918 | +and the function is <EM>instantiated</EM> (or <EM>closed</EM>). | |
| 919 | +This function instance (or <EM>closure</EM>) | |
| 749 | 920 | is the final value of the expression. |
| 750 | −Different instances of a same function | |
| 921 | +Different instances of the same function | |
| 751 | 922 | may have different upvalues. |
| 752 | 923 | <P> |
| 753 | 924 | Parameters act as local variables, |
| 754 | 925 | initialized with the argument values: |
| 755 | 926 | <PRE> |
| 756 | −parlist1 ::= '<B>...</B>' | |
| 757 | −parlist1 ::= name {'<B>,</B>' name} ['<B>,</B>' '<B>...</B>'] | |
| 927 | + parlist1 ::= `<B>...</B>' | |
| 928 | + parlist1 ::= name {`<B>,</B>' name} [`<B>,</B>' `<B>...</B>'] | |
| 758 | 929 | </PRE> |
| 759 | 930 | <A NAME="vararg"></A> |
| 760 | 931 | |
| 761 | 932 | When a function is called, |
| 762 | 933 | the list of <A NAME="arguments">arguments</A> is adjusted to |
| 763 | −the length of the list of parameters (see Section <A HREF="#adjust">4.4</A>), | |
| 764 | −unless the function is a <A NAME="vararg"><EM>vararg</EM></A> function, | |
| 765 | −indicated by the dots (...) at the end of its parameter list. | |
| 934 | +the length of the list of parameters (see Section <A HREF="#adjust">4.3</A>), | |
| 935 | +unless the function is a <A NAME="vararg function"><EM>vararg function</EM></A>, | |
| 936 | +which is | |
| 937 | +indicated by three dots (`<CODE>...</CODE>') at the end of its parameter list. | |
| 766 | 938 | A vararg function does not adjust its argument list; |
| 767 | −instead, it collects any extra arguments into an implicit parameter, | |
| 939 | +instead, it collects all extra arguments into an implicit parameter, | |
| 768 | 940 | called <A NAME="arg"><TT>arg</TT></A>. |
| 769 | −This parameter is always initialized as a table, | |
| 770 | −with a field <CODE>n</CODE> whose value is the number of extra arguments, | |
| 771 | −and the extra arguments at positions 1, 2, ... | |
| 941 | +The value of <CODE>arg</CODE> is a table, | |
| 942 | +with a field <CODE>n</CODE> whose value is the number of extra arguments, | |
| 943 | +and the extra arguments at positions 1, 2, ..., <CODE>n</CODE>. | |
| 772 | 944 | <P> |
| 773 | −As an example, suppose definitions like: | |
| 945 | +As an example, consider the following definitions: | |
| 774 | 946 | <PRE> |
| 775 | − function f(a, b) end | |
| 776 | − function g(a, b, ...) end | |
| 947 | + function f(a, b) end | |
| 948 | + function g(a, b, ...) end | |
| 949 | + function r() return 1,2,3 end | |
| 777 | 950 | </PRE> |
| 778 | 951 | Then, we have the following mapping from arguments to parameters: |
| 779 | 952 | <PRE> |
| 780 | − CALL PARAMETERS | |
| 953 | + CALL PARAMETERS | |
| 781 | 954 | <P> |
| 782 | − f(3) a=3, b=nil | |
| 783 | − f(3, 4) a=3, b=4 | |
| 784 | − f(3, 4, 5) a=3, b=4 | |
| 955 | + f(3) a=3, b=nil | |
| 956 | + f(3, 4) a=3, b=4 | |
| 957 | + f(3, 4, 5) a=3, b=4 | |
| 958 | + f(r(), 10) a=1, b=10 | |
| 959 | + f(r()) a=1, b=2 | |
| 785 | 960 | <P> |
| 786 | − g(3) a=3, b=nil, arg={n=0} | |
| 787 | − g(3, 4) a=3, b=4, arg={n=0} | |
| 788 | − g(3, 4, 5, 8) a=3, b=4, arg={5, 8; n=2} | |
| 961 | + g(3) a=3, b=nil, arg={n=0} | |
| 962 | + g(3, 4) a=3, b=4, arg={n=0} | |
| 963 | + g(3, 4, 5, 8) a=3, b=4, arg={5, 8; n=2} | |
| 964 | + g(5, r()) a=5, b=1, arg={2, 3; n=2} | |
| 789 | 965 | </PRE> |
| 790 | 966 | <P> |
| 791 | −Results are returned using the <CODE>return</CODE> statement (see Section <A HREF="#return">4.5.3</A>). | |
| 792 | −If control reaches the end of a function without a return instruction, | |
| 967 | +Results are returned using the <B>return</B> statement (see Section <A HREF="#return">4.4.3</A>). | |
| 968 | +If control reaches the end of a function | |
| 969 | +without encountering a <B>return</B> statement, | |
| 793 | 970 | then the function returns with no results. |
| 794 | 971 | <P> |
| 795 | −There is a special syntax for defining <A NAME="methods">methods</A>, | |
| 796 | −that is, functions that have an implicit extra parameter <A NAME="self"><TT>self</TT></A>: | |
| 972 | +The syntax | |
| 797 | 973 | <PRE> |
| 798 | −function ::= <B>function</B> name '<B>:</B>' name '<B>(</B>' [parlist1] '<B>)</B>' block <B>end</B> | |
| 974 | + funcname ::= name `<B>:</B>' name | |
| 799 | 975 | </PRE> |
| 800 | −Thus, a declaration like | |
| 976 | +is used for defining <A NAME="methods"><EM>methods</EM></A>, | |
| 977 | +that is, functions that have an implicit extra parameter <A NAME="self"><TT>self</TT></A>. | |
| 978 | +<P> | |
| 979 | +The statement | |
| 801 | 980 | <PRE> |
| 802 | − function v:f (...) | |
| 803 | − ... | |
| 804 | − end | |
| 981 | + function v:f (...) ... end | |
| 805 | 982 | </PRE> |
| 806 | −is equivalent to | |
| 983 | +is just syntactic sugar for | |
| 807 | 984 | <PRE> |
| 808 | − v.f = function (self, ...) | |
| 809 | − ... | |
| 810 | − end | |
| 985 | + v.f = function (self, ...) ... end | |
| 811 | 986 | </PRE> |
| 812 | −that is, the function gets an extra formal parameter called <CODE>self</CODE>. | |
| 813 | −Note that the variable <CODE>v</CODE> must have been | |
| 814 | −previously initialized with a table value. | |
| 987 | +Note that the function gets an extra formal parameter called <CODE>self</CODE>. | |
| 815 | 988 | <P> |
| 816 | 989 | <P> |
| 817 | 990 | <A NAME="upvalue"></A> |
| 818 | −<A NAME="4.7"></A> | |
| 819 | −<H2>4.7 - Visibility and Upvalues</H2> | |
| 820 | −<A NAME="Visibility"></A> <A NAME="Upvalues"></A> | |
| 991 | +<A NAME="4.6"></A> | |
| 992 | +<H2>4.6 - Visibility and Upvalues</H2> | |
| 993 | +<A NAME="visibility"></A><A NAME="upvalues"></A> | |
| 821 | 994 | <P> |
| 822 | 995 | A function body may refer to its own local variables |
| 823 | −(which includes its parameters) and to global variables, | |
| 824 | −as long as they are not shadowed by local | |
| 825 | −variables from enclosing functions. | |
| 996 | +(which include its parameters) and to global variables, | |
| 997 | +as long as they are not <EM>shadowed</EM> by local | |
| 998 | +variables with the same name from enclosing functions. | |
| 826 | 999 | A function <EM>cannot</EM> access a local |
| 827 | 1000 | variable from an enclosing function, |
| 828 | 1001 | since such variables may no longer exist when the function is called. |
| 829 | 1002 | However, a function may access the <EM>value</EM> of a local variable |
| 830 | −from an enclosing function, using <EM>upvalues</EM>. | |
| 831 | −<P> | |
| 1003 | +from an enclosing function, using <EM>upvalues</EM>, | |
| 1004 | +whose syntax is | |
| 832 | 1005 | <PRE> |
| 833 | −upvalue ::= '<B>%</B>' name | |
| 1006 | + upvalue ::= `<B>%</B>' name | |
| 834 | 1007 | </PRE> |
| 1008 | +<P> | |
| 835 | 1009 | An upvalue is somewhat similar to a variable expression, |
| 836 | −but whose value is frozen when the function wherein it | |
| 1010 | +but whose value is <EM>frozen</EM> when the function wherein it | |
| 837 | 1011 | appears is instantiated. |
| 838 | 1012 | The name used in an upvalue may be the name of any variable visible |
| 839 | −at the point where the function is defined. | |
| 1013 | +at the point where the function is defined, | |
| 1014 | +that is, | |
| 1015 | +global variables and local variables | |
| 1016 | +from the <EM>immediately enclosing</EM> function. | |
| 1017 | +Note that when the upvalue is a table, | |
| 1018 | +only the <EM>reference</EM> to that table | |
| 1019 | +(which is the value of the upvalue) is frozen; | |
| 1020 | +the table contents can be changed at will. | |
| 1021 | +Using table values as upvalues is a technique for having | |
| 1022 | +writable but private state attached to functions. | |
| 840 | 1023 | <P> |
| 841 | 1024 | Here are some examples: |
| 842 | 1025 | <PRE> |
| 843 | − a,b,c = 1,2,3 -- global variables | |
| 844 | − function f (x) | |
| 845 | − local b -- x and b are local to f | |
| 846 | − local g = function (a) | |
| 847 | − local y -- a and y are local to g | |
| 848 | − p = a -- OK, access local 'a' | |
| 849 | − p = c -- OK, access global 'c' | |
| 850 | − p = b -- ERROR: cannot access a variable in outer scope | |
| 851 | − p = %b -- OK, access frozen value of 'b' (local to 'f') | |
| 852 | − p = %c -- OK, access frozen value of global 'c' | |
| 853 | − p = %y -- ERROR: 'y' is not visible where 'g' is defined | |
| 854 | − end -- g | |
| 855 | − end -- f | |
| 1026 | + a,b,c = 1,2,3 -- global variables | |
| 1027 | + local d | |
| 1028 | + function f (x) | |
| 1029 | + local b = {} -- x and b are local to f; b shadows the global b | |
| 1030 | + local g = function (a) | |
| 1031 | + local y -- a and y are local to g | |
| 1032 | + p = a -- OK, access local `a' | |
| 1033 | + p = c -- OK, access global `c' | |
| 1034 | + p = b -- ERROR: cannot access a variable in outer scope | |
| 1035 | + p = %b -- OK, access frozen value of `b' (local to `f') | |
| 1036 | + %b = 3 -- ERROR: cannot change an upvalue | |
| 1037 | + %b.x = 3 -- OK, change the table contents | |
| 1038 | + p = %c -- OK, access frozen value of global `c' | |
| 1039 | + p = %y -- ERROR: `y' is not visible where `g' is defined | |
| 1040 | + p = %d -- ERROR: `d' is not visible where `g' is defined | |
| 1041 | + end -- g | |
| 1042 | + end -- f | |
| 856 | 1043 | </PRE> |
| 857 | 1044 | <P> |
| 858 | 1045 | <P> |
| 1046 | +<A NAME="error"></A> | |
| 1047 | +<A NAME="4.7"></A> | |
| 1048 | +<H2>4.7 - Error Handling</H2> | |
| 1049 | +<P> | |
| 1050 | +Because Lua is an extension language, | |
| 1051 | +all Lua actions start from C code in the host program | |
| 1052 | +calling a function from the Lua library. | |
| 1053 | +Whenever an error occurs during Lua compilation or execution, | |
| 1054 | +the function <CODE>_ERRORMESSAGE</CODE> is called <A NAME="_ERRORMESSAGE"></A> | |
| 1055 | +(provided it is different from <B>nil</B>), | |
| 1056 | +and then the corresponding function from the library | |
| 1057 | +(<CODE>lua_dofile</CODE>, <CODE>lua_dostring</CODE>, | |
| 1058 | +<CODE>lua_dobuffer</CODE>, or <CODE>lua_call</CODE>) | |
| 1059 | +is terminated, returning an error condition. | |
| 1060 | +<P> | |
| 1061 | +Memory allocation errors are an exception to the previous rule. | |
| 1062 | +When memory allocation fails, Lua may not be able to execute the | |
| 1063 | +<CODE>_ERRORMESSAGE</CODE> function. | |
| 1064 | +So, for this kind of error, Lua does not call | |
| 1065 | +the <CODE>_ERRORMESSAGE</CODE> function; | |
| 1066 | +instead, the corresponding function from the library | |
| 1067 | +returns immediately with a special error code (<CODE>LUA_ERRMEM</CODE>). | |
| 1068 | +This and other error codes are defined in <CODE>lua.h</CODE>; | |
| 1069 | +Section <A HREF="#luado">5.8</A>. | |
| 1070 | +<P> | |
| 1071 | +The only argument to <CODE>_ERRORMESSAGE</CODE> is a string | |
| 1072 | +describing the error. | |
| 1073 | +The default definition for | |
| 1074 | +this function calls <CODE>_ALERT</CODE>, <A NAME="_ALERT"></A> | |
| 1075 | +which prints the message to <CODE>stderr</CODE> (see Section <A HREF="#alert">6.1</A>). | |
| 1076 | +The standard I/O library redefines <CODE>_ERRORMESSAGE</CODE> | |
| 1077 | +and uses the debug facilities (see Section <A HREF="#debugI">7</A>) | |
| 1078 | +to print some extra information, | |
| 1079 | +such as a call stack traceback. | |
| 1080 | +<P> | |
| 1081 | +Lua code can explicitly generate an error by calling the | |
| 1082 | +function <CODE>error</CODE> (see Section <A HREF="#pdf-error">6.1</A>). | |
| 1083 | +Lua code can ``catch'' an error using the function | |
| 1084 | +<CODE>call</CODE> (see Section <A HREF="#pdf-call">6.1</A>). | |
| 1085 | +<P> | |
| 1086 | +<P> | |
| 859 | 1087 | <A NAME="tag-method"></A> |
| 860 | 1088 | <A NAME="4.8"></A> |
| 861 | 1089 | <H2>4.8 - Tag Methods</H2> |
| 862 | 1090 | <P> |
| 863 | 1091 | Lua provides a powerful mechanism to extend its semantics, |
| 864 | −called <A NAME="tag methods"><EM>tag methods</EM></A>. | |
| 1092 | +called <EM>tag methods</EM>. | |
| 865 | 1093 | A tag method is a programmer-defined function |
| 866 | −that is called at specific key points during the evaluation of a program, | |
| 1094 | +that is called at specific key points during the execution of a Lua program, | |
| 867 | 1095 | allowing the programmer to change the standard Lua behavior at these points. |
| 868 | 1096 | Each of these points is called an <A NAME="event"><EM>event</EM></A>. |
| 869 | 1097 | <P> |
| @@ -876,8 +1104,8 @@ Its first parameter is the tag, the second parameter is the event name · 6 unmodified lines | ||
| 876 | 1104 | (a string; see below), |
| 877 | 1105 | and the third parameter is the new method (a function), |
| 878 | 1106 | or <B>nil</B> to restore the default behavior for the pair. |
| 879 | −The function returns the previous tag method for that pair. | |
| 880 | −Another function, <A NAME="gettagmethod"><TT>gettagmethod</TT></A>, | |
| 1107 | +The <CODE>settagmethod</CODE> function returns the previous tag method for that pair. | |
| 1108 | +A companion function <A NAME="gettagmethod"><TT>gettagmethod</TT></A> | |
| 881 | 1109 | receives a tag and an event name and returns the |
| 882 | 1110 | current method associated with the pair. |
| 883 | 1111 | <P> |
| @@ -885,573 +1113,640 @@ Tag methods are called in the following events, · 1 unmodified line | ||
| 885 | 1113 | identified by the given names. |
| 886 | 1114 | The semantics of tag methods is better explained by a Lua function |
| 887 | 1115 | describing the behavior of the interpreter at each event. |
| 888 | −The function not only shows when a tag method is called, | |
| 889 | −but also its arguments, its results and the default behavior. | |
| 890 | −Please notice that the code shown here is only illustrative; | |
| 1116 | +This function not only shows when a tag method is called, | |
| 1117 | +but also its arguments, its results, and the default behavior. | |
| 1118 | +The code shown here is only <EM>illustrative</EM>; | |
| 891 | 1119 | the real behavior is hard coded in the interpreter, |
| 892 | 1120 | and it is much more efficient than this simulation. |
| 893 | 1121 | All functions used in these descriptions |
| 894 | −(<CODE>rawgetglobal</CODE>, <CODE>tonumber</CODE>, <CODE>call</CODE>, etc.) | |
| 1122 | +(<CODE>rawget</CODE>, <CODE>tonumber</CODE>, <CODE>call</CODE>, etc.) | |
| 895 | 1123 | are described in Section <A HREF="#predefined">6.1</A>. |
| 896 | 1124 | <P> |
| 897 | 1125 | <DL> |
| 898 | 1126 | <P> |
| 899 | 1127 | <DT><B>``add'':</B><DD><A NAME="add event"></A> |
| 900 | −called when a <CODE>+</CODE> operation is applied to non numerical operands. | |
| 1128 | +called when a <CODE>+</CODE> operation is applied to non-numerical operands. | |
| 901 | 1129 | <P> |
| 902 | −The function <CODE>getbinmethod</CODE> defines how Lua chooses a tag method | |
| 1130 | +The function <CODE>getbinmethod</CODE> below defines how Lua chooses a tag method | |
| 903 | 1131 | for a binary operation. |
| 904 | 1132 | First, Lua tries the first operand. |
| 905 | 1133 | If its tag does not define a tag method for the operation, |
| 906 | 1134 | then Lua tries the second operand. |
| 907 | −If it also fails, then it gets a tag method from tag 0: | |
| 908 | −<PRE> | |
| 909 | − function getbinmethod (op1, op2, event) | |
| 910 | − return gettagmethod(tag(op1), event) or | |
| 911 | − gettagmethod(tag(op2), event) or | |
| 912 | − gettagmethod(0, event) | |
| 913 | − end | |
| 914 | −</PRE> | |
| 915 | −<PRE> | |
| 916 | − function add_event (op1, op2) | |
| 917 | − local o1, o2 = tonumber(op1), tonumber(op2) | |
| 918 | − if o1 and o2 then -- both operands are numeric | |
| 919 | − return o1+o2 -- '+' here is the primitive 'add' | |
| 920 | − else -- at least one of the operands is not numeric | |
| 921 | − local tm = getbinmethod(op1, op2, "add") | |
| 922 | − if tm then | |
| 923 | − -- call the method with both operands and an extra | |
| 924 | − -- argument with the event name | |
| 925 | − return tm(op1, op2, "add") | |
| 926 | − else -- no tag method available: default behavior | |
| 927 | − error("unexpected type at arithmetic operation") | |
| 928 | − end | |
| 929 | − end | |
| 930 | − end | |
| 1135 | +If it also fails, then it gets a tag method from tag 0. | |
| 1136 | +<PRE> | |
| 1137 | + function getbinmethod (op1, op2, event) | |
| 1138 | + return gettagmethod(tag(op1), event) or | |
| 1139 | + gettagmethod(tag(op2), event) or | |
| 1140 | + gettagmethod(0, event) | |
| 1141 | + end | |
| 1142 | +</PRE> | |
| 1143 | +Using this function, | |
| 1144 | +the tag method for the ``add'' event is | |
| 1145 | +<PRE> | |
| 1146 | + function add_event (op1, op2) | |
| 1147 | + local o1, o2 = tonumber(op1), tonumber(op2) | |
| 1148 | + if o1 and o2 then -- both operands are numeric | |
| 1149 | + return o1+o2 -- '+' here is the primitive 'add' | |
| 1150 | + else -- at least one of the operands is not numeric | |
| 1151 | + local tm = getbinmethod(op1, op2, "add") | |
| 1152 | + if tm then | |
| 1153 | + -- call the method with both operands and an extra | |
| 1154 | + -- argument with the event name | |
| 1155 | + return tm(op1, op2, "add") | |
| 1156 | + else -- no tag method available: default behavior | |
| 1157 | + error("unexpected type at arithmetic operation") | |
| 1158 | + end | |
| 1159 | + end | |
| 1160 | + end | |
| 931 | 1161 | </PRE> |
| 932 | 1162 | <P> |
| 933 | 1163 | <DT><B>``sub'':</B><DD><A NAME="sub event"></A> |
| 934 | −called when a <CODE>-</CODE> operation is applied to non numerical operands. | |
| 935 | −Behavior similar to the <CODE>"add"</CODE> event. | |
| 1164 | +called when a <CODE>-</CODE> operation is applied to non-numerical operands. | |
| 1165 | +Behavior similar to the ``add'' event. | |
| 936 | 1166 | <P> |
| 937 | 1167 | <DT><B>``mul'':</B><DD><A NAME="mul event"></A> |
| 938 | −called when a <CODE>*</CODE> operation is applied to non numerical operands. | |
| 939 | −Behavior similar to the <CODE>"add"</CODE> event. | |
| 1168 | +called when a <CODE>*</CODE> operation is applied to non-numerical operands. | |
| 1169 | +Behavior similar to the ``add'' event. | |
| 940 | 1170 | <P> |
| 941 | 1171 | <DT><B>``div'':</B><DD><A NAME="div event"></A> |
| 942 | −called when a <CODE>/</CODE> operation is applied to non numerical operands. | |
| 943 | −Behavior similar to the <CODE>"add"</CODE> event. | |
| 1172 | +called when a <CODE>/</CODE> operation is applied to non-numerical operands. | |
| 1173 | +Behavior similar to the ``add'' event. | |
| 944 | 1174 | <P> |
| 945 | 1175 | <DT><B>``pow'':</B><DD><A NAME="pow event"></A> |
| 946 | −called when a <CODE>^</CODE> operation is applied. | |
| 1176 | +called when a <CODE>^</CODE> operation (exponentiation) is applied, | |
| 1177 | +even for numerical operands. | |
| 947 | 1178 | <PRE> |
| 948 | − function pow_event (op1, op2) | |
| 949 | − local tm = getbinmethod(op1, op2, "pow") | |
| 950 | − if tm then | |
| 951 | − -- call the method with both operands and an extra | |
| 952 | − -- argument with the event name | |
| 953 | − return tm(op1, op2, "pow") | |
| 954 | − else -- no tag method available: default behavior | |
| 955 | − error("unexpected type at arithmetic operation") | |
| 956 | − end | |
| 957 | − end | |
| 1179 | + function pow_event (op1, op2) | |
| 1180 | + local tm = getbinmethod(op1, op2, "pow") | |
| 1181 | + if tm then | |
| 1182 | + -- call the method with both operands and an extra | |
| 1183 | + -- argument with the event name | |
| 1184 | + return tm(op1, op2, "pow") | |
| 1185 | + else -- no tag method available: default behavior | |
| 1186 | + error("unexpected type at arithmetic operation") | |
| 1187 | + end | |
| 1188 | + end | |
| 958 | 1189 | </PRE> |
| 959 | 1190 | <P> |
| 960 | 1191 | <DT><B>``unm'':</B><DD><A NAME="unm event"></A> |
| 961 | −called when an unary <CODE>-</CODE> operation is applied to a non numerical operand. | |
| 962 | −<PRE> | |
| 963 | − function unm_event (op) | |
| 964 | − local o = tonumber(op) | |
| 965 | − if o then -- operand is numeric | |
| 966 | − return -o -- '-' here is the primitive 'unm' | |
| 967 | − else -- the operand is not numeric. | |
| 968 | − -- Try to get a tag method from the operand; | |
| 969 | − -- if it does not have one, try a "global" one (tag 0) | |
| 970 | − local tm = gettagmethod(tag(op), "unm") or | |
| 971 | − gettagmethod(0, "unm") | |
| 972 | − if tm then | |
| 973 | − -- call the method with the operand, nil, and an extra | |
| 974 | − -- argument with the event name | |
| 975 | − return tm(op, nil, "unm") | |
| 976 | − else -- no tag method available: default behavior | |
| 977 | − error("unexpected type at arithmetic operation") | |
| 978 | − end | |
| 979 | − end | |
| 980 | − end | |
| 1192 | +called when a unary <CODE>-</CODE> operation is applied to a non-numerical operand. | |
| 1193 | +<PRE> | |
| 1194 | + function unm_event (op) | |
| 1195 | + local o = tonumber(op) | |
| 1196 | + if o then -- operand is numeric | |
| 1197 | + return -o -- '-' here is the primitive 'unm' | |
| 1198 | + else -- the operand is not numeric. | |
| 1199 | + -- Try to get a tag method from the operand; | |
| 1200 | + -- if it does not have one, try a "global" one (tag 0) | |
| 1201 | + local tm = gettagmethod(tag(op), "unm") or | |
| 1202 | + gettagmethod(0, "unm") | |
| 1203 | + if tm then | |
| 1204 | + -- call the method with the operand, nil, and an extra | |
| 1205 | + -- argument with the event name | |
| 1206 | + return tm(op, nil, "unm") | |
| 1207 | + else -- no tag method available: default behavior | |
| 1208 | + error("unexpected type at arithmetic operation") | |
| 1209 | + end | |
| 1210 | + end | |
| 1211 | + end | |
| 981 | 1212 | </PRE> |
| 982 | 1213 | <P> |
| 983 | 1214 | <DT><B>``lt'':</B><DD><A NAME="lt event"></A> |
| 984 | −called when a <CODE><</CODE> operation is applied to non numerical | |
| 985 | −or non string operands. | |
| 986 | −<PRE> | |
| 987 | − function lt_event (op1, op2) | |
| 988 | − if type(op1) == "number" and type(op2) == "number" then | |
| 989 | − return op1 < op2 -- numeric comparison | |
| 990 | − elseif type(op1) == "string" and type(op2) == "string" then | |
| 991 | − return op1 < op2 -- lexicographic comparison | |
| 992 | − else | |
| 993 | − local tm = getbinmethod(op1, op2, "lt") | |
| 994 | − if tm then | |
| 995 | − return tm(op1, op2, "lt") | |
| 996 | − else | |
| 997 | − error("unexpected type at comparison"); | |
| 998 | − end | |
| 999 | − end | |
| 1000 | − end | |
| 1001 | −</PRE> | |
| 1002 | −<P> | |
| 1003 | −<DT><B>``gt'':</B><DD><A NAME="gt event"></A> | |
| 1004 | −called when a <CODE>></CODE> operation is applied to non numerical | |
| 1005 | −or non string operands. | |
| 1006 | −Behavior similar to the <CODE>"lt"</CODE> event. | |
| 1007 | −<P> | |
| 1008 | −<DT><B>``le'':</B><DD><A NAME="le event"></A> | |
| 1009 | −called when a <CODE><=</CODE> operation is applied to non numerical | |
| 1010 | −or non string operands. | |
| 1011 | −Behavior similar to the <CODE>"lt"</CODE> event. | |
| 1012 | −<P> | |
| 1013 | −<DT><B>``ge'':</B><DD><A NAME="ge event"></A> | |
| 1014 | −called when a <CODE>>=</CODE> operation is applied to non numerical | |
| 1015 | −or non string operands. | |
| 1016 | −Behavior similar to the <CODE>"lt"</CODE> event. | |
| 1215 | +called when an order operation is applied to non-numerical | |
| 1216 | +or non-string operands. | |
| 1217 | +It corresponds to the <CODE><</CODE> operator. | |
| 1218 | +<PRE> | |
| 1219 | + function lt_event (op1, op2) | |
| 1220 | + if type(op1) == "number" and type(op2) == "number" then | |
| 1221 | + return op1 < op2 -- numeric comparison | |
| 1222 | + elseif type(op1) == "string" and type(op2) == "string" then | |
| 1223 | + return op1 < op2 -- lexicographic comparison | |
| 1224 | + else | |
| 1225 | + local tm = getbinmethod(op1, op2, "lt") | |
| 1226 | + if tm then | |
| 1227 | + return tm(op1, op2, "lt") | |
| 1228 | + else | |
| 1229 | + error("unexpected type at comparison"); | |
| 1230 | + end | |
| 1231 | + end | |
| 1232 | + end | |
| 1233 | +</PRE> | |
| 1234 | +The other order operators use this tag method according to the | |
| 1235 | +usual equivalences: | |
| 1236 | +<PRE> | |
| 1237 | + a>b <=> b<a | |
| 1238 | + a<=b <=> not (b<a) | |
| 1239 | + a>=b <=> not (a<b) | |
| 1240 | +</PRE> | |
| 1017 | 1241 | <P> |
| 1018 | 1242 | <DT><B>``concat'':</B><DD><A NAME="concatenation event"></A> |
| 1019 | −called when a concatenation is applied to non string operands. | |
| 1020 | −<PRE> | |
| 1021 | − function concat_event (op1, op2) | |
| 1022 | − if (type(op1) == "string" or type(op1) == "number") and | |
| 1023 | − (type(op2) == "string" or type(op2) == "number") then | |
| 1024 | − return op1..op2 -- primitive string concatenation | |
| 1025 | − else | |
| 1026 | − local tm = getbinmethod(op1, op2, "concat") | |
| 1027 | − if tm then | |
| 1028 | − return tm(op1, op2, "concat") | |
| 1029 | − else | |
| 1030 | − error("unexpected type for concatenation") | |
| 1031 | − end | |
| 1032 | − end | |
| 1033 | − end | |
| 1243 | +called when a concatenation is applied to non-string operands. | |
| 1244 | +<PRE> | |
| 1245 | + function concat_event (op1, op2) | |
| 1246 | + if (type(op1) == "string" or type(op1) == "number") and | |
| 1247 | + (type(op2) == "string" or type(op2) == "number") then | |
| 1248 | + return op1..op2 -- primitive string concatenation | |
| 1249 | + else | |
| 1250 | + local tm = getbinmethod(op1, op2, "concat") | |
| 1251 | + if tm then | |
| 1252 | + return tm(op1, op2, "concat") | |
| 1253 | + else | |
| 1254 | + error("unexpected type for concatenation") | |
| 1255 | + end | |
| 1256 | + end | |
| 1257 | + end | |
| 1034 | 1258 | </PRE> |
| 1035 | 1259 | <P> |
| 1036 | 1260 | <DT><B>``index'':</B><DD><A NAME="index event"></A> |
| 1037 | 1261 | called when Lua tries to retrieve the value of an index |
| 1038 | 1262 | not present in a table. |
| 1039 | −See event <CODE>"gettable"</CODE> for its semantics. | |
| 1263 | +See the ``gettable'' event for its semantics. | |
| 1040 | 1264 | <P> |
| 1041 | 1265 | <DT><B>``getglobal'':</B><DD><A NAME="getglobal event"></A> |
| 1042 | 1266 | called whenever Lua needs the value of a global variable. |
| 1043 | 1267 | This method can only be set for <B>nil</B> and for tags |
| 1044 | 1268 | created by <CODE>newtag</CODE>. |
| 1045 | −<PRE> | |
| 1046 | − function getglobal (varname) | |
| 1047 | − local value = rawgetglobal(varname) | |
| 1048 | − local tm = gettagmethod(tag(value), "getglobal") | |
| 1049 | − if not tm then | |
| 1050 | − return value | |
| 1051 | − else | |
| 1052 | − return tm(varname, value) | |
| 1053 | − end | |
| 1054 | − end | |
| 1055 | −</PRE> | |
| 1056 | −The function <CODE>getglobal</CODE> is pre-defined in Lua (see Section <A HREF="#predefined">6.1</A>). | |
| 1269 | +Note that | |
| 1270 | +the tag is that of the <EM>current value</EM> of the global variable. | |
| 1271 | +<PRE> | |
| 1272 | + function getglobal (varname) | |
| 1273 | + -- access the table of globals | |
| 1274 | + local value = rawget(globals(), varname) | |
| 1275 | + local tm = gettagmethod(tag(value), "getglobal") | |
| 1276 | + if not tm then | |
| 1277 | + return value | |
| 1278 | + else | |
| 1279 | + return tm(varname, value) | |
| 1280 | + end | |
| 1281 | + end | |
| 1282 | +</PRE> | |
| 1283 | +The function <CODE>getglobal</CODE> is defined in the basic library (see Section <A HREF="#predefined">6.1</A>). | |
| 1057 | 1284 | <P> |
| 1058 | 1285 | <DT><B>``setglobal'':</B><DD><A NAME="setglobal event"></A> |
| 1059 | 1286 | called whenever Lua assigns to a global variable. |
| 1060 | 1287 | This method cannot be set for numbers, strings, and tables and |
| 1061 | −userdata with default tags. | |
| 1288 | +userdata with the default tag. | |
| 1062 | 1289 | <PRE> |
| 1063 | − function setglobal (varname, newvalue) | |
| 1064 | − local oldvalue = rawgetglobal(varname) | |
| 1065 | − local tm = gettagmethod(tag(oldvalue), "setglobal") | |
| 1066 | − if not tm then | |
| 1067 | − return rawsetglobal(varname, newvalue) | |
| 1068 | − else | |
| 1069 | − return tm(varname, oldvalue, newvalue) | |
| 1070 | − end | |
| 1071 | − end | |
| 1290 | + function setglobal (varname, newvalue) | |
| 1291 | + local oldvalue = rawget(globals(), varname) | |
| 1292 | + local tm = gettagmethod(tag(oldvalue), "setglobal") | |
| 1293 | + if not tm then | |
| 1294 | + rawset(globals(), varname, newvalue) | |
| 1295 | + else | |
| 1296 | + tm(varname, oldvalue, newvalue) | |
| 1297 | + end | |
| 1298 | + end | |
| 1072 | 1299 | </PRE> |
| 1073 | −Notice: the function <CODE>setglobal</CODE> is pre-defined in Lua (see Section <A HREF="#predefined">6.1</A>). | |
| 1300 | +The function <CODE>setglobal</CODE> is defined in the basic library (see Section <A HREF="#predefined">6.1</A>). | |
| 1074 | 1301 | <P> |
| 1075 | 1302 | <DT><B>``gettable'':</B><DD><A NAME="gettable event"></A> |
| 1076 | 1303 | called whenever Lua accesses an indexed variable. |
| 1077 | −This method cannot be set for tables with default tag. | |
| 1078 | −<PRE> | |
| 1079 | − function gettable_event (table, index) | |
| 1080 | − local tm = gettagmethod(tag(table), "gettable") | |
| 1081 | − if tm then | |
| 1082 | − return tm(table, index) | |
| 1083 | − elseif type(table) ~= "table" then | |
| 1084 | − error("indexed expression not a table"); | |
| 1085 | − else | |
| 1086 | − local v = rawgettable(table, index) | |
| 1087 | − tm = gettagmethod(tag(table), "index") | |
| 1088 | − if v == nil and tm then | |
| 1089 | − return tm(table, index) | |
| 1090 | − else | |
| 1091 | − return v | |
| 1092 | − end | |
| 1093 | − end | |
| 1094 | − end | |
| 1304 | +This method cannot be set for tables with the default tag. | |
| 1305 | +<PRE> | |
| 1306 | + function gettable_event (table, index) | |
| 1307 | + local tm = gettagmethod(tag(table), "gettable") | |
| 1308 | + if tm then | |
| 1309 | + return tm(table, index) | |
| 1310 | + elseif type(table) ~= "table" then | |
| 1311 | + error("indexed expression not a table"); | |
| 1312 | + else | |
| 1313 | + local v = rawget(table, index) | |
| 1314 | + tm = gettagmethod(tag(table), "index") | |
| 1315 | + if v == nil and tm then | |
| 1316 | + return tm(table, index) | |
| 1317 | + else | |
| 1318 | + return v | |
| 1319 | + end | |
| 1320 | + end | |
| 1321 | + end | |
| 1095 | 1322 | </PRE> |
| 1096 | 1323 | <P> |
| 1097 | 1324 | <DT><B>``settable'':</B><DD><A NAME="settable event"></A> |
| 1098 | 1325 | called when Lua assigns to an indexed variable. |
| 1099 | −This method cannot be set for tables with default tag. | |
| 1326 | +This method cannot be set for tables with the default tag. | |
| 1100 | 1327 | <PRE> |
| 1101 | − function settable_event (table, index, value) | |
| 1102 | − local tm = gettagmethod(tag(table), "settable") | |
| 1103 | − if tm then | |
| 1104 | − tm(table, index, value) | |
| 1105 | − elseif type(table) ~= "table" then | |
| 1106 | − error("indexed expression not a table") | |
| 1107 | − else | |
| 1108 | − rawsettable(table, index, value) | |
| 1109 | − end | |
| 1110 | − end | |
| 1328 | + function settable_event (table, index, value) | |
| 1329 | + local tm = gettagmethod(tag(table), "settable") | |
| 1330 | + if tm then | |
| 1331 | + tm(table, index, value) | |
| 1332 | + elseif type(table) ~= "table" then | |
| 1333 | + error("indexed expression not a table") | |
| 1334 | + else | |
| 1335 | + rawset(table, index, value) | |
| 1336 | + end | |
| 1337 | + end | |
| 1111 | 1338 | </PRE> |
| 1112 | 1339 | <P> |
| 1113 | 1340 | <DT><B>``function'':</B><DD><A NAME="function event"></A> |
| 1114 | −called when Lua tries to call a non function value. | |
| 1115 | −<PRE> | |
| 1116 | − function function_event (func, ...) | |
| 1117 | − if type(func) == "function" then | |
| 1118 | − return call(func, arg) | |
| 1119 | − else | |
| 1120 | − local tm = gettagmethod(tag(func), "function") | |
| 1121 | − if tm then | |
| 1122 | − local i = arg.n | |
| 1123 | − while i > 0 do | |
| 1124 | − arg[i+1] = arg[i] | |
| 1125 | − i = i-1 | |
| 1126 | − end | |
| 1127 | − arg.n = arg.n+1 | |
| 1128 | − arg[1] = func | |
| 1129 | − return call(tm, arg) | |
| 1130 | − else | |
| 1131 | − error("call expression not a function") | |
| 1132 | − end | |
| 1133 | − end | |
| 1134 | − end | |
| 1341 | +called when Lua tries to call a non-function value. | |
| 1342 | +<PRE> | |
| 1343 | + function function_event (func, ...) | |
| 1344 | + if type(func) == "function" then | |
| 1345 | + return call(func, arg) | |
| 1346 | + else | |
| 1347 | + local tm = gettagmethod(tag(func), "function") | |
| 1348 | + if tm then | |
| 1349 | + for i=arg.n,1,-1 do | |
| 1350 | + arg[i+1] = arg[i] | |
| 1351 | + end | |
| 1352 | + arg.n = arg.n+1 | |
| 1353 | + arg[1] = func | |
| 1354 | + return call(tm, arg) | |
| 1355 | + else | |
| 1356 | + error("call expression not a function") | |
| 1357 | + end | |
| 1358 | + end | |
| 1359 | + end | |
| 1135 | 1360 | </PRE> |
| 1136 | 1361 | <P> |
| 1137 | 1362 | <DT><B>``gc'':</B><DD><A NAME="gc event"></A> |
| 1138 | −called when Lua is ``garbage collecting'' an object. | |
| 1139 | −This method cannot be set for strings, numbers, functions, | |
| 1140 | −and userdata with default tag. | |
| 1141 | −For each object to be collected, | |
| 1363 | +called when Lua is ``garbage collecting'' a userdata. | |
| 1364 | +This tag method can be set only from C, | |
| 1365 | +and cannot be set for a userdata with the default tag. | |
| 1366 | +For each userdata to be collected, | |
| 1142 | 1367 | Lua does the equivalent of the following function: |
| 1143 | 1368 | <PRE> |
| 1144 | − function gc_event (obj) | |
| 1145 | − local tm = gettagmethod(tag(obj), "gc") | |
| 1146 | − if tm then | |
| 1147 | − tm(obj) | |
| 1148 | − end | |
| 1149 | − end | |
| 1150 | −</PRE> | |
| 1151 | −Moreover, at the end of a garbage collection cycle, | |
| 1369 | + function gc_event (obj) | |
| 1370 | + local tm = gettagmethod(tag(obj), "gc") | |
| 1371 | + if tm then | |
| 1372 | + tm(obj) | |
| 1373 | + end | |
| 1374 | + end | |
| 1375 | +</PRE> | |
| 1376 | +In a garbage-collection cycle, | |
| 1377 | +the tag methods for userdata are called in <EM>reverse</EM> order of tag creation, | |
| 1378 | +that is, the first tag methods to be called are those associated | |
| 1379 | +with the last tag created in the program. | |
| 1380 | +Moreover, at the end of the cycle, | |
| 1152 | 1381 | Lua does the equivalent of the call <CODE>gc_event(nil)</CODE>. |
| 1153 | 1382 | <P> |
| 1154 | 1383 | </DL> |
| 1155 | 1384 | <P> |
| 1156 | 1385 | <P> |
| 1157 | 1386 | <P> |
| 1158 | −<A NAME="error"></A> | |
| 1159 | −<A NAME="4.9"></A> | |
| 1160 | −<H2>4.9 - Error Handling</H2> | |
| 1161 | −<P> | |
| 1162 | −Because Lua is an extension language, | |
| 1163 | −all Lua actions start from C code in the host program | |
| 1164 | −calling a function from the Lua library. | |
| 1165 | −Whenever an error occurs during Lua compilation or execution, | |
| 1166 | −function <CODE>_ERRORMESSAGE</CODE> is called <A NAME="_ERRORMESSAGE"></A> | |
| 1167 | −(provided it is different from <B>nil</B>), | |
| 1168 | −and then the corresponding function from the library | |
| 1169 | −(<CODE>lua_dofile</CODE>, <CODE>lua_dostring</CODE>, | |
| 1170 | −<CODE>lua_dobuffer</CODE>, or <CODE>lua_callfunction</CODE>) | |
| 1171 | −is terminated, returning an error condition. | |
| 1172 | −<P> | |
| 1173 | −The only argument to <CODE>_ERRORMESSAGE</CODE> is a string | |
| 1174 | −describing the error. | |
| 1175 | −The default definition for this function calls <CODE>_ALERT</CODE>, | |
| 1176 | −which prints the message to <CODE>stderr</CODE> (see Section <A HREF="#alert">6.1</A>). | |
| 1177 | −The standard I/O library redefines <CODE>_ERRORMESSAGE</CODE>, | |
| 1178 | −and uses the debug facilities (see Section <A HREF="#debugI">7</A>) | |
| 1179 | −to print some extra information, | |
| 1180 | −such as the call stack. | |
| 1181 | −<P> | |
| 1182 | −To provide more information about errors, | |
| 1183 | −Lua programs should include the compilation pragma <CODE>$debug</CODE>. | |
| 1184 | −<A NAME="pragma"></A> | |
| 1185 | −<A NAME="debug pragma"></A> | |
| 1186 | −When an error occurs in a chunk compiled with this option, | |
| 1187 | −the I/O error routine is able to print the number of the | |
| 1188 | −lines where the calls (and the error) were made. | |
| 1189 | −<P> | |
| 1190 | −Lua code can explicitly generate an error by calling the built-in | |
| 1191 | −function <CODE>error</CODE> (see Section <A HREF="#pdf-error">6.1</A>). | |
| 1192 | −Lua code can ``catch'' an error using the built-in function | |
| 1193 | −<CODE>call</CODE> (see Section <A HREF="#pdf-call">6.1</A>). | |
| 1194 | −<P> | |
| 1195 | −<P> | |
| 1196 | 1387 | <P> |
| 1197 | 1388 | <!-- ====================================================================== --> |
| 1198 | 1389 | <HR> |
| 1199 | 1390 | <A NAME="5."></A> |
| 1200 | 1391 | <H1>5 - The Application Program Interface</H1> |
| 1201 | −<P> | |
| 1392 | +<A NAME="C API"></A> | |
| 1202 | 1393 | This section describes the API for Lua, that is, |
| 1203 | −the set of C functions available to the host program to communicate | |
| 1204 | −with the Lua library. | |
| 1205 | −The API functions can be classified in the following categories: | |
| 1206 | −<OL> | |
| 1207 | −<LI>managing states; | |
| 1208 | −<LI>exchanging values between C and Lua; | |
| 1209 | −<LI>executing Lua code; | |
| 1210 | −<LI>manipulating (reading and writing) Lua objects; | |
| 1211 | −<LI>calling Lua functions; | |
| 1212 | −<LI>C functions to be called by Lua; | |
| 1213 | −<LI>manipulating references to Lua Objects. | |
| 1214 | −</OL> | |
| 1394 | +the set of C functions available to the host program to communicate | |
| 1395 | +with Lua. | |
| 1215 | 1396 | All API functions and related types and constants |
| 1216 | 1397 | are declared in the header file <CODE>lua.h</CODE>. |
| 1217 | 1398 | <P> |
| 1399 | +Even when we use the term ``function'', | |
| 1400 | +any facility in the API may be provided as a <EM>macro</EM> instead. | |
| 1401 | +All such macros use each of its arguments exactly once, | |
| 1402 | +and so do not generate hidden side-effects. | |
| 1403 | +<P> | |
| 1404 | +<P> | |
| 1218 | 1405 | <A NAME="mangstate"></A> |
| 1219 | 1406 | <A NAME="5.1"></A> |
| 1220 | −<H2>5.1 - Managing States</H2> | |
| 1407 | +<H2>5.1 - States</H2> | |
| 1408 | +<P> | |
| 1409 | +The Lua library is fully reentrant: | |
| 1410 | +it does not have any global variables. | |
| 1411 | +<A NAME="state"></A> | |
| 1221 | 1412 | The whole state of the Lua interpreter |
| 1222 | −(global variables, stack, tag methods, etc) | |
| 1223 | −is stored in a dynamic structure pointed by<A NAME="lua_state"></A> | |
| 1224 | −<PRE> | |
| 1225 | −typedef struct lua_State lua_State; | |
| 1226 | −extern lua_State *lua_state; | |
| 1227 | −</PRE> | |
| 1228 | −The variable <CODE>lua_state</CODE> is the only C global variable in | |
| 1229 | −the Lua library. | |
| 1413 | +(global variables, stack, tag methods, etc.) | |
| 1414 | +is stored in a dynamically allocated structure of type <CODE>lua_State</CODE>; <A NAME="lua_State"></A> | |
| 1415 | +this state must be passed as the first argument to | |
| 1416 | +every function in the library (except <CODE>lua_open</CODE> below). | |
| 1230 | 1417 | <P> |
| 1231 | 1418 | Before calling any API function, |
| 1232 | −this state must be initialized. | |
| 1233 | −This is done by calling<A NAME="lua_open"></A> | |
| 1419 | +you must create a state by calling | |
| 1420 | +<A NAME="lua_open"></A> | |
| 1234 | 1421 | <PRE> |
| 1235 | −void lua_open (void); | |
| 1422 | + lua_State *lua_open (int stacksize); | |
| 1236 | 1423 | </PRE> |
| 1237 | −This function allocates and initializes some internal structures, | |
| 1238 | −and defines all pre-defined functions of Lua. | |
| 1239 | −If <CODE>lua_state</CODE> is already different from <CODE>NULL</CODE>, | |
| 1240 | −<CODE>lua_open</CODE> has no effect; | |
| 1241 | −therefore, it is safe to call this function multiple times. | |
| 1242 | −All standard libraries call <CODE>lua_open</CODE> when they are opened. | |
| 1424 | +The sole argument to this function is the stack size for the interpreter. | |
| 1425 | +(Each function call needs one stack position for each argument, local variable, | |
| 1426 | +and temporary value, plus one position for book-keeping. | |
| 1427 | +The stack must also have some 20 extra positions available. | |
| 1428 | +For very small implementations, without recursive functions, | |
| 1429 | +a stack size of 100 should be enough.) | |
| 1430 | +If <CODE>stacksize</CODE> is zero, | |
| 1431 | +then a default size of 1024 is used. | |
| 1243 | 1432 | <P> |
| 1244 | −Function <CODE>lua_setstate</CODE> is used to change the current state | |
| 1245 | −of Lua:<A NAME="lua_setstate"></A> | |
| 1433 | +To release a state created with <CODE>lua_open</CODE>, call | |
| 1434 | +<A NAME="lua_close"></A> | |
| 1246 | 1435 | <PRE> |
| 1247 | −lua_State *lua_setstate (lua_State *st); | |
| 1436 | + void lua_close (lua_State *L); | |
| 1248 | 1437 | </PRE> |
| 1249 | −It sets <CODE>lua_state</CODE> to <CODE>st</CODE> and returns the old state. | |
| 1438 | +This function destroys all objects in the given Lua environment | |
| 1439 | +(calling the corresponding garbage-collection tag methods, if any) | |
| 1440 | +and frees all dynamic memory used by that state. | |
| 1441 | +Usually, you do not need to call this function, | |
| 1442 | +because all resources are naturally released when your program ends. | |
| 1443 | +On the other hand, | |
| 1444 | +long-running programs - | |
| 1445 | +like a daemon or a web server - | |
| 1446 | +might need to release states as soon as they are not needed, | |
| 1447 | +to avoid growing too big. | |
| 1448 | +<P> | |
| 1449 | +With the exception of <CODE>lua_open</CODE>, | |
| 1450 | +all functions in the Lua API need a state as their first argument. | |
| 1250 | 1451 | <P> |
| 1251 | −Multiple, independent states may be created. | |
| 1252 | −For that, you must set <CODE>lua_state</CODE> back to <CODE>NULL</CODE> before | |
| 1253 | −calling <CODE>lua_open</CODE>. | |
| 1254 | −An easy way to do that is defining an auxiliary function: | |
| 1255 | −<PRE> | |
| 1256 | − lua_State *lua_newstate (void) { | |
| 1257 | − lua_State *old = lua_setstate(NULL); | |
| 1258 | − lua_open(); | |
| 1259 | − return lua_setstate(old); | |
| 1260 | − } | |
| 1261 | −</PRE> | |
| 1262 | −This function creates a new state without changing the current state | |
| 1263 | −of the interpreter. | |
| 1264 | −Note that any new state is created with all predefined functions, | |
| 1265 | −but any additional library (such as the standard libraries) must be | |
| 1266 | −explicitly open in the new state, if needed. | |
| 1267 | −<P> | |
| 1268 | −If necessary, a state may be released by calling<A NAME="lua_close"></A> | |
| 1269 | −<PRE> | |
| 1270 | −void lua_close (void); | |
| 1271 | −</PRE> | |
| 1272 | −This function destroys all objects in the current Lua environment | |
| 1273 | −(calling the correspondent garbage collector tag methods), | |
| 1274 | −frees all dynamic memory used by the state, | |
| 1275 | −and then sets <CODE>lua_state</CODE> to <CODE>NULL</CODE>. | |
| 1276 | −Usually, there is no need to call this function, | |
| 1277 | −since these resources are naturally released when the program ends. | |
| 1278 | −If <CODE>lua_state</CODE> is already <CODE>NULL</CODE>, | |
| 1279 | −<CODE>lua_close</CODE> has no effect. | |
| 1280 | −<P> | |
| 1281 | −If you are using multiple states, | |
| 1282 | −you may find useful to define the following function, | |
| 1283 | −which releases a given state: | |
| 1284 | −<PRE> | |
| 1285 | − void lua_freestate (lua_State *st) { | |
| 1286 | − lua_State *old = lua_setstate(st); | |
| 1287 | − lua_close(); | |
| 1288 | − if (old != st) lua_setstate(old); | |
| 1289 | − } | |
| 1290 | −</PRE> | |
| 1291 | 1452 | <P> |
| 1292 | −<A NAME="valuesCLua"></A> | |
| 1293 | 1453 | <A NAME="5.2"></A> |
| 1294 | −<H2>5.2 - Exchanging Values between C and Lua</H2> | |
| 1295 | −Because Lua has no static type system, | |
| 1296 | −all values passed between Lua and C have type | |
| 1297 | −<CODE>lua_Object</CODE><A NAME="lua_Object"></A>, | |
| 1298 | −which works like an abstract type in C that can hold any Lua value. | |
| 1299 | −Values of type <CODE>lua_Object</CODE> have no meaning outside Lua; | |
| 1300 | −for instance, | |
| 1301 | −the comparison of two <CODE>lua_Object's</CODE> is undefined. | |
| 1302 | −<P> | |
| 1303 | −To check the type of a <CODE>lua_Object</CODE>, | |
| 1454 | +<H2>5.2 - The Stack and Indices</H2> | |
| 1455 | +<P> | |
| 1456 | +Lua uses a <EM>stack</EM> to pass values to and from C. | |
| 1457 | +Each element in this stack represents a Lua value | |
| 1458 | +(nil, number, string, etc.). | |
| 1459 | +<P> | |
| 1460 | +For convenience, | |
| 1461 | +most query operations in the API do not follow a strict stack discipline. | |
| 1462 | +Instead, they can refer to any element in the stack by using an <EM>index</EM>: | |
| 1463 | +A positive index represents an <EM>absolute</EM> stack position | |
| 1464 | +(starting at 1, not 0 as in C); | |
| 1465 | +a negative index represents an <EM>offset</EM> from the top of the stack. | |
| 1466 | +More specifically, if the stack has <EM>n</EM> elements, | |
| 1467 | +index 1 represents the first element | |
| 1468 | +(that is, the first element pushed onto the stack), | |
| 1469 | +and | |
| 1470 | +index <EM>n</EM> represents the last element; | |
| 1471 | +index <I>-1</I> also represents the last element | |
| 1472 | +(that is, the element at the top), | |
| 1473 | +and index <I>-n</I> represents the first element. | |
| 1474 | +We say that an index is <EM>valid</EM> | |
| 1475 | +if it lays between 1 and the stack top | |
| 1476 | +(that is, if <CODE>1 <= abs(index) <= top</CODE>). | |
| 1477 | +<A NAME="stack index"></A> <A NAME="valid index"></A> | |
| 1478 | +<P> | |
| 1479 | +At any time, you can get the index of the top element by calling | |
| 1480 | +<A NAME="lua_gettop"></A> | |
| 1481 | +<PRE> | |
| 1482 | + int lua_gettop (lua_State *L); | |
| 1483 | +</PRE> | |
| 1484 | +Because indices start at 1, | |
| 1485 | +the result of <CODE>lua_gettop</CODE> is equal to the number of elements in the stack | |
| 1486 | +(and so 0 means an empty stack). | |
| 1487 | +<P> | |
| 1488 | +When you interact with Lua API, | |
| 1489 | +<EM>you are responsible for controlling stack overflow</EM>. | |
| 1490 | +The function <A NAME="lua_stackspace"></A> | |
| 1491 | +<PRE> | |
| 1492 | + int lua_stackspace (lua_State *L); | |
| 1493 | +</PRE> | |
| 1494 | +returns the number of stack positions still available. | |
| 1495 | +Whenever Lua calls C, <A NAME="LUA_MINSTACK"></A> | |
| 1496 | +it ensures that | |
| 1497 | +at least <CODE>LUA_MINSTACK</CODE> positions are still available. | |
| 1498 | +<CODE>LUA_MINSTACK</CODE> is defined in <CODE>lua.h</CODE> and is at least 16, | |
| 1499 | +and so you have to worry about stack space only | |
| 1500 | +when your code has loops pushing elements onto the stack. | |
| 1501 | +<P> | |
| 1502 | +Most query functions accept as indices any value inside the | |
| 1503 | +available stack space. | |
| 1504 | +Such indices are called <EM>acceptable indices</EM>. | |
| 1505 | +More formally, we can define an <A NAME="acceptable index"><EM>acceptable index</EM></A> | |
| 1506 | +as | |
| 1507 | +<PRE> | |
| 1508 | + (index < 0 && abs(index) <= top) || (index > 0 && index <= top + stackspace) | |
| 1509 | +</PRE> | |
| 1510 | +Note that 0 is not an acceptable index. | |
| 1511 | +<P> | |
| 1512 | +<A NAME="5.3"></A> | |
| 1513 | +<H2>5.3 - Stack Manipulation</H2> | |
| 1514 | +The API offers the following functions for basic stack manipulation: | |
| 1515 | +<A NAME="lua_settop"></A><A NAME="lua_pushvalue"></A> | |
| 1516 | +<A NAME="lua_remove"></A><A NAME="lua_insert"></A> | |
| 1517 | +<PRE> | |
| 1518 | + void lua_settop (lua_State *L, int index); | |
| 1519 | + void lua_pushvalue (lua_State *L, int index); | |
| 1520 | + void lua_remove (lua_State *L, int index); | |
| 1521 | + void lua_insert (lua_State *L, int index); | |
| 1522 | +</PRE> | |
| 1523 | +<P> | |
| 1524 | +<CODE>lua_settop</CODE> accepts any acceptable index, | |
| 1525 | +or 0, | |
| 1526 | +and sets the stack top to that index. | |
| 1527 | +If the new top is larger than the old one, | |
| 1528 | +then the new elements are filled with <B>nil</B>. | |
| 1529 | +If <CODE>index</CODE> is 0, then all stack elements are removed. | |
| 1530 | +A useful macro defined in the API is | |
| 1531 | +<PRE> | |
| 1532 | + #define lua_pop(L,n) lua_settop(L, -(n)-1) | |
| 1533 | +</PRE> | |
| 1534 | +which pops <CODE>n</CODE> elements from the stack. | |
| 1535 | +<P> | |
| 1536 | +<CODE>lua_pushvalue</CODE> pushes onto the stack a <EM>copy</EM> of the element | |
| 1537 | +at the given index. | |
| 1538 | +<CODE>lua_remove</CODE> removes the element at the given position, | |
| 1539 | +shifting down the elements on top of that position to fill in the gap. | |
| 1540 | +<CODE>lua_insert</CODE> moves the top element into the given position, | |
| 1541 | +shifting up the elements on top of that position to open space. | |
| 1542 | +These functions accept only valid indices. | |
| 1543 | +As an example, if the stack starts as <CODE>10 20 30 40 50</CODE> | |
| 1544 | +(from bottom to top), | |
| 1545 | +then | |
| 1546 | +<PRE> | |
| 1547 | + lua_pushvalue(L, 3) --> 10 20 30 40 50 30 | |
| 1548 | + lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30 | |
| 1549 | + lua_remove(L, -3) --> 10 20 30 40 30 30 | |
| 1550 | + lua_remove(L, 6) --> 10 20 30 40 30 | |
| 1551 | + lua_insert(L, 1) --> 30 10 20 30 40 | |
| 1552 | + lua_insert(L, -1) --> 30 10 20 30 40 (no effect) | |
| 1553 | + lua_settop(L, -3) --> 30 10 20 | |
| 1554 | + lua_settop(L, 6) --> 30 10 20 nil nil nil | |
| 1555 | +</PRE> | |
| 1556 | +<P> | |
| 1557 | +<P> | |
| 1558 | +<A NAME="5.4"></A> | |
| 1559 | +<H2>5.4 - Querying the Stack</H2> | |
| 1560 | +<P> | |
| 1561 | +To check the type of a stack element, | |
| 1304 | 1562 | the following functions are available: |
| 1563 | +<A NAME="lua_type"></A><A NAME="lua_tag"></A> | |
| 1305 | 1564 | <A NAME="lua_isnil"></A><A NAME="lua_isnumber"></A><A NAME="lua_isstring"></A> |
| 1306 | −<A NAME="lua_istable"></A><A NAME="lua_iscfunction"></A><A NAME="lua_isuserdata"></A> | |
| 1307 | −<A NAME="lua_isfunction"></A> | |
| 1308 | −<PRE> | |
| 1309 | −int lua_isnil (lua_Object object); | |
| 1310 | −int lua_isnumber (lua_Object object); | |
| 1311 | −int lua_isstring (lua_Object object); | |
| 1312 | −int lua_istable (lua_Object object); | |
| 1313 | −int lua_isfunction (lua_Object object); | |
| 1314 | −int lua_iscfunction (lua_Object object); | |
| 1315 | −int lua_isuserdata (lua_Object object); | |
| 1316 | −</PRE> | |
| 1317 | −These functions return 1 if the object is compatible with the given type, | |
| 1318 | −and 0 otherwise. | |
| 1319 | −The function <CODE>lua_isnumber</CODE> accepts numbers and numerical strings, | |
| 1320 | −whereas | |
| 1321 | −<CODE>lua_isstring</CODE> accepts strings and numbers (see Section <A HREF="#coercion">4.3</A>), | |
| 1322 | −and <CODE>lua_isfunction</CODE> accepts Lua functions and C functions. | |
| 1323 | −<P> | |
| 1324 | −To get the tag of a <CODE>lua_Object</CODE>, | |
| 1325 | −the following function is available: | |
| 1326 | −<A NAME="lua_tag"></A> | |
| 1327 | −<PRE> | |
| 1328 | −int lua_tag (lua_Object object); | |
| 1329 | −</PRE> | |
| 1330 | −<P> | |
| 1331 | −To translate a value from type <CODE>lua_Object</CODE> to a specific C type, | |
| 1332 | −the programmer can use: | |
| 1333 | −<A NAME="lua_getnumber"></A><A NAME="lua_getstring"></A><A NAME="lua_strlen"></A> | |
| 1334 | −<A NAME="lua_getcfunction"></A><A NAME="lua_getuserdata"></A> | |
| 1335 | −<PRE> | |
| 1336 | −double lua_getnumber (lua_Object object); | |
| 1337 | −char *lua_getstring (lua_Object object); | |
| 1338 | −long lua_strlen (lua_Object object); | |
| 1339 | −lua_CFunction lua_getcfunction (lua_Object object); | |
| 1340 | −void *lua_getuserdata (lua_Object object); | |
| 1341 | −</PRE> | |
| 1342 | −<P> | |
| 1343 | −<CODE>lua_getnumber</CODE> converts a <CODE>lua_Object</CODE> to a floating-point number. | |
| 1344 | −This <CODE>lua_Object</CODE> must be a number or a string convertible to number | |
| 1345 | −(see Section <A HREF="#coercion">4.3</A>); otherwise, <CODE>lua_getnumber</CODE> returns 0. | |
| 1346 | −<P> | |
| 1347 | −<CODE>lua_getstring</CODE> converts a <CODE>lua_Object</CODE> to a string (<CODE>char*</CODE>). | |
| 1348 | −This <CODE>lua_Object</CODE> must be a string or a number; | |
| 1349 | −otherwise, the function returns 0 (the <CODE>NULL</CODE> pointer). | |
| 1350 | −This function does not create a new string, | |
| 1351 | −but returns a pointer to a string inside the Lua environment. | |
| 1352 | −Those strings always have a 0 after their last character (like in C), | |
| 1565 | +<A NAME="lua_istable"></A> | |
| 1566 | +<A NAME="lua_isfunction"></A><A NAME="lua_iscfunction"></A><A NAME="lua_isuserdata"></A> | |
| 1567 | +<PRE> | |
| 1568 | + int lua_type (lua_State *L, int index); | |
| 1569 | + int lua_tag (lua_State *L, int index); | |
| 1570 | + int lua_isnil (lua_State *L, int index); | |
| 1571 | + int lua_isnumber (lua_State *L, int index); | |
| 1572 | + int lua_isstring (lua_State *L, int index); | |
| 1573 | + int lua_istable (lua_State *L, int index); | |
| 1574 | + int lua_isfunction (lua_State *L, int index); | |
| 1575 | + int lua_iscfunction (lua_State *L, int index); | |
| 1576 | + int lua_isuserdata (lua_State *L, int index); | |
| 1577 | +</PRE> | |
| 1578 | +These functions can be called with any acceptable index. | |
| 1579 | +<P> | |
| 1580 | +<CODE>lua_type</CODE> returns one of the following constants, | |
| 1581 | +according to the type of the given object: | |
| 1582 | +<CODE>LUA_TNIL</CODE>, | |
| 1583 | +<CODE>LUA_TNUMBER</CODE>, | |
| 1584 | +<CODE>LUA_TSTRING</CODE>, | |
| 1585 | +<CODE>LUA_TTABLE</CODE>, | |
| 1586 | +<CODE>LUA_TFUNCTION</CODE>, | |
| 1587 | +<CODE>LUA_TUSERDATA</CODE>. | |
| 1588 | +If the index is non-valid | |
| 1589 | +(that is, if that stack position is ``empty''), | |
| 1590 | +then <CODE>lua_type</CODE> returns <CODE>LUA_TNONE</CODE>. | |
| 1591 | +These constants can be converted to strings with | |
| 1592 | +<A NAME="lua_typename"></A> | |
| 1593 | +<PRE> | |
| 1594 | + const char *lua_typename (lua_State *L, int t); | |
| 1595 | +</PRE> | |
| 1596 | +where <CODE>t</CODE> is a type returned by <CODE>lua_type</CODE>. | |
| 1597 | +The strings returned by <CODE>lua_typename</CODE> are | |
| 1598 | +<CODE>"nil"</CODE>, <CODE>"number"</CODE>, <CODE>"string"</CODE>, <CODE>"table"</CODE>, | |
| 1599 | +<CODE>"function"</CODE>, <CODE>"userdata"</CODE>, and <CODE>"no value"</CODE>, | |
| 1600 | +<P> | |
| 1601 | +<CODE>lua_tag</CODE> returns the tag of a value, | |
| 1602 | +or <CODE>LUA_NOTAG</CODE> for a non-valid index. | |
| 1603 | +<P> | |
| 1604 | +The <CODE>lua_is*</CODE> functions return 1 if the object is compatible | |
| 1605 | +with the given type, and 0 otherwise. | |
| 1606 | +They always return 0 for a non-valid index. | |
| 1607 | +<CODE>lua_isnumber</CODE> accepts numbers and numerical strings, | |
| 1608 | +<CODE>lua_isstring</CODE> accepts strings and numbers (see Section <A HREF="#coercion">4.2</A>), | |
| 1609 | +and <CODE>lua_isfunction</CODE> accepts both Lua functions and C functions. | |
| 1610 | +To distinguish between Lua functions and C functions, | |
| 1611 | +you should use <CODE>lua_iscfunction</CODE>. | |
| 1612 | +To distinguish between numbers and numerical strings, | |
| 1613 | +you can use <CODE>lua_type</CODE>. | |
| 1614 | +<P> | |
| 1615 | +The API also has functions to compare two values in the stack: | |
| 1616 | +<A NAME="lua_equal"></A> | |
| 1617 | +<A NAME="lua_lessthan"></A> | |
| 1618 | +<PRE> | |
| 1619 | + int lua_equal (lua_State *L, int index1, int index2); | |
| 1620 | + int lua_lessthan (lua_State *L, int index1, int index2); | |
| 1621 | +</PRE> | |
| 1622 | +These functions are equivalent to their counterparts in Lua. | |
| 1623 | +Specifically, <CODE>lua_lessthan</CODE> is equivalent to the <CODE>lt_event</CODE> | |
| 1624 | +described in Section <A HREF="#tag-method">4.8</A>. | |
| 1625 | +Both functions return 0 if any of the indices are non-valid. | |
| 1626 | +<P> | |
| 1627 | +To translate a value in the stack to a specific C type, | |
| 1628 | +you can use the following conversion functions: | |
| 1629 | +<A NAME="lua_tonumber"></A><A NAME="lua_tostring"></A><A NAME="lua_strlen"></A> | |
| 1630 | +<A NAME="lua_tocfunction"></A><A NAME="lua_touserdata"></A> | |
| 1631 | +<PRE> | |
| 1632 | + double lua_tonumber (lua_State *L, int index); | |
| 1633 | + const char *lua_tostring (lua_State *L, int index); | |
| 1634 | + size_t lua_strlen (lua_State *L, int index); | |
| 1635 | + lua_CFunction lua_tocfunction (lua_State *L, int index); | |
| 1636 | + void *lua_touserdata (lua_State *L, int index); | |
| 1637 | +</PRE> | |
| 1638 | +These functions can be called with any acceptable index. | |
| 1639 | +When called with a non-valid index, | |
| 1640 | +they act as if the given value had an incorrect type. | |
| 1641 | +<P> | |
| 1642 | +<CODE>lua_tonumber</CODE> converts the value at the given index | |
| 1643 | +to a floating-point number. | |
| 1644 | +This value must be a number or a string convertible to number | |
| 1645 | +(see Section <A HREF="#coercion">4.2</A>); otherwise, <CODE>lua_tonumber</CODE> returns 0. | |
| 1646 | +<P> | |
| 1647 | +<CODE>lua_tostring</CODE> converts a Lua value to a string | |
| 1648 | +(<CODE>const char*</CODE>). | |
| 1649 | +This value must be a string or a number; | |
| 1650 | +otherwise, the function returns <CODE>NULL</CODE>. | |
| 1651 | +This function returns a pointer to a string inside the Lua environment. | |
| 1652 | +Those strings always have a zero (<CODE>'\0'</CODE>) after their last character (as in C), | |
| 1353 | 1653 | but may contain other zeros in their body. |
| 1354 | 1654 | If you do not know whether a string may contain zeros, |
| 1355 | −you can use <CODE>lua_strlen</CODE> to get the actual length. | |
| 1655 | +you should use <CODE>lua_strlen</CODE> to get its actual length. | |
| 1356 | 1656 | Because Lua has garbage collection, |
| 1357 | −there is no guarantee that the pointer returned by <CODE>lua_getstring</CODE> | |
| 1358 | −will be valid after the block ends | |
| 1359 | −(see Section <A HREF="#GC">5.3</A>). | |
| 1657 | +there is no guarantee that the pointer returned by <CODE>lua_tostring</CODE> | |
| 1658 | +will be valid after the respective value is removed from the stack. | |
| 1360 | 1659 | <P> |
| 1361 | −<CODE>lua_getcfunction</CODE> converts a <CODE>lua_Object</CODE> to a C function. | |
| 1362 | −This <CODE>lua_Object</CODE> must have type <EM>CFunction</EM>; | |
| 1363 | −otherwise, <CODE>lua_getcfunction</CODE> returns 0 (the <CODE>NULL</CODE> pointer). | |
| 1364 | −The type <CODE>lua_CFunction</CODE> is explained in Section <A HREF="#LuacallC">5.7</A>. | |
| 1660 | +<CODE>lua_tocfunction</CODE> converts a value in the stack to a C function. | |
| 1661 | +This value must be a C function; | |
| 1662 | +otherwise, <CODE>lua_tocfunction</CODE> returns <CODE>NULL</CODE>. | |
| 1663 | +The type <CODE>lua_CFunction</CODE> is explained in Section <A HREF="#LuacallC">5.13</A>. | |
| 1365 | 1664 | <P> |
| 1366 | −<CODE>lua_getuserdata</CODE> converts a <CODE>lua_Object</CODE> to <CODE>void*</CODE>. | |
| 1367 | −This <CODE>lua_Object</CODE> must have type <EM>userdata</EM>; | |
| 1368 | −otherwise, <CODE>lua_getuserdata</CODE> returns 0 (the <CODE>NULL</CODE> pointer). | |
| 1665 | +<CODE>lua_touserdata</CODE> converts a value to <CODE>void*</CODE>. | |
| 1666 | +This value must have type <EM>userdata</EM>; | |
| 1667 | +otherwise, <CODE>lua_touserdata</CODE> returns <CODE>NULL</CODE>. | |
| 1369 | 1668 | <P> |
| 1370 | −<A NAME="GC"></A> | |
| 1371 | −<A NAME="5.3"></A> | |
| 1372 | −<H2>5.3 - Garbage Collection</H2> | |
| 1373 | −Because Lua has automatic memory management and garbage collection, | |
| 1374 | −a <CODE>lua_Object</CODE> has a limited scope, | |
| 1375 | −and is only valid inside the <EM>block</EM> where it has been created. | |
| 1376 | −A C function called from Lua is a block, | |
| 1377 | −and its parameters are valid only until its end. | |
| 1378 | −It is good programming practice to convert Lua objects to C values | |
| 1379 | −as soon as they are available, | |
| 1380 | −and never to store <CODE>lua_Object</CODE>s in C global variables. | |
| 1381 | −<P> | |
| 1382 | −A garbage collection cycle can be forced by: | |
| 1383 | −<A NAME="lua_collectgarbage"></A> | |
| 1384 | −<PRE> | |
| 1385 | −long lua_collectgarbage (long limit); | |
| 1386 | −</PRE> | |
| 1387 | −This function returns the number of objects collected. | |
| 1388 | −The argument <CODE>limit</CODE> makes the next cycle occur only | |
| 1389 | −after that number of new objects have been created. | |
| 1390 | −If <CODE>limit</CODE>=0, then Lua uses an adaptive heuristics to set this limit. | |
| 1391 | −<P> | |
| 1392 | −<P> | |
| 1393 | −All communication between Lua and C is done through two | |
| 1394 | −abstract data types, called <A NAME="lua2C"><EM>lua2C</EM></A> and <A NAME="C2lua"><EM>C2lua</EM></A>. | |
| 1395 | −The first one, as the name implies, is used to pass values | |
| 1396 | −from Lua to C: | |
| 1397 | −parameters when Lua calls C and results when C calls Lua. | |
| 1398 | −The structure C2lua is used in the reverse direction: | |
| 1399 | −parameters when C calls Lua and results when Lua calls C. | |
| 1400 | −<P> | |
| 1401 | −The structure lua2C is an abstract array, | |
| 1402 | −which can be indexed with the function: | |
| 1403 | −<A NAME="lua_lua2C"></A> | |
| 1404 | −<PRE> | |
| 1405 | −lua_Object lua_lua2C (int number); | |
| 1406 | −</PRE> | |
| 1407 | −where <CODE>number</CODE> starts with 1. | |
| 1408 | −When called with a number larger than the array size, | |
| 1409 | −this function returns <CODE>LUA_NOOBJECT</CODE><A NAME="LUA_NOOBJECT"></A>. | |
| 1410 | −In this way, it is possible to write C functions that receive | |
| 1411 | −a variable number of parameters, | |
| 1412 | −and to call Lua functions that return a variable number of results. | |
| 1413 | −Note that the structure lua2C cannot be directly modified by C code. | |
| 1414 | −<P> | |
| 1415 | −The second structure, C2lua, is an abstract stack. | |
| 1416 | −Pushing elements into this stack | |
| 1417 | −is done with the following functions: | |
| 1669 | +<P> | |
| 1670 | +<P> | |
| 1671 | +<A NAME="5.5"></A> | |
| 1672 | +<H2>5.5 - Pushing values onto the Stack</H2> | |
| 1673 | +<P> | |
| 1674 | +The API has the following functions to | |
| 1675 | +push C values onto the stack: | |
| 1418 | 1676 | <A NAME="lua_pushnumber"></A><A NAME="lua_pushlstring"></A><A NAME="lua_pushstring"></A> |
| 1419 | 1677 | <A NAME="lua_pushcfunction"></A><A NAME="lua_pushusertag"></A> |
| 1420 | −<A NAME="lua_pushnil"></A><A NAME="lua_pushobject"></A> | |
| 1421 | 1678 | <A NAME="pushing"></A> |
| 1422 | −<A NAME="lua_pushuserdata"></A> | |
| 1423 | −<PRE> | |
| 1424 | −void lua_pushnumber (double n); | |
| 1425 | −void lua_pushlstring (char *s, long len); | |
| 1426 | −void lua_pushstring (char *s); | |
| 1427 | −void lua_pushusertag (void *u, int tag); | |
| 1428 | −void lua_pushnil (void); | |
| 1429 | −void lua_pushobject (lua_Object object); | |
| 1430 | −void lua_pushcfunction (lua_CFunction f); /* macro */ | |
| 1431 | −</PRE> | |
| 1432 | −All of them receive a C value, | |
| 1433 | −convert it to a corresponding <CODE>lua_Object</CODE>, | |
| 1434 | −and leave the result on the top of C2lua. | |
| 1435 | −In particular, functions <CODE>lua_pushlstring</CODE> and <CODE>lua_pushstring</CODE> | |
| 1436 | −make an internal copy of the given string. | |
| 1437 | −Function <CODE>lua_pushstring</CODE> can only be used to push proper C strings | |
| 1438 | −(that is, strings that do not contain zeros and end with a zero); | |
| 1439 | −otherwise you should use the more generic <CODE>lua_pushlstring</CODE>. | |
| 1440 | −The function | |
| 1441 | −<A NAME="lua_pop"></A> | |
| 1442 | −<PRE> | |
| 1443 | −lua_Object lua_pop (void); | |
| 1444 | −</PRE> | |
| 1445 | −returns a reference to the object at the top of the C2lua stack, | |
| 1446 | −and pops it. | |
| 1447 | −<P> | |
| 1448 | −As a general rule, all API functions pop from the stack | |
| 1449 | −all elements they use. | |
| 1679 | +<A NAME="lua_pushnil"></A><A NAME="lua_pushuserdata"></A> | |
| 1680 | +<PRE> | |
| 1681 | + void lua_pushnumber (lua_State *L, double n); | |
| 1682 | + void lua_pushlstring (lua_State *L, const char *s, size_t len); | |
| 1683 | + void lua_pushstring (lua_State *L, const char *s); | |
| 1684 | + void lua_pushusertag (lua_State *L, void *u, int tag); | |
| 1685 | + void lua_pushnil (lua_State *L); | |
| 1686 | + void lua_pushcfunction (lua_State *L, lua_CFunction f); | |
| 1687 | +</PRE> | |
| 1688 | +These functions receive a C value, | |
| 1689 | +convert it to a corresponding Lua value, | |
| 1690 | +and push the result onto the stack. | |
| 1691 | +In particular, <CODE>lua_pushlstring</CODE> and <CODE>lua_pushstring</CODE> | |
| 1692 | +make an <EM>internal copy</EM> of the given string. | |
| 1693 | +<CODE>lua_pushstring</CODE> can only be used to push proper C strings | |
| 1694 | +(that is, strings that end with a zero and do not contain embedded zeros); | |
| 1695 | +otherwise you should use the more general <CODE>lua_pushlstring</CODE>, | |
| 1696 | +which accepts an explicit size. | |
| 1697 | +<P> | |
| 1698 | +<P> | |
| 1699 | +<A NAME="GC"></A> | |
| 1700 | +<A NAME="5.6"></A> | |
| 1701 | +<H2>5.6 - Garbage Collection</H2> | |
| 1702 | +<P> | |
| 1703 | +Lua uses two numbers to control its garbage collection. | |
| 1704 | +One number counts how many bytes of dynamic memory Lua is using, | |
| 1705 | +and the other is a threshold. | |
| 1706 | +(This internal byte counter kept by Lua is not completely acurate; | |
| 1707 | +it is just a lower bound, usually within 10% of the correct value.) | |
| 1708 | +When the number of bytes crosses the threshold, | |
| 1709 | +Lua runs a garbage-collection cycle, | |
| 1710 | +which reclaims the memory of all ``dead'' objects | |
| 1711 | +(that is, objects no longer accessible from Lua). | |
| 1712 | +The byte counter is corrected, | |
| 1713 | +and then the threshold is reset to twice the value of the byte counter. | |
| 1714 | +<P> | |
| 1715 | +You can access the current values of these two numbers through the | |
| 1716 | +following functions: | |
| 1717 | +<A NAME="lua_getgcthreshold"></A> <A NAME="lua_getgccount"></A> | |
| 1718 | +<PRE> | |
| 1719 | + int lua_getgccount (lua_State *L); | |
| 1720 | + int lua_getgcthreshold (lua_State *L); | |
| 1721 | +</PRE> | |
| 1722 | +Both return their respective values in Kbytes. | |
| 1723 | +You can change the threshold value with | |
| 1724 | +<A NAME="lua_setgcthreshold"></A> | |
| 1725 | +<PRE> | |
| 1726 | + void lua_setgcthreshold (lua_State *L, int newthreshold); | |
| 1727 | +</PRE> | |
| 1728 | +Again, the <CODE>newthreshold</CODE> value is given in Kbytes. | |
| 1729 | +When you call this function, | |
| 1730 | +Lua sets the new threshold and checks it against the byte counter. | |
| 1731 | +If the new threshold is smaller than the byte counter, | |
| 1732 | +then Lua immediately runs the garbage collector; | |
| 1733 | +after the collection, | |
| 1734 | +a new threshold is set according to the previous rule. | |
| 1735 | +<P> | |
| 1736 | +If you want to change the adaptative behavior of the garbage collector, | |
| 1737 | +you can use the garbage-collection tag method for <B>nil</B> | |
| 1738 | +to set your own threshold | |
| 1739 | +(the tag method is called after Lua resets the threshold). | |
| 1740 | +<P> | |
| 1741 | +<P> | |
| 1742 | +<A NAME="C-tags"></A> | |
| 1743 | +<A NAME="5.7"></A> | |
| 1744 | +<H2>5.7 - Userdata and Tags</H2> | |
| 1450 | 1745 | <P> |
| 1451 | 1746 | Because userdata are objects, |
| 1452 | 1747 | the function <CODE>lua_pushusertag</CODE> may create a new userdata. |
| 1453 | 1748 | If Lua has a userdata with the given value (<CODE>void*</CODE>) and tag, |
| 1454 | −that userdata is pushed. | |
| 1749 | +then that userdata is pushed. | |
| 1455 | 1750 | Otherwise, a new userdata is created, with the given value and tag. |
| 1456 | 1751 | If this function is called with |
| 1457 | 1752 | <CODE>tag</CODE> equal to <CODE>LUA_ANYTAG</CODE><A NAME="LUA_ANYTAG"></A>, |
| @@ -1462,230 +1757,361 @@ with tag equal to 0. · 4 unmodified lines | ||
| 1462 | 1757 | <P> |
| 1463 | 1758 | Userdata can have different tags, |
| 1464 | 1759 | whose semantics are only known to the host program. |
| 1465 | −Tags are created with the function: | |
| 1760 | +Tags are created with the function | |
| 1466 | 1761 | <A NAME="lua_newtag"></A> |
| 1467 | 1762 | <PRE> |
| 1468 | −int lua_newtag (void); | |
| 1763 | + int lua_newtag (lua_State *L); | |
| 1469 | 1764 | </PRE> |
| 1470 | 1765 | The function <CODE>lua_settag</CODE> changes the tag of |
| 1471 | −the object on the top of C2lua (and pops it); | |
| 1472 | −the object must be a userdata or a table. | |
| 1766 | +the object on top of the stack (without popping it): | |
| 1473 | 1767 | <A NAME="lua_settag"></A> |
| 1474 | 1768 | <PRE> |
| 1475 | −void lua_settag (int tag); | |
| 1476 | −</PRE> | |
| 1477 | −<CODE>tag</CODE> must be a value created with <CODE>lua_newtag</CODE>. | |
| 1478 | −<P> | |
| 1479 | −When C code calls Lua repeatedly, as in a loop, | |
| 1480 | −objects returned by these calls can accumulate, | |
| 1481 | −and may cause a stack overflow. | |
| 1482 | −To avoid this, | |
| 1483 | −nested blocks can be defined with the functions: | |
| 1484 | −<PRE> | |
| 1485 | −void lua_beginblock (void); | |
| 1486 | −void lua_endblock (void); | |
| 1769 | + void lua_settag (lua_State *L, int tag); | |
| 1487 | 1770 | </PRE> |
| 1488 | −After the end of the block, | |
| 1489 | −all <CODE>lua_Object</CODE>'s created inside it are released. | |
| 1490 | −The use of explicit nested blocks is good programming practice | |
| 1491 | −and is strongly encouraged. | |
| 1771 | +The object must be a userdata or a table; | |
| 1772 | +the given <CODE>tag</CODE> must be a value created with <CODE>lua_newtag</CODE>. | |
| 1492 | 1773 | <P> |
| 1493 | −<A NAME="5.4"></A> | |
| 1494 | −<H2>5.4 - Executing Lua Code</H2> | |
| 1774 | +<A NAME="luado"></A> | |
| 1775 | +<A NAME="5.8"></A> | |
| 1776 | +<H2>5.8 - Executing Lua Code</H2> | |
| 1495 | 1777 | A host program can execute Lua chunks written in a file or in a string |
| 1496 | −using the following functions: | |
| 1778 | +by using the following functions: | |
| 1497 | 1779 | <A NAME="lua_dofile"></A><A NAME="lua_dostring"></A><A NAME="lua_dobuffer"></A> |
| 1498 | 1780 | <PRE> |
| 1499 | −int lua_dofile (char *filename); | |
| 1500 | −int lua_dostring (char *string); | |
| 1501 | −int lua_dobuffer (char *buff, int size, char *name); | |
| 1781 | + int lua_dofile (lua_State *L, const char *filename); | |
| 1782 | + int lua_dostring (lua_State *L, const char *string); | |
| 1783 | + int lua_dobuffer (lua_State *L, const char *buff, | |
| 1784 | + size_t size, const char *name); | |
| 1502 | 1785 | </PRE> |
| 1503 | −All these functions return an error code: | |
| 1504 | −0, in case of success; non zero, in case of errors. | |
| 1505 | −More specifically, <CODE>lua_dofile</CODE> returns 2 if for any reason | |
| 1506 | −it could not open the file. | |
| 1786 | +These functions return | |
| 1787 | +0 in case of success, or one of the following error codes if they fail: | |
| 1788 | +<UL> | |
| 1789 | +<LI><A NAME="LUA_ERRRUN"><TT>LUA_ERRRUN</TT></A> - | |
| 1790 | +error while running the chunk. | |
| 1791 | +<LI><A NAME="LUA_ERRSYNTAX"><TT>LUA_ERRSYNTAX</TT></A> - | |
| 1792 | +syntax error during pre-compilation. | |
| 1793 | +<LI><A NAME="LUA_ERRMEM"><TT>LUA_ERRMEM</TT></A> - | |
| 1794 | +memory allocation error. | |
| 1795 | +For such errors, Lua does not call <CODE>_ERRORMESSAGE</CODE> (see Section <A HREF="#error">4.7</A>). | |
| 1796 | +<LI><A NAME="LUA_ERRERR"><TT>LUA_ERRERR</TT></A> - | |
| 1797 | +error while running <CODE>_ERRORMESSAGE</CODE>. | |
| 1798 | +For such errors, Lua does not call <CODE>_ERRORMESSAGE</CODE> again, to avoid loops. | |
| 1799 | +<LI><A NAME="LUA_ERRFILE"><TT>LUA_ERRFILE</TT></A> - | |
| 1800 | +error opening the file (only for <CODE>lua_dofile</CODE>). | |
| 1801 | +In this case, | |
| 1802 | +you may want to | |
| 1803 | +check <CODE>errno</CODE>, | |
| 1804 | +call <CODE>strerror</CODE>, | |
| 1805 | +or call <CODE>perror</CODE> to tell the user what went wrong. | |
| 1806 | +</UL> | |
| 1807 | +These constants are defined in <CODE>lua.h</CODE>. | |
| 1808 | +<P> | |
| 1507 | 1809 | When called with argument <CODE>NULL</CODE>, |
| 1508 | 1810 | <CODE>lua_dofile</CODE> executes the <CODE>stdin</CODE> stream. |
| 1509 | −Functions <CODE>lua_dofile</CODE> and <CODE>lua_dobuffer</CODE> | |
| 1811 | +<CODE>lua_dofile</CODE> and <CODE>lua_dobuffer</CODE> | |
| 1510 | 1812 | are both able to execute pre-compiled chunks. |
| 1511 | 1813 | They automatically detect whether the chunk is text or binary, |
| 1512 | 1814 | and load it accordingly (see program <A NAME="luac"><TT><A HREF="luac.html">luac</A></TT></A>). |
| 1513 | −Function <CODE>lua_dostring</CODE> executes only source code. | |
| 1815 | +<CODE>lua_dostring</CODE> executes only source code, | |
| 1816 | +given in textual form. | |
| 1514 | 1817 | <P> |
| 1515 | −The third parameter to <CODE>lua_dobuffer</CODE> (<CODE>name</CODE>) | |
| 1818 | +The third parameter to <CODE>lua_dobuffer</CODE> | |
| 1516 | 1819 | is the ``name of the chunk'', |
| 1517 | −used in error messages and debug information. | |
| 1820 | +which is used in error messages and debug information. | |
| 1518 | 1821 | If <CODE>name</CODE> is <CODE>NULL</CODE>, |
| 1519 | −Lua gives a default name to the chunk. | |
| 1822 | +then Lua gives a default name to the chunk. | |
| 1823 | +<P> | |
| 1824 | +These functions push onto the stack | |
| 1825 | +any values eventually returned by the chunk. | |
| 1826 | +A chunk may return any number of values; | |
| 1827 | +Lua takes care that these values fit into the stack space, | |
| 1828 | +but after the call the responsibility is back to you. | |
| 1829 | +If you need to push other elements after calling any of these functions, | |
| 1830 | +and you want to ``play safe'', | |
| 1831 | +you must either check the stack space | |
| 1832 | +with <CODE>lua_stackspace</CODE> | |
| 1833 | +or remove the returned elements | |
| 1834 | +from the stack (if you do not need them). | |
| 1835 | +For instance, the following code | |
| 1836 | +loads a chunk in a file and discards all results returned by this chunk, | |
| 1837 | +leaving the stack as it was before the call: | |
| 1838 | +<PRE> | |
| 1839 | + { | |
| 1840 | + int oldtop = lua_gettop(L); | |
| 1841 | + lua_dofile(L, filename); | |
| 1842 | + lua_settop(L, oldtop); | |
| 1843 | + } | |
| 1844 | +</PRE> | |
| 1520 | 1845 | <P> |
| 1521 | −These functions return, in structure lua2C, | |
| 1522 | −any values eventually returned by the chunks. | |
| 1523 | −They also empty the stack C2lua. | |
| 1524 | 1846 | <P> |
| 1847 | +<A NAME="5.9"></A> | |
| 1848 | +<H2>5.9 - Manipulating Global Variables in Lua</H2> | |
| 1525 | 1849 | <P> |
| 1526 | −<A NAME="5.5"></A> | |
| 1527 | −<H2>5.5 - Manipulating Lua Objects</H2> | |
| 1528 | −To read the value of any global Lua variable, | |
| 1529 | −one uses the function: | |
| 1850 | +To read the value of a global Lua variable, | |
| 1851 | +you call | |
| 1530 | 1852 | <A NAME="lua_getglobal"></A> |
| 1531 | 1853 | <PRE> |
| 1532 | −lua_Object lua_getglobal (char *varname); | |
| 1854 | + void lua_getglobal (lua_State *L, const char *varname); | |
| 1533 | 1855 | </PRE> |
| 1534 | −As in Lua, this function may trigger a tag method. | |
| 1535 | −To read the real value of any global variable, | |
| 1856 | +which pushes onto the stack the value of the given variable. | |
| 1857 | +As in Lua, this function may trigger a tag method | |
| 1858 | +for the ``getglobal'' event (see Section <A HREF="#tag-method">4.8</A>). | |
| 1859 | +To read the real value of a global variable, | |
| 1536 | 1860 | without invoking any tag method, |
| 1537 | −use the <EM>raw</EM> version: | |
| 1538 | −<A NAME="lua_rawgetglobal"></A> | |
| 1539 | −<PRE> | |
| 1540 | −lua_Object lua_rawgetglobal (char *varname); | |
| 1541 | −</PRE> | |
| 1861 | +use <CODE>lua_rawget</CODE> over the table of globals | |
| 1862 | +(see below). | |
| 1542 | 1863 | <P> |
| 1543 | −To store a value previously pushed onto C2lua in a global variable, | |
| 1544 | −there is the function: | |
| 1864 | +To store a value in a global variable, | |
| 1865 | +you call | |
| 1545 | 1866 | <A NAME="lua_setglobal"></A> |
| 1546 | 1867 | <PRE> |
| 1547 | −void lua_setglobal (char *varname); | |
| 1868 | + void lua_setglobal (lua_State *L, const char *varname); | |
| 1548 | 1869 | </PRE> |
| 1549 | −As in Lua, this function may trigger a tag method. | |
| 1550 | −To set the real value of any global variable, | |
| 1870 | +which pops from the stack the value to be stored in the given variable. | |
| 1871 | +As in Lua, this function may trigger a tag method | |
| 1872 | +for the ``setglobal'' event (see Section <A HREF="#tag-method">4.8</A>). | |
| 1873 | +To set the real value of a global variable, | |
| 1551 | 1874 | without invoking any tag method, |
| 1552 | −use the <EM>raw</EM> version: | |
| 1553 | −<A NAME="lua_rawgetglobal"></A> | |
| 1875 | +use <CODE>lua_rawset</CODE> over the table of globals | |
| 1876 | +(see below). | |
| 1877 | +<P> | |
| 1878 | +All global variables are kept in an ordinary Lua table. | |
| 1879 | +You can get this table calling | |
| 1880 | +<A NAME="lua_getglobals"></A> | |
| 1554 | 1881 | <PRE> |
| 1555 | −void lua_rawsetglobal (char *varname); | |
| 1882 | + void lua_getglobals (lua_State *L); | |
| 1556 | 1883 | </PRE> |
| 1884 | +which pushes the current table of globals onto the stack. | |
| 1885 | +To set another table as the table of globals, | |
| 1886 | +you call | |
| 1887 | +<A NAME="lua_setglobals"></A> | |
| 1888 | +<PRE> | |
| 1889 | + void lua_setglobals (lua_State *L); | |
| 1890 | +</PRE> | |
| 1891 | +The table to be used is popped from the stack. | |
| 1557 | 1892 | <P> |
| 1558 | −Tables can also be manipulated via the API. | |
| 1559 | −The function | |
| 1893 | +<A NAME="5.10"></A> | |
| 1894 | +<H2>5.10 - Manipulating Tables in Lua</H2> | |
| 1895 | +Lua tables can also be manipulated through the API. | |
| 1896 | +<P> | |
| 1897 | +To read the value of in a table, | |
| 1898 | +the table must reside somewhere in the stack. | |
| 1899 | +With this set, | |
| 1900 | +you call | |
| 1560 | 1901 | <A NAME="lua_gettable"></A> |
| 1561 | 1902 | <PRE> |
| 1562 | −lua_Object lua_gettable (void); | |
| 1903 | + void lua_gettable (lua_State *L, int index); | |
| 1563 | 1904 | </PRE> |
| 1564 | −pops a table and an index from the stack C2lua, | |
| 1565 | −and returns the contents of the table at that index. | |
| 1566 | −As in Lua, this operation may trigger a tag method. | |
| 1567 | −To get the real value of any table index, | |
| 1905 | +where <CODE>index</CODE> refers to the table. | |
| 1906 | +<CODE>lua_gettable</CODE> pops a key from the stack, | |
| 1907 | +and returns (on the stack) the contents of the table at that key. | |
| 1908 | +As in Lua, this operation may trigger a tag method | |
| 1909 | +for the ``gettable'' event. | |
| 1910 | +To get the real value of any table key, | |
| 1568 | 1911 | without invoking any tag method, |
| 1569 | 1912 | use the <EM>raw</EM> version: |
| 1570 | −<A NAME="lua_rawgetglobal"></A> | |
| 1913 | +<A NAME="lua_rawget"></A> | |
| 1571 | 1914 | <PRE> |
| 1572 | −lua_Object lua_rawgettable (void); | |
| 1915 | + void lua_rawget (lua_State *L, int index); | |
| 1573 | 1916 | </PRE> |
| 1574 | 1917 | <P> |
| 1575 | −To store a value in an index, | |
| 1576 | −the program must push the table, the index, | |
| 1577 | −and the value onto C2lua, | |
| 1578 | −and then call the function | |
| 1918 | +To store a value into a table that resides somewhere in the stack, | |
| 1919 | +you push the key and the value onto the stack | |
| 1920 | +(in this order), | |
| 1921 | +and then call | |
| 1579 | 1922 | <A NAME="lua_settable"></A> |
| 1580 | 1923 | <PRE> |
| 1581 | −void lua_settable (void); | |
| 1924 | + void lua_settable (lua_State *L, int index); | |
| 1582 | 1925 | </PRE> |
| 1583 | −Again, the tag method for ``settable'' may be called. | |
| 1926 | +where <CODE>index</CODE> refers to the table. | |
| 1927 | +<CODE>lua_settable</CODE> pops from the stack both the key and the value. | |
| 1928 | +As in Lua, this operation may trigger a tag method | |
| 1929 | +for the ``settable'' event. | |
| 1584 | 1930 | To set the real value of any table index, |
| 1585 | 1931 | without invoking any tag method, |
| 1586 | 1932 | use the <EM>raw</EM> version: |
| 1587 | −<A NAME="lua_rawsettable"></A> | |
| 1933 | +<A NAME="lua_rawset"></A> | |
| 1588 | 1934 | <PRE> |
| 1589 | −void lua_rawsettable (void); | |
| 1935 | + void lua_rawset (lua_State *L, int index); | |
| 1590 | 1936 | </PRE> |
| 1591 | 1937 | <P> |
| 1592 | 1938 | Finally, the function |
| 1593 | −<A NAME="lua_createtable"></A> | |
| 1939 | +<A NAME="lua_newtable"></A> | |
| 1940 | +<PRE> | |
| 1941 | + void lua_newtable (lua_State *L); | |
| 1942 | +</PRE> | |
| 1943 | +creates a new, empty table and pushes it onto the stack. | |
| 1944 | +<P> | |
| 1945 | +<A NAME="5.11"></A> | |
| 1946 | +<H2>5.11 - Using Tables as Arrays</H2> | |
| 1947 | +The API has functions that help to use Lua tables as arrays, | |
| 1948 | +that is, | |
| 1949 | +tables indexed by numbers only: | |
| 1950 | +<A NAME="lua_rawgeti"></A> | |
| 1951 | +<A NAME="lua_rawseti"></A> | |
| 1952 | +<A NAME="lua_getn"></A> | |
| 1594 | 1953 | <PRE> |
| 1595 | −lua_Object lua_createtable (void); | |
| 1954 | + void lua_rawgeti (lua_State *L, int index, int n); | |
| 1955 | + void lua_rawseti (lua_State *L, int index, int n); | |
| 1956 | + int lua_getn (lua_State *L, int index); | |
| 1596 | 1957 | </PRE> |
| 1597 | −creates and returns a new, empty table. | |
| 1598 | 1958 | <P> |
| 1959 | +<CODE>lua_rawgeti</CODE> gets the value of the <EM>n</EM>-th element of the table | |
| 1960 | +at stack position <CODE>index</CODE>. | |
| 1599 | 1961 | <P> |
| 1600 | −<A NAME="5.6"></A> | |
| 1601 | −<H2>5.6 - Calling Lua Functions</H2> | |
| 1602 | −Functions defined in Lua by a chunk | |
| 1962 | +<CODE>lua_rawseti</CODE> sets the value of the <EM>n</EM>-th element of the table | |
| 1963 | +at stack position <CODE>index</CODE> to the value at the top of the stack. | |
| 1964 | +<P> | |
| 1965 | +<CODE>lua_getn</CODE> returns the number of elements in the table | |
| 1966 | +at stack position <CODE>index</CODE>. | |
| 1967 | +This number is the value of the table field <CODE>n</CODE>, | |
| 1968 | +if it has a numeric value, | |
| 1969 | +or | |
| 1970 | +the largest numerical index with a non-nil value in the table. | |
| 1971 | +<P> | |
| 1972 | +<A NAME="5.12"></A> | |
| 1973 | +<H2>5.12 - Calling Lua Functions</H2> | |
| 1974 | +<P> | |
| 1975 | +Functions defined in Lua | |
| 1976 | +(and C functions registered in Lua) | |
| 1603 | 1977 | can be called from the host program. |
| 1604 | 1978 | This is done using the following protocol: |
| 1605 | −first, the arguments to the function are pushed onto C2lua | |
| 1606 | −(see Section <A HREF="#pushing">5.3</A>), in direct order, i.e., the first argument is pushed first. | |
| 1607 | −Then, the function is called using | |
| 1608 | −<A NAME="lua_callfunction"></A> | |
| 1609 | −<PRE> | |
| 1610 | −int lua_callfunction (lua_Object function); | |
| 1611 | −</PRE> | |
| 1612 | −This function returns an error code: | |
| 1613 | −0, in case of success; non zero, in case of errors. | |
| 1614 | −Finally, the results (a Lua function may return many values) | |
| 1615 | −are returned in structure lua2C, | |
| 1616 | −and can be retrieved with the macro <CODE>lua_getresult</CODE>, | |
| 1617 | −<A NAME="lua_getresult"></A> | |
| 1618 | −which is just another name to function <CODE>lua_lua2C</CODE>. | |
| 1619 | −Note that function <CODE>lua_callfunction</CODE> | |
| 1620 | −pops all elements from the C2lua stack. | |
| 1621 | −<P> | |
| 1622 | −The following example shows how a C program may do the | |
| 1979 | +First, the function to be called is pushed onto the stack; | |
| 1980 | +then, the arguments to the function are pushed | |
| 1981 | +(see Section <A HREF="#pushing">5.5</A>) in <EM>direct order</EM>, that is, the first argument is pushed first. | |
| 1982 | +Finally, the function is called using | |
| 1983 | +<A NAME="lua_call"></A> | |
| 1984 | +<PRE> | |
| 1985 | + int lua_call (lua_State *L, int nargs, int nresults); | |
| 1986 | +</PRE> | |
| 1987 | +This function returns the same error codes as <CODE>lua_dostring</CODE> and | |
| 1988 | +friends (see Section <A HREF="#luado">5.8</A>). | |
| 1989 | +If you want to propagate the error, | |
| 1990 | +instead of returning an error code, | |
| 1991 | +use | |
| 1992 | +<A NAME="lua_rawcall"></A> | |
| 1993 | +<PRE> | |
| 1994 | + void lua_rawcall (lua_State *L, int nargs, int nresults); | |
| 1995 | +</PRE> | |
| 1996 | +<P> | |
| 1997 | +In both functions, | |
| 1998 | +<CODE>nargs</CODE> is the number of arguments that you pushed onto the stack. | |
| 1999 | +All arguments and the function value are popped from the stack, | |
| 2000 | +and the function results are pushed. | |
| 2001 | +The number of results are adjusted (see Section <A HREF="#adjust">4.3</A>) to <CODE>nresults</CODE>, | |
| 2002 | +unless <CODE>nresults</CODE> is <A NAME="LUA_MULTRET"><TT>LUA_MULTRET</TT></A>. | |
| 2003 | +In that case, <EM>all</EM> results from the function are pushed. | |
| 2004 | +The function results are pushed in direct order | |
| 2005 | +(the first result is pushed first), | |
| 2006 | +so that after the call the last result is on the top. | |
| 2007 | +<P> | |
| 2008 | +The following example shows how the host program may do the | |
| 1623 | 2009 | equivalent to the Lua code: |
| 1624 | 2010 | <PRE> |
| 1625 | − a,b = f("how", t.x, 4) | |
| 2011 | + a,b = f("how", t.x, 4) | |
| 1626 | 2012 | </PRE> |
| 2013 | +Here it is in C: | |
| 1627 | 2014 | <PRE> |
| 1628 | − lua_pushstring("how"); /* 1st argument */ | |
| 1629 | − lua_pushobject(lua_getglobal("t")); /* push value of global 't' */ | |
| 1630 | − lua_pushstring("x"); /* push the string 'x' */ | |
| 1631 | − lua_pushobject(lua_gettable()); /* push result of t.x (2nd arg) */ | |
| 1632 | − lua_pushnumber(4); /* 3rd argument */ | |
| 1633 | − lua_callfunction(lua_getglobal("f")); /* call Lua function */ | |
| 1634 | − lua_pushobject(lua_getresult(1)); /* push first result of the call */ | |
| 1635 | − lua_setglobal("a"); /* set global variable 'a' */ | |
| 1636 | − lua_pushobject(lua_getresult(2)); /* push second result of the call */ | |
| 1637 | − lua_setglobal("b"); /* set global variable 'b' */ | |
| 2015 | + lua_getglobal(L, "t"); /* global `t' (for later use) */ | |
| 2016 | + lua_getglobal(L, "f"); /* function to be called */ | |
| 2017 | + lua_pushstring(L, "how"); /* 1st argument */ | |
| 2018 | + lua_pushstring(L, "x"); /* push the string `x' */ | |
| 2019 | + lua_gettable(L, -4); /* push result of t.x (2nd arg) */ | |
| 2020 | + lua_pushnumber(L, 4); /* 3rd argument */ | |
| 2021 | + lua_call(L, 3, 2); /* call function with 3 arguments and 2 results */ | |
| 2022 | + lua_setglobal(L, "b"); /* set global variable `b' */ | |
| 2023 | + lua_setglobal(L, "a"); /* set global variable `a' */ | |
| 2024 | + lua_pop(L, 1); /* remove `t' from the stack */ | |
| 1638 | 2025 | </PRE> |
| 2026 | +Notice that the code above is ``balanced'': | |
| 2027 | +at its end ,the stack is back to its original configuration. | |
| 2028 | +This is considered good programming practice. | |
| 2029 | +<P> | |
| 1639 | 2030 | <P> |
| 1640 | −Some special Lua functions have exclusive interfaces. | |
| 1641 | −A C function can generate a Lua error calling the function | |
| 2031 | +<P> | |
| 2032 | +Some special Lua functions have their own C interfaces. | |
| 2033 | +The host program can generate a Lua error calling the function | |
| 1642 | 2034 | <A NAME="lua_error"></A> |
| 1643 | 2035 | <PRE> |
| 1644 | −void lua_error (char *message); | |
| 2036 | + void lua_error (lua_State *L, const char *message); | |
| 1645 | 2037 | </PRE> |
| 1646 | 2038 | This function never returns. |
| 1647 | −If the C function has been called from Lua, | |
| 2039 | +If <CODE>lua_error</CODE> is called from a C function that has been called from Lua, | |
| 1648 | 2040 | then the corresponding Lua execution terminates, |
| 1649 | 2041 | as if an error had occurred inside Lua code. |
| 1650 | −Otherwise, the whole host program terminates with a call to <CODE>exit(1)</CODE>. | |
| 1651 | −The <CODE>message</CODE> is passed to the error handler function, | |
| 1652 | −<CODE>_ERRORMESSAGE</CODE>. | |
| 2042 | +Otherwise, the whole host program terminates with a call to | |
| 2043 | +<CODE>exit(EXIT_FAILURE)</CODE>. | |
| 2044 | +Before terminating execution, | |
| 2045 | +the <CODE>message</CODE> is passed to the error handler function, | |
| 2046 | +<CODE>_ERRORMESSAGE</CODE> (see Section <A HREF="#error">4.7</A>). | |
| 1653 | 2047 | If <CODE>message</CODE> is <CODE>NULL</CODE>, |
| 1654 | 2048 | then <CODE>_ERRORMESSAGE</CODE> is not called. |
| 1655 | 2049 | <P> |
| 1656 | −Tag methods can be changed with: <A NAME="lua_settagmethod"></A> | |
| 2050 | +<P> | |
| 2051 | +Tag methods can be changed with <A NAME="lua_settagmethod"></A> | |
| 1657 | 2052 | <PRE> |
| 1658 | −lua_Object lua_settagmethod (int tag, char *event); | |
| 2053 | + void lua_settagmethod (lua_State *L, int tag, const char *event); | |
| 1659 | 2054 | </PRE> |
| 1660 | −The first parameter is the tag, | |
| 1661 | −and the second is the event name (see Section <A HREF="#tag-method">4.8</A>); | |
| 1662 | −the new method is pushed from C2lua. | |
| 1663 | −This function returns a <CODE>lua_Object</CODE>, | |
| 1664 | −which is the old tag method value. | |
| 1665 | −To get just the current value of a tag method, | |
| 2055 | +The second parameter is the tag, | |
| 2056 | +and the third is the event name (see Section <A HREF="#tag-method">4.8</A>); | |
| 2057 | +the new method is popped from the stack. | |
| 2058 | +To get the current value of a tag method, | |
| 1666 | 2059 | use the function <A NAME="lua_gettagmethod"></A> |
| 1667 | 2060 | <PRE> |
| 1668 | −lua_Object lua_gettagmethod (int tag, char *event); | |
| 2061 | + void lua_gettagmethod (lua_State *L, int tag, const char *event); | |
| 1669 | 2062 | </PRE> |
| 1670 | 2063 | <P> |
| 1671 | 2064 | It is also possible to copy all tag methods from one tag |
| 1672 | 2065 | to another: <A NAME="lua_copytagmethods"></A> |
| 1673 | 2066 | <PRE> |
| 1674 | −int lua_copytagmethods (int tagto, int tagfrom); | |
| 2067 | + int lua_copytagmethods (lua_State *L, int tagto, int tagfrom); | |
| 1675 | 2068 | </PRE> |
| 1676 | 2069 | This function returns <CODE>tagto</CODE>. |
| 1677 | 2070 | <P> |
| 1678 | 2071 | <P> |
| 2072 | +You can traverse a table with the function <A NAME="lua_next"></A> | |
| 2073 | +<PRE> | |
| 2074 | + int lua_next (lua_State *L, int index); | |
| 2075 | +</PRE> | |
| 2076 | +where <CODE>index</CODE> refers to the table to be traversed. | |
| 2077 | +The function pops a key from the stack, | |
| 2078 | +and pushes a key-value pair from the table | |
| 2079 | +(the ``next'' pair after the given key). | |
| 2080 | +If there are no more elements, then the function returns 0 | |
| 2081 | +(and pushes nothing). | |
| 2082 | +A typical traversal looks like this: | |
| 2083 | +<PRE> | |
| 2084 | + /* table is in the stack at index `t' */ | |
| 2085 | + lua_pushnil(L); /* first key */ | |
| 2086 | + while (lua_next(L, t) != 0) { | |
| 2087 | + /* `key' is at index -2 and `value' at index -1 */ | |
| 2088 | + printf("%s - %s\n", | |
| 2089 | + lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); | |
| 2090 | + lua_pop(L, 1); /* removes `value'; keeps `index' for next iteration */ | |
| 2091 | + } | |
| 2092 | +</PRE> | |
| 2093 | +<P> | |
| 2094 | +The function <A NAME="lua_concat"></A> | |
| 2095 | +<PRE> | |
| 2096 | + void lua_concat (lua_State *L, int n); | |
| 2097 | +</PRE> | |
| 2098 | +concatenates the <CODE>n</CODE> values at the top of the stack, | |
| 2099 | +pops them, and leaves the result at the top; | |
| 2100 | +<CODE>n</CODE> must be at least 2. | |
| 2101 | +Concatenation is done following the usual semantics of Lua | |
| 2102 | +(see Section <A HREF="#concat">4.5.5</A>). | |
| 2103 | +<P> | |
| 2104 | +<P> | |
| 1679 | 2105 | <A NAME="LuacallC"></A> |
| 1680 | −<A NAME="5.7"></A> | |
| 1681 | −<H2>5.7 - C Functions</H2> | |
| 1682 | −To register a C function to Lua, | |
| 1683 | −there is the following macro: | |
| 2106 | +<A NAME="5.13"></A> | |
| 2107 | +<H2>5.13 - Defining C Functions</H2> | |
| 2108 | +To register a C function to Lua, | |
| 2109 | +there is the following convenience macro: | |
| 1684 | 2110 | <A NAME="lua_register"></A> |
| 1685 | 2111 | <PRE> |
| 1686 | −#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n)) | |
| 1687 | −/* char *n; */ | |
| 1688 | −/* lua_CFunction f; */ | |
| 2112 | + #define lua_register(L, n, f) (lua_pushcfunction(L, f), lua_setglobal(L, n)) | |
| 2113 | + /* const char *n; */ | |
| 2114 | + /* lua_CFunction f; */ | |
| 1689 | 2115 | </PRE> |
| 1690 | 2116 | which receives the name the function will have in Lua, |
| 1691 | 2117 | and a pointer to the function. |
| @@ -1693,110 +2119,185 @@ This pointer must have type <CODE>lua_CFunction</CODE>, · 1 unmodified line | ||
| 1693 | 2119 | which is defined as |
| 1694 | 2120 | <A NAME="lua_CFunction"></A> |
| 1695 | 2121 | <PRE> |
| 1696 | −typedef void (*lua_CFunction) (void); | |
| 2122 | + typedef int (*lua_CFunction) (lua_State *L); | |
| 1697 | 2123 | </PRE> |
| 1698 | −that is, a pointer to a function with no parameters and no results. | |
| 2124 | +that is, a pointer to a function with integer result and a single argument, | |
| 2125 | +a Lua environment. | |
| 1699 | 2126 | <P> |
| 1700 | 2127 | In order to communicate properly with Lua, |
| 1701 | −a C function must follow a protocol, | |
| 1702 | −which defines the way parameters and results are passed. | |
| 1703 | −<P> | |
| 1704 | −A C function receives its arguments in structure lua2C; | |
| 1705 | −to access them, it uses the macro <CODE>lua_getparam</CODE>, <A NAME="lua_getparam"></A> | |
| 1706 | −again just another name for <CODE>lua_lua2C</CODE>. | |
| 1707 | −To return values, a C function just pushes them onto the stack C2lua, | |
| 1708 | −in direct order (see Section <A HREF="#valuesCLua">5.2</A>). | |
| 1709 | −Like a Lua function, a C function called by Lua can also return | |
| 2128 | +a C function must follow the following protocol, | |
| 2129 | +which defines the way parameters and results are passed: | |
| 2130 | +A C function receives its arguments from Lua in the stack, | |
| 2131 | +in direct order (the first argument is pushed first). | |
| 2132 | +To return values to Lua, a C function just pushes them onto the stack, | |
| 2133 | +in direct order (the first result is pushed first), | |
| 2134 | +and returns the number of results. | |
| 2135 | +Like a Lua function, a C function called by Lua can also return | |
| 1710 | 2136 | many results. |
| 1711 | 2137 | <P> |
| 1712 | −When a C function is created, | |
| 1713 | −it is possible to associate some <EM>upvalues</EM> to it, | |
| 1714 | −thus creating a C closure; | |
| 1715 | −then these values are passed to the function whenever it is called, | |
| 1716 | −as common arguments. | |
| 1717 | −To associate upvalues to a function, | |
| 1718 | −first these values must be pushed on C2lua. | |
| 1719 | −Then the function | |
| 1720 | −<A NAME="lua_pushcclosure"></A> | |
| 1721 | −<PRE> | |
| 1722 | −void lua_pushcclosure (lua_CFunction fn, int n); | |
| 1723 | −</PRE> | |
| 1724 | −is used to put the C function on C2lua, | |
| 1725 | −with the argument <CODE>n</CODE> telling how many upvalues must be | |
| 1726 | −associated with the function; | |
| 2138 | +As an example, the following function receives a variable number | |
| 2139 | +of numerical arguments and returns their average and sum: | |
| 2140 | +<PRE> | |
| 2141 | + static int foo (lua_State *L) { | |
| 2142 | + int n = lua_gettop(L); /* number of arguments */ | |
| 2143 | + double sum = 0; | |
| 2144 | + int i; | |
| 2145 | + for (i = 1; i <= n; i++) { | |
| 2146 | + if (!lua_isnumber(L, i)) | |
| 2147 | + lua_error(L, "incorrect argument to function `average'"); | |
| 2148 | + sum += lua_tonumber(L, i); | |
| 2149 | + } | |
| 2150 | + lua_pushnumber(L, sum/n); /* first result */ | |
| 2151 | + lua_pushnumber(L, sum); /* second result */ | |
| 2152 | + return 2; /* number of results */ | |
| 2153 | + } | |
| 2154 | +</PRE> | |
| 2155 | +This function may be registered in Lua as `<CODE>average</CODE>' by calling | |
| 2156 | +<PRE> | |
| 2157 | + lua_register(L, "average", foo); | |
| 2158 | +</PRE> | |
| 2159 | +<P> | |
| 2160 | +<P> | |
| 2161 | +When a C function is created, | |
| 2162 | +it is possible to associate some <EM>upvalues</EM> to it | |
| 2163 | +(see Section <A HREF="#upvalue">4.6</A>), | |
| 2164 | +thus creating a <A NAME="C closure"><EM>C closure</EM></A>; | |
| 2165 | +these values are passed to the function whenever it is called, | |
| 2166 | +as ordinary arguments. | |
| 2167 | +To associate upvalues to a C function, | |
| 2168 | +first these values should be pushed onto the stack. | |
| 2169 | +Then the function <A NAME="lua_pushcclosure"></A> | |
| 2170 | +<PRE> | |
| 2171 | + void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); | |
| 2172 | +</PRE> | |
| 2173 | +is used to push the C function onto the stack, | |
| 2174 | +with the argument <CODE>n</CODE> telling how many upvalues should be | |
| 2175 | +associated with the function | |
| 2176 | +(these upvalues are popped from the stack); | |
| 1727 | 2177 | in fact, the macro <CODE>lua_pushcfunction</CODE> is defined as |
| 1728 | 2178 | <CODE>lua_pushcclosure</CODE> with <CODE>n</CODE> set to 0. |
| 1729 | −Then, any time the function is called, | |
| 1730 | −these upvalues are inserted as the first arguments to the function, | |
| 1731 | −before the actual arguments provided in the call. | |
| 1732 | −<P> | |
| 1733 | −For some examples of C functions, see files <CODE>lstrlib.c</CODE>, | |
| 1734 | −<CODE>liolib.c</CODE> and <CODE>lmathlib.c</CODE> in the official Lua distribution. | |
| 1735 | −<P> | |
| 1736 | −<A NAME="5.8"></A> | |
| 1737 | −<H2>5.8 - References to Lua Objects</H2> | |
| 1738 | −<P> | |
| 1739 | −As noted in Section <A HREF="#GC">5.3</A>, <CODE>lua_Object</CODE>s are volatile. | |
| 1740 | −If the C code needs to keep a <CODE>lua_Object</CODE> | |
| 1741 | −outside block boundaries, | |
| 1742 | −then it must create a <A NAME="reference"><EM>reference</EM></A> to the object. | |
| 1743 | −The routines to manipulate references are the following: | |
| 2179 | +Then, whenever the C function is called, | |
| 2180 | +these upvalues are inserted as the <EM>last</EM> arguments to the function, | |
| 2181 | +after the actual arguments provided in the call. | |
| 2182 | +This makes it easy to get the upvalues without knowing how many arguments | |
| 2183 | +the function received (recall that functions in Lua can receive any number of | |
| 2184 | +arguments): The <EM>i</EM>-th upvalue is in the stack at index <I>i-(n+1)</I>, | |
| 2185 | +where <EM>n</EM> is the number of upvalues. | |
| 2186 | +<P> | |
| 2187 | +For more examples of C functions and closures, see files | |
| 2188 | +<CODE>lbaselib.c</CODE>, <CODE>liolib.c</CODE>, <CODE>lmathlib.c</CODE>, and <CODE>lstrlib.c</CODE> | |
| 2189 | +in the official Lua distribution. | |
| 2190 | +<P> | |
| 2191 | +<A NAME="5.14"></A> | |
| 2192 | +<H2>5.14 - References to Lua Objects</H2> | |
| 2193 | +<P> | |
| 2194 | +If the C code needs to keep a Lua value | |
| 2195 | +outside the life span of a C function, | |
| 2196 | +then it must create a <A NAME="reference"><EM>reference</EM></A> to the value. | |
| 2197 | +The functions to manipulate references are the following: | |
| 1744 | 2198 | <A NAME="lua_ref"></A><A NAME="lua_getref"></A> |
| 1745 | 2199 | <A NAME="lua_unref"></A> |
| 1746 | 2200 | <PRE> |
| 1747 | −int lua_ref (int lock); | |
| 1748 | −lua_Object lua_getref (int ref); | |
| 1749 | −void lua_unref (int ref); | |
| 2201 | + int lua_ref (lua_State *L, int lock); | |
| 2202 | + int lua_getref (lua_State *L, int ref); | |
| 2203 | + void lua_unref (lua_State *L, int ref); | |
| 1750 | 2204 | </PRE> |
| 1751 | −The function <CODE>lua_ref</CODE> creates a reference | |
| 1752 | −to the object that is on the top of the stack, | |
| 2205 | +<P> | |
| 2206 | +<CODE>lua_ref</CODE> pops a value from | |
| 2207 | +the stack, creates a reference to it, | |
| 1753 | 2208 | and returns this reference. |
| 1754 | −If <CODE>lock</CODE> is true, the object is <EM>locked</EM>: | |
| 2209 | +For a <B>nil</B> value, | |
| 2210 | +the reference is always <CODE>LUA_REFNIL</CODE>.<A NAME="LUA_REFNIL"></A> | |
| 2211 | +(<CODE>lua.h</CODE> also defines a constant <CODE>LUA_NOREF</CODE> <A NAME="LUA_NOREF"></A> | |
| 2212 | +that | |
| 2213 | +is different from any valid reference.) | |
| 2214 | +If <CODE>lock</CODE> is not zero, then the object is <EM>locked</EM>: | |
| 1755 | 2215 | this means the object will not be garbage collected. |
| 1756 | −Note that an unlocked reference may be garbage collected. | |
| 1757 | −Whenever the referenced object is needed, | |
| 2216 | +<EM>Unlocked references may be garbage collected</EM>. | |
| 2217 | +<P> | |
| 2218 | +Whenever the referenced object is needed in C, | |
| 1758 | 2219 | a call to <CODE>lua_getref</CODE> |
| 1759 | −returns a handle to it; | |
| 2220 | +pushes that object onto the stack; | |
| 1760 | 2221 | if the object has been collected, |
| 1761 | −<CODE>lua_getref</CODE> returns <CODE>LUA_NOOBJECT</CODE>. | |
| 2222 | +<CODE>lua_getref</CODE> returns 0 (and does not push anything). | |
| 1762 | 2223 | <P> |
| 1763 | 2224 | When a reference is no longer needed, |
| 1764 | −it can be released with a call to <CODE>lua_unref</CODE>. | |
| 2225 | +it should be released with a call to <CODE>lua_unref</CODE>. | |
| 2226 | +<P> | |
| 2227 | +<P> | |
| 2228 | +<h3>Registry</h3> | |
| 1765 | 2229 | <P> |
| 2230 | +When Lua starts, it registers a table at position | |
| 2231 | +<A NAME="LUA_REFREGISTRY"><TT>LUA_REFREGISTRY</TT></A>. | |
| 2232 | +It can be accessed through the macro<A NAME="lua_getregistry"></A> | |
| 2233 | +<PRE> | |
| 2234 | + #define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY) | |
| 2235 | +</PRE> | |
| 2236 | +This table can be used by C libraries as a general registry mechanism. | |
| 2237 | +Any C library can store data into this table, | |
| 2238 | +as long as it chooses a key different from other libraries. | |
| 1766 | 2239 | <P> |
| 1767 | 2240 | <P> |
| 1768 | 2241 | <!-- ====================================================================== --> |
| 1769 | 2242 | <HR> |
| 1770 | 2243 | <A NAME="6."></A> |
| 1771 | −<H1>6 - Predefined Functions and Libraries</H1> | |
| 2244 | +<H1>6 - Standard Libraries</H1> | |
| 1772 | 2245 | <P> |
| 1773 | −The set of <A NAME="predefined functions">predefined functions</A> in Lua is small but powerful. | |
| 1774 | −Most of them provide features that allow some degree of | |
| 1775 | −<A NAME="reflexivity">reflexivity</A> in the language. | |
| 1776 | −Some of these features cannot be simulated with the rest of the | |
| 1777 | −language nor with the standard Lua API. | |
| 1778 | −Others are just convenient interfaces to common API functions. | |
| 1779 | −<P> | |
| 1780 | −The libraries, on the other hand, provide useful routines | |
| 2246 | +The standard libraries provide useful functions | |
| 1781 | 2247 | that are implemented directly through the standard API. |
| 1782 | 2248 | Therefore, they are not necessary to the language, |
| 1783 | −and are provided as separate C modules. | |
| 1784 | −Currently, there are three standard libraries: | |
| 2249 | +and are provided as separate C modules. | |
| 2250 | +Currently, Lua has the following standard libraries: | |
| 1785 | 2251 | <UL> |
| 2252 | +<LI>basic library; | |
| 1786 | 2253 | <LI>string manipulation; |
| 1787 | 2254 | <LI>mathematical functions (sin, log, etc); |
| 1788 | 2255 | <LI>input and output (plus some system facilities). |
| 1789 | 2256 | </UL> |
| 1790 | 2257 | To have access to these libraries, |
| 1791 | −the C host program must call the functions | |
| 2258 | +the C host program must call the functions | |
| 2259 | +<CODE>lua_baselibopen</CODE>, | |
| 1792 | 2260 | <CODE>lua_strlibopen</CODE>, <CODE>lua_mathlibopen</CODE>, |
| 1793 | −and <CODE>lua_iolibopen</CODE>, declared in <CODE>lualib.h</CODE>. | |
| 1794 | −<A NAME="lua_strlibopen"></A><A NAME="lua_mathlibopen"></A><A NAME="lua_iolibopen"></A> | |
| 1795 | −<P> | |
| 2261 | +and <CODE>lua_iolibopen</CODE>, which are declared in <CODE>lualib.h</CODE>. | |
| 2262 | +<A NAME="lua_baselibopen"></A> | |
| 2263 | +<A NAME="lua_strlibopen"></A> | |
| 2264 | +<A NAME="lua_mathlibopen"></A> | |
| 2265 | +<A NAME="lua_iolibopen"></A> | |
| 1796 | 2266 | <P> |
| 1797 | 2267 | <A NAME="predefined"></A> |
| 1798 | 2268 | <A NAME="6.1"></A> |
| 1799 | −<H2>6.1 - Predefined Functions</H2> | |
| 2269 | +<H2>6.1 - Basic Functions</H2> | |
| 2270 | +<P> | |
| 2271 | +The basic library provides some core functions to Lua. | |
| 2272 | +Therefore, if you do not include this library in your application, | |
| 2273 | +you should check carefully whether you need to provide some alternative | |
| 2274 | +implementation for some facilities. | |
| 2275 | +(For instance, | |
| 2276 | +without function <CODE>_ERRORMESSAGE</CODE>, | |
| 2277 | +Lua is unable to show error messages.) | |
| 2278 | +<P> | |
| 2279 | +<A NAME="alert"></A> | |
| 2280 | +<h3> <TT>_ALERT (message)</TT></h3><A NAME="alert"></A> | |
| 2281 | +Prints its only string argument to <A NAME="stderr"><TT>stderr</TT></A>. | |
| 2282 | +All error messages in Lua are printed through the function stored | |
| 2283 | +in the <CODE>_ALERT</CODE> global variable | |
| 2284 | +(see Section <A HREF="#error">4.7</A>). | |
| 2285 | +Therefore, a program may assign another function to this variable | |
| 2286 | +to change the way such messages are shown | |
| 2287 | +(for instance, for systems without <CODE>stderr</CODE>). | |
| 2288 | +<P> | |
| 2289 | +<h3> <TT>assert (v [, message])</TT></h3><A NAME="assert"></A> | |
| 2290 | +Issues an <EM>``assertion failed!''</EM> error | |
| 2291 | +when its argument <CODE>v</CODE> is <B>nil</B>. | |
| 2292 | +This function is equivalent to the following Lua function: | |
| 2293 | +<PRE> | |
| 2294 | + function assert (v, m) | |
| 2295 | + if not v then | |
| 2296 | + m = m or "" | |
| 2297 | + error("assertion failed! " .. m) | |
| 2298 | + end | |
| 2299 | + end | |
| 2300 | +</PRE> | |
| 1800 | 2301 | <P> |
| 1801 | 2302 | <h3> <TT>call (func, arg [, mode [, errhandler]])</TT></h3><A NAME="call"></A> |
| 1802 | 2303 | <A NAME="pdf-call"></A> |
| @@ -1805,29 +2306,13 @@ Calls function <CODE>func</CODE> with · 2 unmodified lines | ||
| 1805 | 2306 | the arguments given by the table <CODE>arg</CODE>. |
| 1806 | 2307 | The call is equivalent to |
| 1807 | 2308 | <PRE> |
| 1808 | − func(arg[1], arg[2], ..., arg[n]) | |
| 2309 | + func(arg[1], arg[2], ..., arg[n]) | |
| 1809 | 2310 | </PRE> |
| 1810 | 2311 | where <CODE>n</CODE> is the result of <CODE>getn(arg)</CODE> (see Section <A HREF="#getn">6.1</A>). |
| 2312 | +All results from <CODE>func</CODE> are simply returned by <CODE>call</CODE>. | |
| 1811 | 2313 | <P> |
| 1812 | 2314 | By default, |
| 1813 | −all results from <CODE>func</CODE> are just returned by the call. | |
| 1814 | −If the string <CODE>mode</CODE> contains <CODE>"p"</CODE>, | |
| 1815 | −the results are <EM>packed</EM> in a single table.<A NAME="packed results"></A> | |
| 1816 | −That is, <CODE>call</CODE> returns just one table; | |
| 1817 | −at index <CODE>n</CODE>, the table has the total number of results | |
| 1818 | −from the call; | |
| 1819 | −the first result is at index 1, etc. | |
| 1820 | −For instance, the following calls produce the following results: | |
| 1821 | −<PRE> | |
| 1822 | −a = call(sin, {5}) --> a = 0.0871557 = sin(5) | |
| 1823 | −a = call(max, {1,4,5; n=2}) --> a = 4 (only 1 and 4 are arguments) | |
| 1824 | −a = call(max, {1,4,5; n=2}, "p") --> a = {4; n=1} | |
| 1825 | −t = {x=1} | |
| 1826 | −a = call(next, {t,nil;n=2}, "p") --> a={"x", 1; n=2} | |
| 1827 | −</PRE> | |
| 1828 | −<P> | |
| 1829 | −By default, | |
| 1830 | −if an error occurs during the function call, | |
| 2315 | +if an error occurs during the call to <CODE>func</CODE>, | |
| 1831 | 2316 | the error is propagated. |
| 1832 | 2317 | If the string <CODE>mode</CODE> contains <CODE>"x"</CODE>, |
| 1833 | 2318 | then the call is <EM>protected</EM>.<A NAME="protected calls"></A> |
| @@ -1836,96 +2321,168 @@ regardless of what happens during the call. · 2 unmodified lines | ||
| 1836 | 2321 | Instead, it returns <B>nil</B> to signal the error |
| 1837 | 2322 | (besides calling the appropriated error handler). |
| 1838 | 2323 | <P> |
| 1839 | −If provided, | |
| 1840 | −<CODE>errhandler</CODE> is temporarily set as the error function | |
| 1841 | −<CODE>_ERRORMESSAGE</CODE>, while <CODE>func</CODE> runs. | |
| 2324 | +If <CODE>errhandler</CODE> is provided, | |
| 2325 | +the error function <CODE>_ERRORMESSAGE</CODE> is temporarily set to <CODE>errhandler</CODE>, | |
| 2326 | +while <CODE>func</CODE> runs. | |
| 1842 | 2327 | In particular, if <CODE>errhandler</CODE> is <B>nil</B>, |
| 1843 | 2328 | no error messages will be issued during the execution of the called function. |
| 1844 | 2329 | <P> |
| 1845 | 2330 | <h3> <TT>collectgarbage ([limit])</TT></h3><A NAME="collectgarbage"></A> |
| 1846 | −Forces a garbage collection cycle. | |
| 1847 | −Returns the number of objects collected. | |
| 1848 | −An optional argument, <CODE>limit</CODE>, is a number that | |
| 1849 | −makes the next cycle occur only after that number of new | |
| 1850 | −objects have been created. | |
| 1851 | −If <CODE>limit</CODE> is absent or equal to 0, | |
| 1852 | −Lua uses an adaptive algorithm to set this limit. | |
| 1853 | −<CODE>collectgarbage</CODE> is equivalent to | |
| 1854 | −the API function <CODE>lua_collectgarbage</CODE>. | |
| 2331 | +<P> | |
| 2332 | +Sets the garbage-collection threshold for the given limit | |
| 2333 | +(in Kbytes), and checks it against the byte counter. | |
| 2334 | +If the new threshold is smaller than the byte counter, | |
| 2335 | +then Lua immediately runs the garbage collector (see Section <A HREF="#GC">5.6</A>). | |
| 2336 | +If <CODE>limit</CODE> is absent, it defaults to zero | |
| 2337 | +(thus forcing a garbage-collection cycle). | |
| 2338 | +<P> | |
| 2339 | +<h3> <TT>copytagmethods (tagto, tagfrom)</TT></h3> | |
| 2340 | +<A NAME="copytagmethods"></A> | |
| 2341 | +Copies all tag methods from one tag to another; | |
| 2342 | +returns <CODE>tagto</CODE>. | |
| 1855 | 2343 | <P> |
| 1856 | 2344 | <h3> <TT>dofile (filename)</TT></h3><A NAME="dofile"></A> |
| 1857 | 2345 | Receives a file name, |
| 1858 | −opens the file, and executes the file contents as a Lua chunk, | |
| 2346 | +opens the named file, and executes its contents as a Lua chunk, | |
| 1859 | 2347 | or as pre-compiled chunks. |
| 1860 | 2348 | When called without arguments, |
| 1861 | 2349 | <CODE>dofile</CODE> executes the contents of the standard input (<CODE>stdin</CODE>). |
| 1862 | 2350 | If there is any error executing the file, |
| 1863 | 2351 | then <CODE>dofile</CODE> returns <B>nil</B>. |
| 1864 | 2352 | Otherwise, it returns the values returned by the chunk, |
| 1865 | −or a non <B>nil</B> value if the chunk returns no values. | |
| 1866 | −It issues an error when called with a non string argument. | |
| 1867 | −<CODE>dofile</CODE> is equivalent to the API function <CODE>lua_dofile</CODE>. | |
| 2353 | +or a non-<B>nil</B> value if the chunk returns no values. | |
| 2354 | +It issues an error when called with a non-string argument. | |
| 1868 | 2355 | <P> |
| 1869 | 2356 | <h3> <TT>dostring (string [, chunkname])</TT></h3><A NAME="dostring"></A> |
| 1870 | 2357 | Executes a given string as a Lua chunk. |
| 1871 | 2358 | If there is any error executing the string, |
| 1872 | −<CODE>dostring</CODE> returns <B>nil</B>. | |
| 2359 | +then <CODE>dostring</CODE> returns <B>nil</B>. | |
| 1873 | 2360 | Otherwise, it returns the values returned by the chunk, |
| 1874 | −or a non <B>nil</B> value if the chunk returns no values. | |
| 1875 | −An optional second parameter (<CODE>chunkname</CODE>) | |
| 2361 | +or a non-<B>nil</B> value if the chunk returns no values. | |
| 2362 | +The optional parameter <CODE>chunkname</CODE> | |
| 1876 | 2363 | is the ``name of the chunk'', |
| 1877 | 2364 | used in error messages and debug information. |
| 1878 | −<CODE>dostring</CODE> is equivalent to the API function <CODE>lua_dostring</CODE>. | |
| 1879 | −<P> | |
| 1880 | −<A NAME="pdf-newtag"></A> | |
| 1881 | −<h3> <TT>newtag ()</TT></h3><A NAME="newtag"></A> | |
| 1882 | −Returns a new tag. | |
| 1883 | −<CODE>newtag</CODE> is equivalent to the API function <CODE>lua_newtag</CODE>. | |
| 1884 | 2365 | <P> |
| 1885 | −<h3> <TT>next (table, index)</TT></h3><A NAME="next"></A> | |
| 1886 | −Allows a program to traverse all fields of a table. | |
| 1887 | −Its first argument is a table and its second argument | |
| 1888 | −is an index in this table. | |
| 1889 | −It returns the next index of the table and the | |
| 1890 | −value associated with the index. | |
| 1891 | −When called with <B>nil</B> as its second argument, | |
| 1892 | −the function returns the first index | |
| 1893 | −of the table (and its associated value). | |
| 1894 | −When called with the last index, | |
| 1895 | −or with <B>nil</B> in an empty table, | |
| 1896 | −it returns <B>nil</B>. | |
| 2366 | +<A NAME="pdf-error"></A> | |
| 2367 | +<h3> <TT>error (message)</TT></h3><A NAME="error"></A> | |
| 2368 | +Calls the error handler (see Section <A HREF="#error">4.7</A>) and then terminates | |
| 2369 | +the last protected function called | |
| 2370 | +(in C: <CODE>lua_dofile</CODE>, <CODE>lua_dostring</CODE>, | |
| 2371 | +<CODE>lua_dobuffer</CODE>, or <CODE>lua_callfunction</CODE>; | |
| 2372 | +in Lua: <CODE>dofile</CODE>, <CODE>dostring</CODE>, or <CODE>call</CODE> in protected mode). | |
| 2373 | +If <CODE>message</CODE> is <B>nil</B>, then the error handler is not called. | |
| 2374 | +Function <CODE>error</CODE> never returns. | |
| 1897 | 2375 | <P> |
| 1898 | −Lua has no declaration of fields; | |
| 2376 | +<h3> <TT>foreach (table, func)</TT></h3><A NAME="foreach"></A> | |
| 2377 | +Executes the given <CODE>func</CODE> over all elements of <CODE>table</CODE>. | |
| 2378 | +For each element, the function is called with the index and | |
| 2379 | +respective value as arguments. | |
| 2380 | +If the function returns any non-<B>nil</B> value, | |
| 2381 | +then the loop is broken, and this value is returned | |
| 2382 | +as the final value of <CODE>foreach</CODE>. | |
| 2383 | +This function could be defined in Lua: | |
| 2384 | +<PRE> | |
| 2385 | + function foreach (t, f) | |
| 2386 | + for i, v in t do | |
| 2387 | + local res = f(i, v) | |
| 2388 | + if res then return res end | |
| 2389 | + end | |
| 2390 | + end | |
| 2391 | +</PRE> | |
| 2392 | +<P> | |
| 2393 | +The behavior of <CODE>foreach</CODE> is <EM>undefined</EM> if you change | |
| 2394 | +the table <CODE>t</CODE> during the traversal. | |
| 2395 | +<P> | |
| 2396 | +<P> | |
| 2397 | +<h3> <TT>foreachi (table, func)</TT></h3><A NAME="foreachi"></A> | |
| 2398 | +Executes the given <CODE>func</CODE> over the | |
| 2399 | +numerical indices of <CODE>table</CODE>. | |
| 2400 | +For each index, the function is called with the index and | |
| 2401 | +respective value as arguments. | |
| 2402 | +Indices are visited in sequential order, | |
| 2403 | +from 1 to <CODE>n</CODE>, | |
| 2404 | +where <CODE>n</CODE> is the result of <CODE>getn(table)</CODE> (see Section <A HREF="#getn">6.1</A>). | |
| 2405 | +If the function returns any non-<B>nil</B> value, | |
| 2406 | +then the loop is broken, and this value is returned | |
| 2407 | +as the final value of <CODE>foreachi</CODE>. | |
| 2408 | +This function could be defined in Lua: | |
| 2409 | +<PRE> | |
| 2410 | + function foreachi (t, f) | |
| 2411 | + for i=1,getn(t) do | |
| 2412 | + local res = f(i, t[i]) | |
| 2413 | + if res then return res end | |
| 2414 | + end | |
| 2415 | + end | |
| 2416 | +</PRE> | |
| 2417 | +<P> | |
| 2418 | +<P> | |
| 2419 | +<h3> <TT>getglobal (name)</TT></h3><A NAME="getglobal"></A> | |
| 2420 | +Gets the value of a global variable, | |
| 2421 | +or calls a tag method for ``getglobal''. | |
| 2422 | +Its full semantics is explained in Section <A HREF="#tag-method">4.8</A>. | |
| 2423 | +The string <CODE>name</CODE> does not need to be a | |
| 2424 | +syntactically valid variable name. | |
| 2425 | +<P> | |
| 2426 | +<A NAME="getn"></A> | |
| 2427 | +<h3> <TT>getn (table)</TT></h3><A NAME="getn"></A> | |
| 2428 | +Returns the ``size'' of a table, when seen as a list. | |
| 2429 | +If the table has an <CODE>n</CODE> field with a numeric value, | |
| 2430 | +this value is the ``size'' of the table. | |
| 2431 | +Otherwise, the ``size'' is the largest numerical index with a non-nil | |
| 2432 | +value in the table. | |
| 2433 | +This function could be defined in Lua: | |
| 2434 | +<PRE> | |
| 2435 | + function getn (t) | |
| 2436 | + if type(t.n) == "number" then return t.n end | |
| 2437 | + local max = 0 | |
| 2438 | + for i, _ in t do | |
| 2439 | + if type(i) == "number" and i>max then max=i end | |
| 2440 | + end | |
| 2441 | + return max | |
| 2442 | + end | |
| 2443 | +</PRE> | |
| 2444 | +<P> | |
| 2445 | +<h3> <TT>gettagmethod (tag, event)</TT></h3> | |
| 2446 | +<A NAME="gettagmethod"></A> | |
| 2447 | +Returns the current tag method | |
| 2448 | +for a given pair <EM>(tag, event)</EM>. | |
| 2449 | +This function cannot be used to get a tag method for the ``gc'' event. | |
| 2450 | +(Such tag methods can only be manipulated by C code.) | |
| 2451 | +<P> | |
| 2452 | +<h3> <TT>globals ([table])</TT></h3><A NAME="globals"></A> | |
| 2453 | +Returns the current table of globals. | |
| 2454 | +If the argument <CODE>table</CODE> is given, | |
| 2455 | +then it also sets this table as the table of globals. | |
| 2456 | +<P> | |
| 2457 | +<A NAME="pdf-newtag"></A> | |
| 2458 | +<h3> <TT>newtag ()</TT></h3><A NAME="newtag"></A> | |
| 2459 | +Returns a new tag. | |
| 2460 | +<P> | |
| 2461 | +<h3> <TT>next (table, [index])</TT></h3><A NAME="next"></A> | |
| 2462 | +Allows a program to traverse all fields of a table. | |
| 2463 | +Its first argument is a table and its second argument | |
| 2464 | +is an index in this table. | |
| 2465 | +<CODE>next</CODE> returns the next index of the table and the | |
| 2466 | +value associated with the index. | |
| 2467 | +When called with <B>nil</B> as its second argument, | |
| 2468 | +<CODE>next</CODE> returns the first index | |
| 2469 | +of the table and its associated value. | |
| 2470 | +When called with the last index, | |
| 2471 | +or with <B>nil</B> in an empty table, | |
| 2472 | +<CODE>next</CODE> returns <B>nil</B>. | |
| 2473 | +If the second argument is absent, then it is interpreted as <B>nil</B>. | |
| 2474 | +<P> | |
| 2475 | +Lua has no declaration of fields; | |
| 1899 | 2476 | semantically, there is no difference between a |
| 1900 | 2477 | field not present in a table or a field with value <B>nil</B>. |
| 1901 | −Therefore, the function only considers fields with non <B>nil</B> values. | |
| 2478 | +Therefore, <CODE>next</CODE> only considers fields with non-<B>nil</B> values. | |
| 1902 | 2479 | The order in which the indices are enumerated is not specified, |
| 1903 | 2480 | <EM>even for numeric indices</EM> |
| 1904 | 2481 | (to traverse a table in numeric order, |
| 1905 | −use a counter or the function <CODE>foreachi</CODE>). | |
| 1906 | −If the table indices are modified in any way during a traversal, | |
| 1907 | −the semantics of <CODE>next</CODE> is undefined. | |
| 1908 | −<P> | |
| 1909 | −This function cannot be written with the standard API. | |
| 2482 | +use a numerical <B>for</B> or the function <CODE>foreachi</CODE>). | |
| 1910 | 2483 | <P> |
| 1911 | −<h3> <TT>nextvar (name)</TT></h3><A NAME="nextvar"></A> | |
| 1912 | −This function is similar to the function <CODE>next</CODE>, | |
| 1913 | −but iterates instead over the global variables. | |
| 1914 | −Its single argument is the name of a global variable, | |
| 1915 | −or <B>nil</B> to get a first name. | |
| 1916 | −Similarly to <CODE>next</CODE>, it returns the name of another variable | |
| 1917 | −and its value, | |
| 1918 | −or <B>nil</B> if there are no more variables. | |
| 1919 | −There can be no creation of new global variables during the traversal; | |
| 1920 | −otherwise the semantics of <CODE>nextvar</CODE> is undefined. | |
| 1921 | −<P> | |
| 1922 | −This function cannot be written with the standard API. | |
| 1923 | −<P> | |
| 1924 | −<h3> <TT>tostring (e)</TT></h3><A NAME="tostring"></A> | |
| 1925 | −Receives an argument of any type and | |
| 1926 | −converts it to a string in a reasonable format. | |
| 1927 | −For complete control on how numbers are converted, | |
| 1928 | −use function <CODE>format</CODE>. | |
| 2484 | +The behavior of <CODE>next</CODE> is <EM>undefined</EM> if you change | |
| 2485 | +the table during the traversal. | |
| 1929 | 2486 | <P> |
| 1930 | 2487 | <h3> <TT>print (e1, e2, ...)</TT></h3><A NAME="print"></A> |
| 1931 | 2488 | Receives any number of arguments, |
| @@ -1935,342 +2492,225 @@ but only as a quick way to show a value, · 3 unmodified lines | ||
| 1935 | 2492 | for instance for debugging. |
| 1936 | 2493 | See Section <A HREF="#libio">6.4</A> for functions for formatted output. |
| 1937 | 2494 | <P> |
| 1938 | −<A NAME="alert"></A> | |
| 1939 | −<h3> <TT>_ALERT (message)</TT></h3><A NAME="alert"></A> | |
| 1940 | −Prints its only string argument to <A NAME="stderr"><TT>stderr</TT></A>. | |
| 1941 | −All error messages in Lua are printed through this function. | |
| 1942 | −Therefore, a program may redefine it | |
| 1943 | −to change the way such messages are shown | |
| 1944 | −(for instance, for systems without <CODE>stderr</CODE>). | |
| 1945 | −<P> | |
| 1946 | −<h3> <TT>tonumber (e [, base])</TT></h3><A NAME="tonumber"></A> | |
| 1947 | −Receives one argument, | |
| 1948 | −and tries to convert it to a number. | |
| 1949 | −If the argument is already a number or a string convertible | |
| 1950 | −to a number, then <CODE>tonumber</CODE> returns that number; | |
| 1951 | −otherwise, it returns <B>nil</B>. | |
| 1952 | −<P> | |
| 1953 | −An optional argument specifies the base to interpret the numeral. | |
| 1954 | −The base may be any integer between 2 and 36 inclusive. | |
| 1955 | −In bases above 10, the letter `A' (either upper or lower case) | |
| 1956 | −represents 10, `B' represents 11, and so forth, with `Z' representing 35. | |
| 1957 | −<P> | |
| 1958 | −In base 10 (the default), the number may have a decimal part, | |
| 1959 | −as well as an optional exponent part (see Section <A HREF="#coercion">4.3</A>). | |
| 1960 | −In other bases, only integers are accepted. | |
| 1961 | −<P> | |
| 1962 | −<A NAME="pdf-type"></A> | |
| 1963 | −<h3> <TT>type (v)</TT></h3><A NAME="type"></A> | |
| 1964 | −Allows Lua to test the type of a value. | |
| 1965 | −It receives one argument, and returns its type, coded as a string. | |
| 1966 | −The possible results of this function are | |
| 1967 | −<CODE>"nil"</CODE> (a string, not the value <B>nil</B>), | |
| 1968 | −<CODE>"number"</CODE>, | |
| 1969 | −<CODE>"string"</CODE>, | |
| 1970 | −<CODE>"table"</CODE>, | |
| 1971 | −<CODE>"function"</CODE>, | |
| 1972 | −and <CODE>"userdata"</CODE>. | |
| 1973 | −<P> | |
| 1974 | −<h3> <TT>tag (v)</TT></h3><A NAME="tag"></A> | |
| 1975 | −Allows Lua to test the tag of a value (see Section <A HREF="#TypesSec">3</A>). | |
| 1976 | −It receives one argument, and returns its tag (a number). | |
| 1977 | −<CODE>tag</CODE> is equivalent to the API function <CODE>lua_tag</CODE>. | |
| 1978 | −<P> | |
| 1979 | −<h3> <TT>settag (t, tag)</TT></h3><A NAME="settag"></A> | |
| 1980 | −Sets the tag of a given table (see Section <A HREF="#TypesSec">3</A>). | |
| 1981 | −<CODE>tag</CODE> must be a value created with <CODE>newtag</CODE> | |
| 1982 | −(see Section <A HREF="#pdf-newtag">6.1</A>). | |
| 1983 | −It returns the value of its first argument (the table). | |
| 1984 | −For security reasons, | |
| 1985 | −it is impossible to change the tag of a userdata from Lua. | |
| 1986 | −<P> | |
| 1987 | −<P> | |
| 1988 | −<h3> <TT>assert (v [, message])</TT></h3><A NAME="assert"></A> | |
| 1989 | −Issues an <EM>``assertion failed!''</EM> error | |
| 1990 | −when its argument is <B>nil</B>. | |
| 1991 | −This function is equivalent to the following Lua function: | |
| 1992 | −<PRE> | |
| 1993 | − function assert (v, m) | |
| 1994 | − if not v then | |
| 1995 | − m = m or "" | |
| 1996 | − error("assertion failed! " .. m) | |
| 1997 | − end | |
| 1998 | − end | |
| 1999 | −</PRE> | |
| 2000 | −<P> | |
| 2001 | −<A NAME="pdf-error"></A> | |
| 2002 | −<h3> <TT>error (message)</TT></h3><A NAME="error"></A> | |
| 2003 | −Calls the error handler and then terminates | |
| 2004 | −the last protected function called | |
| 2005 | −(in C: <CODE>lua_dofile</CODE>, <CODE>lua_dostring</CODE>, | |
| 2006 | −<CODE>lua_dobuffer</CODE>, or <CODE>lua_callfunction</CODE>; | |
| 2007 | −in Lua: <CODE>dofile</CODE>, <CODE>dostring</CODE>, or <CODE>call</CODE> in protected mode). | |
| 2008 | −If <CODE>message</CODE> is <B>nil</B>, the error handler is not called. | |
| 2009 | −Function <CODE>error</CODE> never returns. | |
| 2010 | −<CODE>error</CODE> is equivalent to the API function <CODE>lua_error</CODE>. | |
| 2011 | −<P> | |
| 2012 | −<h3> <TT>rawgettable (table, index)</TT></h3><A NAME="rawgettable"></A> | |
| 2495 | +<h3> <TT>rawget (table, index)</TT></h3><A NAME="rawget"></A> | |
| 2013 | 2496 | Gets the real value of <CODE>table[index]</CODE>, |
| 2014 | 2497 | without invoking any tag method. |
| 2015 | 2498 | <CODE>table</CODE> must be a table, |
| 2016 | 2499 | and <CODE>index</CODE> is any value different from <B>nil</B>. |
| 2017 | 2500 | <P> |
| 2018 | −<h3> <TT>rawsettable (table, index, value)</TT></h3><A NAME="rawsettable"></A> | |
| 2501 | +<h3> <TT>rawset (table, index, value)</TT></h3><A NAME="rawset"></A> | |
| 2019 | 2502 | Sets the real value of <CODE>table[index]</CODE> to <CODE>value</CODE>, |
| 2020 | 2503 | without invoking any tag method. |
| 2021 | 2504 | <CODE>table</CODE> must be a table, |
| 2022 | 2505 | <CODE>index</CODE> is any value different from <B>nil</B>, |
| 2023 | 2506 | and <CODE>value</CODE> is any Lua value. |
| 2024 | 2507 | <P> |
| 2025 | −<h3> <TT>rawsetglobal (name, value)</TT></h3><A NAME="rawsetglobal"></A> | |
| 2026 | −Assigns the given value to a global variable. | |
| 2027 | −The string <CODE>name</CODE> does not need to be a | |
| 2028 | −syntactically valid variable name. | |
| 2029 | −Therefore, | |
| 2030 | −this function can set global variables with strange names like | |
| 2031 | −<CODE>"m v 1"</CODE> or <CODE>34</CODE>. | |
| 2032 | −Function <CODE>rawsetglobal</CODE> returns the value of its second argument. | |
| 2033 | −<P> | |
| 2034 | 2508 | <h3> <TT>setglobal (name, value)</TT></h3><A NAME="setglobal"></A> |
| 2035 | −Assigns the given value to a global variable, | |
| 2036 | −or calls a tag method. | |
| 2509 | +Sets the named global variable to the given value, | |
| 2510 | +or calls a tag method for ``setglobal''. | |
| 2037 | 2511 | Its full semantics is explained in Section <A HREF="#tag-method">4.8</A>. |
| 2038 | 2512 | The string <CODE>name</CODE> does not need to be a |
| 2039 | 2513 | syntactically valid variable name. |
| 2040 | −Function <CODE>setglobal</CODE> returns the value of its second argument. | |
| 2041 | −<P> | |
| 2042 | −<h3> <TT>rawgetglobal (name)</TT></h3><A NAME="rawgetglobal"></A> | |
| 2043 | −Retrieves the value of a global variable. | |
| 2044 | −The string <CODE>name</CODE> does not need to be a | |
| 2045 | −syntactically valid variable name. | |
| 2046 | 2514 | <P> |
| 2047 | −<h3> <TT>getglobal (name)</TT></h3><A NAME="getglobal"></A> | |
| 2048 | −Retrieves the value of a global variable, | |
| 2049 | −or calls a tag method. | |
| 2050 | −Its full semantics is explained in Section <A HREF="#tag-method">4.8</A>. | |
| 2051 | −The string <CODE>name</CODE> does not need to be a | |
| 2052 | −syntactically valid variable name. | |
| 2515 | +<h3> <TT>settag (t, tag)</TT></h3><A NAME="settag"></A> | |
| 2516 | +Sets the tag of a given table (see Section <A HREF="#TypesSec">3</A>). | |
| 2517 | +<CODE>tag</CODE> must be a value created with <CODE>newtag</CODE> | |
| 2518 | +(see Section <A HREF="#pdf-newtag">6.1</A>). | |
| 2519 | +<CODE>settag</CODE> returns the value of its first argument (the table). | |
| 2520 | +For the safety of host programs, | |
| 2521 | +it is impossible to change the tag of a userdata from Lua. | |
| 2053 | 2522 | <P> |
| 2054 | 2523 | <h3> <TT>settagmethod (tag, event, newmethod)</TT></h3> |
| 2055 | 2524 | <A NAME="settagmethod"></A> |
| 2056 | −Sets a new tag method to the given pair <EM>(tag, event)</EM>. | |
| 2057 | −It returns the old method. | |
| 2525 | +Sets a new tag method to the given pair <EM>(tag, event)</EM> and | |
| 2526 | +returns the old method. | |
| 2058 | 2527 | If <CODE>newmethod</CODE> is <B>nil</B>, |
| 2059 | −<CODE>settagmethod</CODE> restores the default behavior for the given event. | |
| 2060 | −<P> | |
| 2061 | −<h3> <TT>gettagmethod (tag, event)</TT></h3> | |
| 2062 | −<A NAME="gettagmethod"></A> | |
| 2063 | −Returns the current tag method | |
| 2064 | −for a given pair <EM>(tag, event)</EM>. | |
| 2065 | −<P> | |
| 2066 | −<h3> <TT>copytagmethods (tagto, tagfrom)</TT></h3> | |
| 2067 | −<A NAME="copytagmethods"></A> | |
| 2068 | −Copies all tag methods from one tag to another; | |
| 2069 | −it returns <CODE>tagto</CODE>. | |
| 2070 | −<P> | |
| 2071 | −<A NAME="getn"></A> | |
| 2072 | −<h3> <TT>getn (table)</TT></h3><A NAME="getn"></A> | |
| 2073 | −Returns the ``size'' of a table, when seen as a list. | |
| 2074 | −If the table has an <CODE>n</CODE> field with a numeric value, | |
| 2075 | −this is its ``size''. | |
| 2076 | −Otherwise, the size is the largest numerical index with a non-nil | |
| 2077 | −value in the table. | |
| 2078 | −This function could be defined in Lua: | |
| 2079 | −<PRE> | |
| 2080 | − function getn (t) | |
| 2081 | − if type(t.n) == 'number' then return t.n end | |
| 2082 | − local max = 0 | |
| 2083 | − local i = next(t, nil) | |
| 2084 | − while i do | |
| 2085 | − if type(i) == 'number' and i>max then max=i end | |
| 2086 | − i = next(t, i) | |
| 2087 | − end | |
| 2088 | − return max | |
| 2089 | − end | |
| 2090 | −</PRE> | |
| 2528 | +then <CODE>settagmethod</CODE> restores the default behavior for the given event. | |
| 2529 | +This function cannot be used to set a tag method for the ``gc'' event. | |
| 2530 | +(Such tag methods can only be manipulated by C code.) | |
| 2091 | 2531 | <P> |
| 2532 | +<h3> <TT>sort (table [, comp])</TT></h3><A NAME="sort"></A> | |
| 2533 | +Sorts table elements in a given order, <EM>in-place</EM>, | |
| 2534 | +from <CODE>table[1]</CODE> to <CODE>table[n]</CODE>, | |
| 2535 | +where <CODE>n</CODE> is the result of <CODE>getn(table)</CODE> (see Section <A HREF="#getn">6.1</A>). | |
| 2536 | +If <CODE>comp</CODE> is given, | |
| 2537 | +then it must be a function that receives two table elements, | |
| 2538 | +and returns true (that is, a value different from <B>nil</B>) | |
| 2539 | +when the first is less than the second | |
| 2540 | +(so that <CODE>not comp(a[i+1], a[i])</CODE> will be true after the sort). | |
| 2541 | +If <CODE>comp</CODE> is not given, | |
| 2542 | +then the standard Lua operator <CODE><</CODE> is used instead. | |
| 2092 | 2543 | <P> |
| 2093 | −<h3> <TT>foreach (table, function)</TT></h3><A NAME="foreach"></A> | |
| 2094 | −Executes the given <CODE>function</CODE> over all elements of <CODE>table</CODE>. | |
| 2095 | −For each element, the function is called with the index and | |
| 2096 | −respective value as arguments. | |
| 2097 | −If the function returns any non-<B>nil</B> value, | |
| 2098 | −the loop is broken, and the value is returned | |
| 2099 | −as the final value of <CODE>foreach</CODE>. | |
| 2544 | +The sort algorithm is <EM>not</EM> stable | |
| 2545 | +(that is, elements considered equal by the given order | |
| 2546 | +may have their relative positions changed by the sort). | |
| 2100 | 2547 | <P> |
| 2101 | −This function could be defined in Lua: | |
| 2102 | −<PRE> | |
| 2103 | − function foreach (t, f) | |
| 2104 | − local i, v = next(t, nil) | |
| 2105 | − while i do | |
| 2106 | − local res = f(i, v) | |
| 2107 | − if res then return res end | |
| 2108 | − i, v = next(t, i) | |
| 2109 | − end | |
| 2110 | − end | |
| 2111 | −</PRE> | |
| 2548 | +<A NAME="pdf-tag"></A> | |
| 2549 | +<h3> <TT>tag (v)</TT></h3><A NAME="tag"></A> | |
| 2550 | +Allows Lua programs to test the tag of a value (see Section <A HREF="#TypesSec">3</A>). | |
| 2551 | +It receives one argument, and returns its tag (a number). | |
| 2112 | 2552 | <P> |
| 2553 | +<h3> <TT>tonumber (e [, base])</TT></h3><A NAME="tonumber"></A> | |
| 2554 | +Tries to convert its argument to a number. | |
| 2555 | +If the argument is already a number or a string convertible | |
| 2556 | +to a number, then <CODE>tonumber</CODE> returns that number; | |
| 2557 | +otherwise, it returns <B>nil</B>. | |
| 2113 | 2558 | <P> |
| 2114 | −<h3> <TT>foreachi (table, function)</TT></h3><A NAME="foreachi"></A> | |
| 2115 | −Executes the given <CODE>function</CODE> over the | |
| 2116 | −numerical indices of <CODE>table</CODE>. | |
| 2117 | −For each index, the function is called with the index and | |
| 2118 | −respective value as arguments. | |
| 2119 | −Indices are visited in sequential order, | |
| 2120 | −from 1 to <CODE>n</CODE>, | |
| 2121 | −where <CODE>n</CODE> is the result of <CODE>getn(table)</CODE> (see Section <A HREF="#getn">6.1</A>). | |
| 2122 | −If the function returns any non-<B>nil</B> value, | |
| 2123 | −the loop is broken, and the value is returned | |
| 2124 | −as the final value of <CODE>foreachi</CODE>. | |
| 2559 | +An optional argument specifies the base to interpret the numeral. | |
| 2560 | +The base may be any integer between 2 and 36, inclusive. | |
| 2561 | +In bases above 10, the letter `A' (either upper or lower case) | |
| 2562 | +represents 10, `B' represents 11, and so forth, with `Z' representing 35. | |
| 2563 | +In base 10 (the default), the number may have a decimal part, | |
| 2564 | +as well as an optional exponent part (see Section <A HREF="#coercion">4.2</A>). | |
| 2565 | +In other bases, only unsigned integers are accepted. | |
| 2125 | 2566 | <P> |
| 2126 | −This function could be defined in Lua: | |
| 2127 | −<PRE> | |
| 2128 | − function foreachi (t, f) | |
| 2129 | − local i, n = 1, getn(t) | |
| 2130 | − while i <= n do | |
| 2131 | − local res = f(i, t[i]) | |
| 2132 | − if res then return res end | |
| 2133 | − i = i+1 | |
| 2134 | − end | |
| 2135 | − end | |
| 2136 | −</PRE> | |
| 2567 | +<h3> <TT>tostring (e)</TT></h3><A NAME="tostring"></A> | |
| 2568 | +Receives an argument of any type and | |
| 2569 | +converts it to a string in a reasonable format. | |
| 2570 | +For complete control of how numbers are converted, | |
| 2571 | +use function <CODE>format</CODE>. | |
| 2137 | 2572 | <P> |
| 2138 | −<h3> <TT>foreachvar (function)</TT></h3><A NAME="foreachvar"></A> | |
| 2139 | −Executes <CODE>function</CODE> over all global variables. | |
| 2140 | −For each variable, | |
| 2141 | −the function is called with its name and its value as arguments. | |
| 2142 | −If the function returns any non-nil value, | |
| 2143 | −the loop is broken, and the value is returned | |
| 2144 | −as the final value of <CODE>foreachvar</CODE>. | |
| 2145 | 2573 | <P> |
| 2146 | −This function could be defined in Lua: | |
| 2147 | −<PRE> | |
| 2148 | − function foreachvar (f) | |
| 2149 | − local n, v = nextvar(nil) | |
| 2150 | − while n do | |
| 2151 | − local res = f(n, v) | |
| 2152 | − if res then return res end | |
| 2153 | − n, v = nextvar(n) | |
| 2154 | − end | |
| 2155 | − end | |
| 2156 | −</PRE> | |
| 2157 | 2574 | <P> |
| 2158 | 2575 | <h3> <TT>tinsert (table [, pos] , value)</TT></h3><A NAME="tinsert"></A> |
| 2159 | 2576 | <P> |
| 2160 | 2577 | Inserts element <CODE>value</CODE> at table position <CODE>pos</CODE>, |
| 2161 | −shifting other elements to open space. | |
| 2162 | −The default value for <CODE>pos</CODE> is <CODE>n+1</CODE> | |
| 2163 | −(where <CODE>n</CODE> is the result of <CODE>getn(table)</CODE> (see Section <A HREF="#getn">6.1</A>)) | |
| 2578 | +shifting other elements to open space, if necessary. | |
| 2579 | +The default value for <CODE>pos</CODE> is <CODE>n+1</CODE>, | |
| 2580 | +where <CODE>n</CODE> is the result of <CODE>getn(table)</CODE> (see Section <A HREF="#getn">6.1</A>), | |
| 2164 | 2581 | so that a call <CODE>tinsert(t,x)</CODE> inserts <CODE>x</CODE> at the end |
| 2165 | 2582 | of table <CODE>t</CODE>. |
| 2166 | −<P> | |
| 2167 | −This function also sets or increments the field <CODE>n</CODE> of the table, | |
| 2583 | +This function also sets or increments the field <CODE>n</CODE> of the table | |
| 2168 | 2584 | to <CODE>n+1</CODE>. |
| 2169 | −<P> | |
| 2170 | 2585 | This function is equivalent to the following Lua function, |
| 2171 | −except that the table accesses are all raw (that is, without tag methods): | |
| 2172 | −<PRE> | |
| 2173 | − function tinsert (t, ...) | |
| 2174 | − local pos, value | |
| 2175 | − local n = getn(t) | |
| 2176 | − if arg.n == 1 then | |
| 2177 | − pos = n+1; value = arg[1] | |
| 2178 | − else | |
| 2179 | − pos = arg[1]; value = arg[2] | |
| 2180 | − end | |
| 2181 | − t.n = n+1; | |
| 2182 | − while n >= pos do | |
| 2183 | − t[n+1] = t[n] | |
| 2184 | − n = n-1 | |
| 2185 | − end | |
| 2186 | − t[pos] = value | |
| 2187 | − end | |
| 2586 | +except that the table accesses are all <EM>raw</EM> | |
| 2587 | +(that is, without tag methods): | |
| 2588 | +<PRE> | |
| 2589 | + function tinsert (t, ...) | |
| 2590 | + local pos, value | |
| 2591 | + local n = getn(t) | |
| 2592 | + if arg.n == 1 then | |
| 2593 | + pos, value = n+1, arg[1] | |
| 2594 | + else | |
| 2595 | + pos, value = arg[1], arg[2] | |
| 2596 | + end | |
| 2597 | + t.n = n+1; | |
| 2598 | + for i=n,pos,-1 do | |
| 2599 | + t[i+1] = t[i] | |
| 2600 | + end | |
| 2601 | + t[pos] = value | |
| 2602 | + end | |
| 2188 | 2603 | </PRE> |
| 2189 | 2604 | <P> |
| 2190 | 2605 | <h3> <TT>tremove (table [, pos])</TT></h3><A NAME="tremove"></A> |
| 2191 | 2606 | <P> |
| 2192 | 2607 | Removes from <CODE>table</CODE> the element at position <CODE>pos</CODE>, |
| 2193 | −shifting other elements to close the space. | |
| 2608 | +shifting other elements to close the space, if necessary. | |
| 2194 | 2609 | Returns the value of the removed element. |
| 2195 | −The default value for <CODE>pos</CODE> is <CODE>n</CODE> | |
| 2196 | −(where <CODE>n</CODE> is the result of <CODE>getn(table)</CODE> (see Section <A HREF="#getn">6.1</A>)), | |
| 2610 | +The default value for <CODE>pos</CODE> is <CODE>n</CODE>, | |
| 2611 | +where <CODE>n</CODE> is the result of <CODE>getn(table)</CODE> (see Section <A HREF="#getn">6.1</A>), | |
| 2197 | 2612 | so that a call <CODE>tremove(t)</CODE> removes the last element |
| 2198 | 2613 | of table <CODE>t</CODE>. |
| 2199 | −<P> | |
| 2200 | −This function also sets or decrements the field <CODE>n</CODE> of the table, | |
| 2614 | +This function also sets or decrements the field <CODE>n</CODE> of the table | |
| 2201 | 2615 | to <CODE>n-1</CODE>. |
| 2202 | 2616 | <P> |
| 2203 | 2617 | This function is equivalent to the following Lua function, |
| 2204 | −except that the table accesses are all raw (that is, without tag methods): | |
| 2205 | −<PRE> | |
| 2206 | − function tremove (t, pos) | |
| 2207 | − local n = getn(t) | |
| 2208 | − pos = pos or n | |
| 2209 | − local value = t[pos] | |
| 2210 | − if n<=0 then return end | |
| 2211 | − while pos < n do | |
| 2212 | − t[pos] = t[pos+1] | |
| 2213 | − pos = pos+1 | |
| 2214 | − end | |
| 2215 | − t[n] = nil | |
| 2216 | − t.n = n-1 | |
| 2217 | − return value | |
| 2218 | − end | |
| 2618 | +except that the table accesses are all <EM>raw</EM> | |
| 2619 | +(that is, without tag methods): | |
| 2620 | +<PRE> | |
| 2621 | + function tremove (t, pos) | |
| 2622 | + local n = getn(t) | |
| 2623 | + if n<=0 then return end | |
| 2624 | + pos = pos or n | |
| 2625 | + local value = t[pos] | |
| 2626 | + for i=pos,n-1 do | |
| 2627 | + t[i] = t[i+1] | |
| 2628 | + end | |
| 2629 | + t[n] = nil | |
| 2630 | + t.n = n-1 | |
| 2631 | + return value | |
| 2632 | + end | |
| 2219 | 2633 | </PRE> |
| 2220 | 2634 | <P> |
| 2221 | −<h3> <TT>sort (table [, comp])</TT></h3><A NAME="sort"></A> | |
| 2222 | −Sorts table elements in a given order, <EM>in-place</EM>, | |
| 2223 | −from <CODE>table[1]</CODE> to <CODE>table[n]</CODE>, | |
| 2224 | −where <CODE>n</CODE> is the result of <CODE>getn(table)</CODE> (see Section <A HREF="#getn">6.1</A>). | |
| 2225 | −If <CODE>comp</CODE> is given, | |
| 2226 | −it must be a function that receives two table elements, | |
| 2227 | −and returns true when the first is less than the second | |
| 2228 | −(so that <CODE>not comp(a[i+1], a[i])</CODE> will be true after the sort). | |
| 2229 | −If <CODE>comp</CODE> is not given, | |
| 2230 | −the standard <CODE><</CODE> Lua operator is used instead. | |
| 2231 | −<P> | |
| 2232 | −Function <CODE>sort</CODE> returns the (sorted) table. | |
| 2635 | +<A NAME="pdf-type"></A> | |
| 2636 | +<h3> <TT>type (v)</TT></h3><A NAME="type"></A> | |
| 2637 | +Allows Lua programs to test the type of a value. | |
| 2638 | +It receives one argument, and returns its type, coded as a string. | |
| 2639 | +The possible results of this function are | |
| 2640 | +<CODE>"nil"</CODE> (a string, not the value <B>nil</B>), | |
| 2641 | +<CODE>"number"</CODE>, | |
| 2642 | +<CODE>"string"</CODE>, | |
| 2643 | +<CODE>"table"</CODE>, | |
| 2644 | +<CODE>"function"</CODE>, | |
| 2645 | +and <CODE>"userdata"</CODE>. | |
| 2233 | 2646 | <P> |
| 2234 | 2647 | <P> |
| 2235 | 2648 | <A NAME="6.2"></A> |
| 2236 | 2649 | <H2>6.2 - String Manipulation</H2> |
| 2237 | 2650 | This library provides generic functions for string manipulation, |
| 2238 | 2651 | such as finding and extracting substrings and pattern matching. |
| 2239 | −When indexing a string, the first character is at position 1 | |
| 2652 | +When indexing a string in Lua, the first character is at position 1 | |
| 2240 | 2653 | (not at 0, as in C). |
| 2654 | +Also, | |
| 2655 | +indices are allowed to be negative and are intepreted as indexing backwards, | |
| 2656 | +from the end of the string. Thus, the last character is at position <I>-1</I>, | |
| 2657 | +and so on. | |
| 2658 | +<P> | |
| 2659 | +<h3> <TT>strbyte (s [, i])</TT></h3><A NAME="strbyte"></A> | |
| 2660 | +Returns the internal numerical code of the <EM>i</EM>-th character of <CODE>s</CODE>. | |
| 2661 | +If <CODE>i</CODE> is absent, then it is assumed to be 1. | |
| 2662 | +<CODE>i</CODE> may be negative. | |
| 2663 | +<P> | |
| 2664 | +Numerical codes are not necessarily portable across platforms. | |
| 2241 | 2665 | <P> |
| 2242 | −<h3> <TT>strfind (str, pattern [, init [, plain]])</TT></h3> | |
| 2666 | +<h3> <TT>strchar (i1, i2, ...)</TT></h3><A NAME="strchar"></A> | |
| 2667 | +Receives 0 or more integers. | |
| 2668 | +Returns a string with length equal to the number of arguments, | |
| 2669 | +wherein each character has the internal numerical code equal | |
| 2670 | +to its correspondent argument. | |
| 2671 | +<P> | |
| 2672 | +Numerical codes are not necessarily portable across platforms. | |
| 2673 | +<P> | |
| 2674 | +<h3> <TT>strfind (s, pattern [, init [, plain]])</TT></h3> | |
| 2243 | 2675 | <A NAME="strfind"></A> |
| 2244 | 2676 | Looks for the first <EM>match</EM> of |
| 2245 | −<CODE>pattern</CODE> in <CODE>str</CODE>. | |
| 2246 | −If it finds one, then it returns the indices on <CODE>str</CODE> | |
| 2677 | +<CODE>pattern</CODE> in <CODE>s</CODE>. | |
| 2678 | +If it finds one, then <CODE>strfind</CODE> returns the indices of <CODE>s</CODE> | |
| 2247 | 2679 | where this occurrence starts and ends; |
| 2248 | 2680 | otherwise, it returns <B>nil</B>. |
| 2249 | −If the pattern specifies captures, | |
| 2681 | +If the pattern specifies captures (see <CODE>gsub</CODE> below), | |
| 2250 | 2682 | the captured strings are returned as extra results. |
| 2251 | −A third optional numerical argument specifies where to start the search; | |
| 2252 | −its default value is 1. | |
| 2253 | −If <CODE>init</CODE> is negative, | |
| 2254 | −it is replaced by the length of the string minus its | |
| 2255 | −absolute value plus 1. | |
| 2256 | −Therefore, <I>-1</I> points to the last character of <CODE>str</CODE>. | |
| 2257 | −A value of 1 as a fourth optional argument | |
| 2683 | +A third, optional numerical argument <CODE>init</CODE> specifies | |
| 2684 | +where to start the search; | |
| 2685 | +its default value is 1, and may be negative. | |
| 2686 | +A value of 1 as a fourth, optional argument <CODE>plain</CODE> | |
| 2258 | 2687 | turns off the pattern matching facilities, |
| 2259 | 2688 | so the function does a plain ``find substring'' operation, |
| 2260 | 2689 | with no characters in <CODE>pattern</CODE> being considered ``magic''. |
| 2690 | +Note that if <CODE>plain</CODE> is given, then <CODE>init</CODE> must be given too. | |
| 2261 | 2691 | <P> |
| 2262 | 2692 | <h3> <TT>strlen (s)</TT></h3><A NAME="strlen"></A> |
| 2263 | 2693 | Receives a string and returns its length. |
| 2694 | +The empty string <CODE>""</CODE> has length 0. | |
| 2695 | +Embedded zeros are counted, | |
| 2696 | +and so <CODE>"a\000b\000c"</CODE> has length 5. | |
| 2697 | +<P> | |
| 2698 | +<h3> <TT>strlower (s)</TT></h3><A NAME="strlower"></A> | |
| 2699 | +Receives a string and returns a copy of that string with all | |
| 2700 | +upper case letters changed to lower case. | |
| 2701 | +All other characters are left unchanged. | |
| 2702 | +The definition of what is an upper-case | |
| 2703 | +letter depends on the current locale. | |
| 2704 | +<P> | |
| 2705 | +<h3> <TT>strrep (s, n)</TT></h3><A NAME="strrep"></A> | |
| 2706 | +Returns a string that is the concatenation of <CODE>n</CODE> copies of | |
| 2707 | +the string <CODE>s</CODE>. | |
| 2264 | 2708 | <P> |
| 2265 | 2709 | <h3> <TT>strsub (s, i [, j])</TT></h3><A NAME="strsub"></A> |
| 2266 | 2710 | Returns another string, which is a substring of <CODE>s</CODE>, |
| 2267 | −starting at <CODE>i</CODE> and running until <CODE>j</CODE>. | |
| 2268 | −If <CODE>i</CODE> or <CODE>j</CODE> are negative, | |
| 2269 | −they are replaced by the length of the string minus their | |
| 2270 | −absolute value plus 1. | |
| 2271 | −Therefore, <I>-1</I> points to the last character of <CODE>s</CODE> | |
| 2272 | −and <I>-2</I> to the previous one. | |
| 2273 | −If <CODE>j</CODE> is absent, it is assumed to be equal to <I>-1</I> | |
| 2711 | +starting at <CODE>i</CODE> and running until <CODE>j</CODE>; | |
| 2712 | +<CODE>i</CODE> and <CODE>j</CODE> may be negative, | |
| 2713 | +If <CODE>j</CODE> is absent, then it is assumed to be equal to <I>-1</I> | |
| 2274 | 2714 | (which is the same as the string length). |
| 2275 | 2715 | In particular, |
| 2276 | 2716 | the call <CODE>strsub(s,1,j)</CODE> returns a prefix of <CODE>s</CODE> |
| @@ -2278,13 +2718,6 @@ with length <CODE>j</CODE>, · 1 unmodified line | ||
| 2278 | 2718 | and the call <CODE>strsub(s, -i)</CODE> returns a suffix of <CODE>s</CODE> |
| 2279 | 2719 | with length <CODE>i</CODE>. |
| 2280 | 2720 | <P> |
| 2281 | −<h3> <TT>strlower (s)</TT></h3><A NAME="strlower"></A> | |
| 2282 | −Receives a string and returns a copy of that string with all | |
| 2283 | −upper case letters changed to lower case. | |
| 2284 | −All other characters are left unchanged. | |
| 2285 | −The definition of what is an upper case | |
| 2286 | −letter depends on the current locale. | |
| 2287 | −<P> | |
| 2288 | 2721 | <h3> <TT>strupper (s)</TT></h3><A NAME="strupper"></A> |
| 2289 | 2722 | Receives a string and returns a copy of that string with all |
| 2290 | 2723 | lower case letters changed to upper case. |
| @@ -2292,47 +2725,25 @@ All other characters are left unchanged. · 1 unmodified line | ||
| 2292 | 2725 | The definition of what is a lower case |
| 2293 | 2726 | letter depends on the current locale. |
| 2294 | 2727 | <P> |
| 2295 | −<h3> <TT>strrep (s, n)</TT></h3><A NAME="strrep"></A> | |
| 2296 | −Returns a string that is the concatenation of <CODE>n</CODE> copies of | |
| 2297 | −the string <CODE>s</CODE>. | |
| 2298 | −<P> | |
| 2299 | −<h3> <TT>strbyte (s [, i])</TT></h3><A NAME="strbyte"></A> | |
| 2300 | −Returns the internal numerical code of the character <CODE>s[i]</CODE>. | |
| 2301 | −If <CODE>i</CODE> is absent, then it is assumed to be 1. | |
| 2302 | −If <CODE>i</CODE> is negative, | |
| 2303 | −it is replaced by the length of the string minus its | |
| 2304 | −absolute value plus 1. | |
| 2305 | −Therefore, <I>-1</I> points to the last character of <CODE>s</CODE>. | |
| 2306 | −<P> | |
| 2307 | −Note that numerical codes are not necessarily portable across platforms. | |
| 2308 | −<P> | |
| 2309 | −<h3> <TT>strchar (i1, i2, ...)</TT></h3><A NAME="strchar"></A> | |
| 2310 | −Receives 0 or more integers. | |
| 2311 | −Returns a string with length equal to the number of arguments, | |
| 2312 | −wherein each character has the internal numerical code equal | |
| 2313 | −to its correspondent argument. | |
| 2314 | −<P> | |
| 2315 | −Note that numerical codes are not necessarily portable across platforms. | |
| 2316 | −<P> | |
| 2317 | 2728 | <h3> <TT>format (formatstring, e1, e2, ...)</TT></h3><A NAME="format"></A> |
| 2318 | 2729 | <A NAME="format"></A> |
| 2319 | 2730 | |
| 2320 | 2731 | Returns a formatted version of its variable number of arguments |
| 2321 | 2732 | following the description given in its first argument (which must be a string). |
| 2322 | 2733 | The format string follows the same rules as the <CODE>printf</CODE> family of |
| 2323 | −standard C functions. | |
| 2734 | +standard C functions. | |
| 2324 | 2735 | The only differences are that the options/modifiers |
| 2325 | 2736 | <CODE>*</CODE>, <CODE>l</CODE>, <CODE>L</CODE>, <CODE>n</CODE>, <CODE>p</CODE>, |
| 2326 | 2737 | and <CODE>h</CODE> are not supported, |
| 2327 | 2738 | and there is an extra option, <CODE>q</CODE>. |
| 2328 | −This option formats a string in a form suitable to be safely read | |
| 2739 | +The <CODE>q</CODE> option formats a string in a form suitable to be safely read | |
| 2329 | 2740 | back by the Lua interpreter: |
| 2330 | 2741 | The string is written between double quotes, |
| 2331 | −and all double quotes, returns and backslashes in the string | |
| 2742 | +and all double quotes, returns, and backslashes in the string | |
| 2332 | 2743 | are correctly escaped when written. |
| 2333 | 2744 | For instance, the call |
| 2334 | 2745 | <PRE> |
| 2335 | −format('%q', 'a string with "quotes" and \n new line') | |
| 2746 | + format('%q', 'a string with "quotes" and \n new line') | |
| 2336 | 2747 | </PRE> |
| 2337 | 2748 | will produce the string: |
| 2338 | 2749 | <PRE> |
| @@ -2340,7 +2751,7 @@ will produce the string: · 1 unmodified line | ||
| 2340 | 2751 | new line" |
| 2341 | 2752 | </PRE> |
| 2342 | 2753 | <P> |
| 2343 | −Conversions can be applied to the n-th argument in the argument list, | |
| 2754 | +Conversions can be applied to the <EM>n</EM>-th argument in the argument list, | |
| 2344 | 2755 | rather than the next unused argument. |
| 2345 | 2756 | In this case, the conversion character <CODE>%</CODE> is replaced |
| 2346 | 2757 | by the sequence <CODE>%d$</CODE>, where <CODE>d</CODE> is a |
| @@ -2359,20 +2770,22 @@ the appropriate format string. · 12 unmodified lines | ||
| 2359 | 2770 | For example, <CODE>"%*g"</CODE> can be simulated with |
| 2360 | 2771 | <CODE>"%"..width.."g"</CODE>. |
| 2361 | 2772 | <P> |
| 2362 | −<EM>Note: function <TT>format</TT> can only be used with strings that do not contain zeros.</EM> | |
| 2773 | +Neither the format string nor the string values to be formatted with | |
| 2774 | +<CODE>%s</CODE> can contain embedded zeros. | |
| 2775 | +<CODE>%q</CODE> handles string values with embedded zeros. | |
| 2363 | 2776 | <P> |
| 2364 | 2777 | <h3> <TT>gsub (s, pat, repl [, n])</TT></h3> |
| 2365 | 2778 | <A NAME="gsub"></A> |
| 2366 | −Returns a copy of <CODE>s</CODE>, | |
| 2367 | −where all occurrences of the pattern <CODE>pat</CODE> have been | |
| 2779 | +Returns a copy of <CODE>s</CODE> | |
| 2780 | +in which all occurrences of the pattern <CODE>pat</CODE> have been | |
| 2368 | 2781 | replaced by a replacement string specified by <CODE>repl</CODE>. |
| 2369 | −This function also returns, as a second value, | |
| 2782 | +<CODE>gsub</CODE> also returns, as a second value, | |
| 2370 | 2783 | the total number of substitutions made. |
| 2371 | 2784 | <P> |
| 2372 | 2785 | If <CODE>repl</CODE> is a string, then its value is used for replacement. |
| 2373 | 2786 | Any sequence in <CODE>repl</CODE> of the form <CODE>%n</CODE> |
| 2374 | 2787 | with <CODE>n</CODE> between 1 and 9 |
| 2375 | −stands for the value of the n-th captured substring. | |
| 2788 | +stands for the value of the <EM>n</EM>-th captured substring. | |
| 2376 | 2789 | <P> |
| 2377 | 2790 | If <CODE>repl</CODE> is a function, then this function is called every time a |
| 2378 | 2791 | match occurs, with all captured substrings passed as arguments, |
| @@ -2381,35 +2794,35 @@ If the value returned by this function is a string, · 2 unmodified lines | ||
| 2381 | 2794 | then it is used as the replacement string; |
| 2382 | 2795 | otherwise, the replacement string is the empty string. |
| 2383 | 2796 | <P> |
| 2384 | −A last optional parameter <CODE>n</CODE> limits | |
| 2797 | +The last, optional parameter <CODE>n</CODE> limits | |
| 2385 | 2798 | the maximum number of substitutions to occur. |
| 2386 | 2799 | For instance, when <CODE>n</CODE> is 1 only the first occurrence of |
| 2387 | 2800 | <CODE>pat</CODE> is replaced. |
| 2388 | 2801 | <P> |
| 2389 | 2802 | Here are some examples: |
| 2390 | 2803 | <PRE> |
| 2391 | − x = gsub("hello world", "(%w+)", "%1 %1") | |
| 2392 | − --> x="hello hello world world" | |
| 2804 | + x = gsub("hello world", "(%w+)", "%1 %1") | |
| 2805 | + --> x="hello hello world world" | |
| 2393 | 2806 | <P> |
| 2394 | − x = gsub("hello world", "(%w+)", "%1 %1", 1) | |
| 2395 | − --> x="hello hello world" | |
| 2807 | + x = gsub("hello world", "(%w+)", "%1 %1", 1) | |
| 2808 | + --> x="hello hello world" | |
| 2396 | 2809 | <P> |
| 2397 | − x = gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1") | |
| 2398 | − --> x="world hello Lua from" | |
| 2810 | + x = gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1") | |
| 2811 | + --> x="world hello Lua from" | |
| 2399 | 2812 | <P> |
| 2400 | − x = gsub("home = $HOME, user = $USER", "%$(%w+)", getenv) | |
| 2401 | − --> x="home = /home/roberto, user = roberto" (for instance) | |
| 2813 | + x = gsub("home = $HOME, user = $USER", "%$(%w+)", getenv) | |
| 2814 | + --> x="home = /home/roberto, user = roberto" (for instance) | |
| 2402 | 2815 | <P> |
| 2403 | − x = gsub("4+5 = $return 4+5$", "%$(.-)%$", dostring) | |
| 2404 | − --> x="4+5 = 9" | |
| 2816 | + x = gsub("4+5 = $return 4+5$", "%$(.-)%$", dostring) | |
| 2817 | + --> x="4+5 = 9" | |
| 2405 | 2818 | <P> |
| 2406 | − local t = {name="lua", version="3.2"} | |
| 2407 | − x = gsub("$name - $version", "%$(%w+)", function (v) return %t[v] end) | |
| 2408 | − --> x="lua - 3.2" | |
| 2819 | + local t = {name="lua", version="4.0"} | |
| 2820 | + x = gsub("$name - $version", "%$(%w+)", function (v) return %t[v] end) | |
| 2821 | + --> x="lua - 4.0" | |
| 2409 | 2822 | <P> |
| 2410 | − t = {n=0} | |
| 2411 | − gsub("first second word", "(%w+)", function (w) tinsert(%t, w) end) | |
| 2412 | − --> t={"first", "second", "word"; n=3} | |
| 2823 | + t = {n=0} | |
| 2824 | + gsub("first second word", "(%w+)", function (w) tinsert(%t, w) end) | |
| 2825 | + --> t={"first", "second", "word"; n=3} | |
| 2413 | 2826 | </PRE> |
| 2414 | 2827 | <P> |
| 2415 | 2828 | <P> |
| @@ -2420,7 +2833,7 @@ Here are some examples: · 4 unmodified lines | ||
| 2420 | 2833 | a <A NAME="character class"><EM>character class</EM></A> is used to represent a set of characters. |
| 2421 | 2834 | The following combinations are allowed in describing a character class: |
| 2422 | 2835 | <DL> |
| 2423 | −<DT><B><EM>x</EM></B><DD> (where <EM>x</EM> is any character not in the list | |
| 2836 | +<DT><B><EM>x</EM></B><DD> (where <EM>x</EM> is any magic characters | |
| 2424 | 2837 | <CODE>^$()%.[]*+-?</CODE>) |
| 2425 | 2838 | - represents the character <EM>x</EM> itself. |
| 2426 | 2839 | <DT><B><TT>.</TT></B><DD> - (a dot) represents all characters. |
| @@ -2432,37 +2845,44 @@ The following combinations are allowed in describing a character class: · 5 unmodified lines | ||
| 2432 | 2845 | <DT><B><TT>%s</TT></B><DD> - represents all space characters. |
| 2433 | 2846 | <DT><B><TT>%u</TT></B><DD> - represents all upper case letters. |
| 2434 | 2847 | <DT><B><TT>%w</TT></B><DD> - represents all alphanumeric characters. |
| 2435 | −<DT><B><TT>%x</TT></B><DD> - represents all hexa-decimal digits. | |
| 2848 | +<DT><B><TT>%x</TT></B><DD> - represents all hexadecimal digits. | |
| 2436 | 2849 | <DT><B><TT>%z</TT></B><DD> - represents the character with representation 0. |
| 2437 | −<DT><B><TT>%<EM>x</TT></EM></B><DD> (where <EM>x</EM> is any non alphanumeric character) - | |
| 2850 | +<DT><B><TT>%<EM>x</TT></EM></B><DD> (where <EM>x</EM> is any non-alphanumeric character) - | |
| 2438 | 2851 | represents the character <EM>x</EM>. |
| 2439 | −This is the standard way to escape the magic characters <CODE>()%.[]*-?</CODE>. | |
| 2440 | −It is strongly recommended that any control character (even the non magic), | |
| 2441 | −when used to represent itself in a pattern, should be preceded by a <CODE>%</CODE>. | |
| 2852 | +This is the standard way to escape the magic characters. | |
| 2853 | +We recommend that any punctuation character (even the non magic) | |
| 2854 | +should be preceded by a <CODE>%</CODE> | |
| 2855 | +when used to represent itself in a pattern. | |
| 2856 | +<P> | |
| 2442 | 2857 | <DT><B><TT>[char-set</TT></B>]<DD> - |
| 2443 | −Represents the class which is the union of all | |
| 2444 | −characters in char-set. | |
| 2445 | −To include a <CODE>]</CODE> in char-set, it must be the first character. | |
| 2858 | +represents the class which is the union of all | |
| 2859 | +characters in <CODE>char-set</CODE>. | |
| 2446 | 2860 | A range of characters may be specified by |
| 2447 | 2861 | separating the end characters of the range with a <CODE>-</CODE>. |
| 2448 | −If <CODE>-</CODE> appears as the first or last character of char-set, | |
| 2449 | −then it represents itself. | |
| 2450 | −All classes <CODE>%</CODE><EM>x</EM> described above can also be used as | |
| 2862 | +All classes <CODE>%</CODE><EM>x</EM> described above may also be used as | |
| 2451 | 2863 | components in a char-set. |
| 2452 | 2864 | All other characters in char-set represent themselves. |
| 2453 | −E.g., assuming an <EM>ascii</EM> character set, | |
| 2454 | −<CODE>[%dA-Fa-f]</CODE> specifies the hexa-decimal digits. | |
| 2865 | +For example, <CODE>[%w_]</CODE> (or <CODE>[_%w]</CODE>) | |
| 2866 | +represents all alphanumeric characters plus the underscore, | |
| 2867 | +<CODE>[0-7]</CODE> represents the octal digits, | |
| 2868 | +and <CODE>[0-7%l%-]</CODE> represents the octal digits plus | |
| 2869 | +the lower case letters plus the <CODE>-</CODE> character. | |
| 2870 | +<P> | |
| 2871 | +The interaction between ranges and classes is not defined. | |
| 2872 | +Therefore, patterns like <CODE>[%a-z]</CODE> or <CODE>[a-%%]</CODE> | |
| 2873 | +have no meaning. | |
| 2874 | +<P> | |
| 2455 | 2875 | <DT><B><TT>[^char-set</TT></B>]<DD> - |
| 2456 | −represents the complement of char-set, | |
| 2457 | −where char-set is interpreted as above. | |
| 2876 | +represents the complement of <CODE>char-set</CODE>, | |
| 2877 | +where <CODE>char-set</CODE> is interpreted as above. | |
| 2458 | 2878 | </DL> |
| 2459 | 2879 | For all classes represented by single letters (<CODE>%a</CODE>, <CODE>%c</CODE>, ...), |
| 2460 | −the correspondent upper-case letter represents the complement of the class. | |
| 2880 | +the corresponding upper-case letter represents the complement of the class. | |
| 2461 | 2881 | For instance, <CODE>%S</CODE> represents all non-space characters. |
| 2462 | 2882 | <P> |
| 2463 | 2883 | The definitions of letter, space, etc. depend on the current locale. |
| 2464 | 2884 | In particular, the class <CODE>[a-z]</CODE> may not be equivalent to <CODE>%l</CODE>. |
| 2465 | −The second form should be preferred for more portable programs. | |
| 2885 | +The second form should be preferred for portability. | |
| 2466 | 2886 | <P> |
| 2467 | 2887 | <H4>Pattern Item:</H4> |
| 2468 | 2888 | a <A NAME="pattern item"><EM>pattern item</EM></A> may be |
| @@ -2488,15 +2908,15 @@ a single character class followed by <CODE>?</CODE>, · 19 unmodified lines | ||
| 2488 | 2908 | which matches 0 or 1 occurrence of a character in the class; |
| 2489 | 2909 | <LI> |
| 2490 | 2910 | <TT>%<EM>n</TT></EM>, for <EM>n</EM> between 1 and 9; |
| 2491 | −such item matches a sub-string equal to the n-th captured string | |
| 2911 | +such item matches a sub-string equal to the <EM>n</EM>-th captured string | |
| 2492 | 2912 | (see below); |
| 2493 | 2913 | <LI> |
| 2494 | 2914 | <TT>%b<EM>xy</TT></EM>, where <EM>x</EM> and <EM>y</EM> are two distinct characters; |
| 2495 | −such item matches strings that start with <EM>x</EM>, end with <EM>y</EM>, | |
| 2915 | +such item matches strings that start with <EM>x</EM>, end with <EM>y</EM>, | |
| 2496 | 2916 | and where the <EM>x</EM> and <EM>y</EM> are <EM>balanced</EM>. |
| 2497 | −That means that, if one reads the string from left to write, | |
| 2498 | −counting plus 1 for an <EM>x</EM> and minus 1 for a <EM>y</EM>, | |
| 2499 | −the ending <EM>y</EM> is the first where the count reaches 0. | |
| 2917 | +This means that, if one reads the string from left to right, | |
| 2918 | +counting <I>+1</I> for an <EM>x</EM> and <I>-1</I> for a <EM>y</EM>, | |
| 2919 | +the ending <EM>y</EM> is the first <EM>y</EM> where the count reaches 0. | |
| 2500 | 2920 | For instance, the item <CODE>%b()</CODE> matches expressions with |
| 2501 | 2921 | balanced parentheses. |
| 2502 | 2922 | </UL> |
| @@ -2507,10 +2927,12 @@ A <CODE>^</CODE> at the beginning of a pattern anchors the match at the · 4 unmodified lines | ||
| 2507 | 2927 | beginning of the subject string. |
| 2508 | 2928 | A <CODE>$</CODE> at the end of a pattern anchors the match at the |
| 2509 | 2929 | end of the subject string. |
| 2930 | +At other positions, | |
| 2931 | +<CODE>^</CODE> and <CODE>$</CODE> have no special meaning and represent themselves. | |
| 2510 | 2932 | <P> |
| 2511 | 2933 | <H4>Captures:</H4> |
| 2512 | −a pattern may contain sub-patterns enclosed in parentheses, | |
| 2513 | −that describe <A NAME="captures"><EM>captures</EM></A>. | |
| 2934 | +A pattern may contain sub-patterns enclosed in parentheses, | |
| 2935 | +they describe <A NAME="captures"><EM>captures</EM></A>. | |
| 2514 | 2936 | When a match succeeds, the sub-strings of the subject string |
| 2515 | 2937 | that match captures are stored (<EM>captured</EM>) for future use. |
| 2516 | 2938 | Captures are numbered according to their left parentheses. |
| @@ -2520,43 +2942,44 @@ stored as the first capture (and therefore has number 1); · 3 unmodified lines | ||
| 2520 | 2942 | the character matching <CODE>.</CODE> is captured with number 2, |
| 2521 | 2943 | and the part matching <CODE>%s*</CODE> has number 3. |
| 2522 | 2944 | <P> |
| 2945 | +A pattern cannot contain embedded zeros. Use <CODE>%z</CODE> instead. | |
| 2946 | +<P> | |
| 2523 | 2947 | <P> |
| 2524 | 2948 | <A NAME="mathlib"></A> |
| 2525 | 2949 | <A NAME="6.3"></A> |
| 2526 | 2950 | <H2>6.3 - Mathematical Functions</H2> |
| 2527 | 2951 | <P> |
| 2528 | −This library is an interface to some functions of the standard C math library. | |
| 2952 | +This library is an interface to some functions of the standard C math library. | |
| 2529 | 2953 | In addition, it registers a tag method for the binary operator <CODE>^</CODE> that |
| 2530 | 2954 | returns <I>x^y</I> when applied to numbers <CODE>x^y</CODE>. |
| 2531 | 2955 | <P> |
| 2532 | 2956 | The library provides the following functions: |
| 2533 | 2957 | <A NAME="abs"></A><A NAME="acos"></A><A NAME="asin"></A><A NAME="atan"></A> |
| 2534 | −<A NAME="atan2"></A><A NAME="ceil"></A><A NAME="cos"></A><A NAME="floor"></A> | |
| 2535 | −<A NAME="log"></A><A NAME="log10"></A><A NAME="max"></A><A NAME="min"></A> | |
| 2536 | −<A NAME="mod"></A><A NAME="sin"></A><A NAME="sqrt"></A><A NAME="tan"></A> | |
| 2537 | −<A NAME="frexp"></A><A NAME="ldexp"></A> | |
| 2538 | −<A NAME="random"></A><A NAME="randomseed"></A> | |
| 2958 | +<A NAME="atan2"></A><A NAME="ceil"></A><A NAME="cos"></A><A NAME="def"></A><A NAME="exp"></A> | |
| 2959 | +<A NAME="floor"></A><A NAME="log"></A><A NAME="log10"></A><A NAME="max"></A><A NAME="min"></A> | |
| 2960 | +<A NAME="mod"></A><A NAME="rad"></A><A NAME="sin"></A><A NAME="sqrt"></A><A NAME="tan"></A> | |
| 2961 | +<A NAME="frexp"></A><A NAME="ldexp"></A><A NAME="random"></A><A NAME="randomseed"></A> | |
| 2539 | 2962 | <PRE> |
| 2540 | −abs acos asin atan atan2 ceil cos deg floor log log10 | |
| 2541 | −max min mod rad sin sqrt tan frexp ldexp | |
| 2542 | −random randomseed | |
| 2963 | + abs acos asin atan atan2 ceil cos deg exp floor log log10 | |
| 2964 | + max min mod rad sin sqrt tan frexp ldexp random randomseed | |
| 2543 | 2965 | </PRE> |
| 2544 | 2966 | plus a global variable <A NAME="PI"><TT>PI</TT></A>. |
| 2545 | 2967 | Most of them |
| 2546 | −are only interfaces to the homonymous functions in the C library, | |
| 2968 | +are only interfaces to the homonymous functions in the C library, | |
| 2547 | 2969 | except that, for the trigonometric functions, |
| 2548 | 2970 | all angles are expressed in <EM>degrees</EM>, not radians. |
| 2549 | −Functions <A NAME="deg"><TT>deg</TT></A> and <A NAME="rad"><TT>rad</TT></A> can be used to convert | |
| 2971 | +The functions <CODE>deg</CODE> and <CODE>rad</CODE> can be used to convert | |
| 2550 | 2972 | between radians and degrees. |
| 2551 | 2973 | <P> |
| 2552 | 2974 | The function <CODE>max</CODE> returns the maximum |
| 2553 | 2975 | value of its numeric arguments. |
| 2554 | 2976 | Similarly, <CODE>min</CODE> computes the minimum. |
| 2555 | −Both can be used with 1, 2 or more arguments. | |
| 2977 | +Both can be used with 1, 2, or more arguments. | |
| 2556 | 2978 | <P> |
| 2557 | 2979 | The functions <CODE>random</CODE> and <CODE>randomseed</CODE> are interfaces to |
| 2558 | 2980 | the simple random generator functions <CODE>rand</CODE> and <CODE>srand</CODE>, |
| 2559 | 2981 | provided by ANSI C. |
| 2982 | +(No guarantees can be given for their statistical properties.) | |
| 2560 | 2983 | The function <CODE>random</CODE>, when called without arguments, |
| 2561 | 2984 | returns a pseudo-random real number in the range <I>[0,1)</I>. |
| 2562 | 2985 | When called with a number <I>n</I>, |
| @@ -2574,17 +2997,15 @@ over two <A NAME="file handles"><EM>file handles</EM></A>, one for reading and o · 11 unmodified lines | ||
| 2574 | 2997 | These handles are stored in two Lua global variables, |
| 2575 | 2998 | called <CODE>_INPUT</CODE> and <CODE>_OUTPUT</CODE>. |
| 2576 | 2999 | The global variables |
| 2577 | −<CODE>_STDIN</CODE>, <CODE>_STDOUT</CODE> and <CODE>_STDERR</CODE> | |
| 3000 | +<CODE>_STDIN</CODE>, <CODE>_STDOUT</CODE>, and <CODE>_STDERR</CODE> | |
| 2578 | 3001 | are initialized with file descriptors for |
| 2579 | −<CODE>stdin</CODE>, <CODE>stdout</CODE> and <CODE>stderr</CODE>. | |
| 3002 | +<CODE>stdin</CODE>, <CODE>stdout</CODE>, and <CODE>stderr</CODE>. | |
| 2580 | 3003 | Initially, <CODE>_INPUT=_STDIN</CODE> and <CODE>_OUTPUT=_STDOUT</CODE>. |
| 2581 | 3004 | <A NAME="_INPUT"></A><A NAME="_OUTPUT"></A> |
| 2582 | 3005 | <A NAME="_STDIN"></A><A NAME="_STDOUT"></A><A NAME="_STDERR"></A> |
| 2583 | 3006 | <P> |
| 2584 | −A file handle is a userdata containing the file stream <CODE>FILE*</CODE>, | |
| 3007 | +A file handle is a userdata containing the file stream (<CODE>FILE*</CODE>), | |
| 2585 | 3008 | and with a distinctive tag created by the I/O library. |
| 2586 | −Whenever a file handle is collected by the garbage collector, | |
| 2587 | −its correspondent stream is automatically closed. | |
| 2588 | 3009 | <P> |
| 2589 | 3010 | Unless otherwise stated, |
| 2590 | 3011 | all I/O functions return <B>nil</B> on failure and |
| @@ -2598,18 +3019,19 @@ It returns a new file handle, · 7 unmodified lines | ||
| 2598 | 3019 | or, in case of errors, <B>nil</B> plus a string describing the error. |
| 2599 | 3020 | This function does not modify either <CODE>_INPUT</CODE> or <CODE>_OUTPUT</CODE>. |
| 2600 | 3021 | <P> |
| 2601 | −The string mode can be any of the following: | |
| 3022 | +The <CODE>mode</CODE> string can be any of the following: | |
| 2602 | 3023 | <DL> |
| 2603 | −<DT><B>"r"</B><DD> read mode; | |
| 2604 | −<DT><B>"w"</B><DD> write mode; | |
| 2605 | −<DT><B>"a"</B><DD> append mode; | |
| 2606 | −<DT><B>"r+"</B><DD> update mode, all previous data is preserved; | |
| 2607 | −<DT><B>"w+"</B><DD> update mode, all previous data is erased; | |
| 2608 | −<DT><B>"a+"</B><DD> append update mode, previous data is preserved, | |
| 3024 | +<DT><B>``r''</B><DD> read mode; | |
| 3025 | +<DT><B>``w''</B><DD> write mode; | |
| 3026 | +<DT><B>``a''</B><DD> append mode; | |
| 3027 | +<DT><B>``r+''</B><DD> update mode, all previous data is preserved; | |
| 3028 | +<DT><B>``w+''</B><DD> update mode, all previous data is erased; | |
| 3029 | +<DT><B>``a+''</B><DD> append update mode, previous data is preserved, | |
| 2609 | 3030 | writing is only allowed at the end of file. |
| 2610 | 3031 | </DL> |
| 2611 | −The string mode may also have a <CODE>b</CODE> at the end, | |
| 3032 | +The <CODE>mode</CODE> string may also have a <CODE>b</CODE> at the end, | |
| 2612 | 3033 | which is needed in some systems to open the file in binary mode. |
| 3034 | +This string is exactlty what is used in the standard C function <CODE>fopen</CODE>. | |
| 2613 | 3035 | <P> |
| 2614 | 3036 | <h3> <TT>closefile (handle)</TT></h3><A NAME="closefile"></A> |
| 2615 | 3037 | <P> |
| @@ -2626,18 +3048,15 @@ It does not close the current input file. · 10 unmodified lines | ||
| 2626 | 3048 | When called without parameters, |
| 2627 | 3049 | it closes the <CODE>_INPUT</CODE> file, |
| 2628 | 3050 | and restores <CODE>stdin</CODE> as the value of <CODE>_INPUT</CODE>. |
| 2629 | −<P> | |
| 2630 | 3051 | If this function fails, it returns <B>nil</B>, |
| 2631 | 3052 | plus a string describing the error. |
| 2632 | 3053 | <P> |
| 2633 | −<CITE> | |
| 2634 | −<EM>System dependent</EM>: if <CODE>filename</CODE> starts with a <CODE>|</CODE>, | |
| 3054 | +If <CODE>filename</CODE> starts with a <CODE>|</CODE>, | |
| 2635 | 3055 | then a <A NAME="piped input">piped input</A> is opened, via function <A NAME="popen"><TT>popen</TT></A>. |
| 2636 | 3056 | Not all systems implement pipes. |
| 2637 | 3057 | Moreover, |
| 2638 | 3058 | the number of files that can be open at the same time is |
| 2639 | 3059 | usually limited and depends on the system. |
| 2640 | −</CITE> | |
| 2641 | 3060 | <P> |
| 2642 | 3061 | <h3> <TT>writeto (filename)</TT></h3><A NAME="writeto"></A> |
| 2643 | 3062 | <P> |
| @@ -2653,25 +3072,23 @@ When called without parameters, · 9 unmodified lines | ||
| 2653 | 3072 | this function closes the <CODE>_OUTPUT</CODE> file, |
| 2654 | 3073 | and restores <CODE>stdout</CODE> as the value of <CODE>_OUTPUT</CODE>. |
| 2655 | 3074 | <A NAME="closing a file"></A> |
| 2656 | −<P> | |
| 2657 | 3075 | If this function fails, it returns <B>nil</B>, |
| 2658 | 3076 | plus a string describing the error. |
| 2659 | 3077 | <P> |
| 2660 | −<CITE> | |
| 2661 | −<EM>System dependent</EM>: if <CODE>filename</CODE> starts with a <CODE>|</CODE>, | |
| 2662 | −then a <A NAME="piped output">piped output</A> is opened, via function <A NAME="popen"><TT>popen</TT></A>. | |
| 3078 | +If <CODE>filename</CODE> starts with a <CODE>|</CODE>, | |
| 3079 | +then a <A NAME="piped input">piped input</A> is opened, via function <A NAME="popen"><TT>popen</TT></A>. | |
| 2663 | 3080 | Not all systems implement pipes. |
| 2664 | 3081 | Moreover, |
| 2665 | 3082 | the number of files that can be open at the same time is |
| 2666 | 3083 | usually limited and depends on the system. |
| 2667 | −</CITE> | |
| 2668 | 3084 | <P> |
| 2669 | 3085 | <h3> <TT>appendto (filename)</TT></h3><A NAME="appendto"></A> |
| 2670 | 3086 | <P> |
| 2671 | 3087 | Opens a file named <CODE>filename</CODE> and sets it as the |
| 2672 | 3088 | value of <CODE>_OUTPUT</CODE>. |
| 2673 | 3089 | Unlike the <CODE>writeto</CODE> operation, |
| 2674 | −this function does not erase any previous content of the file. | |
| 3090 | +this function does not erase any previous contents of the file; | |
| 3091 | +instead, anything written to the file is appended to its end. | |
| 2675 | 3092 | If this function fails, it returns <B>nil</B>, |
| 2676 | 3093 | plus a string describing the error. |
| 2677 | 3094 | <P> |
| @@ -2691,7 +3108,7 @@ plus a string describing the error. · 13 unmodified lines | ||
| 2691 | 3108 | <P> |
| 2692 | 3109 | Saves any written data to the given file. |
| 2693 | 3110 | If <CODE>filehandle</CODE> is not specified, |
| 2694 | −flushes all open files. | |
| 3111 | +then <CODE>flush</CODE> flushes all open files. | |
| 2695 | 3112 | If this function fails, it returns <B>nil</B>, |
| 2696 | 3113 | plus a string describing the error. |
| 2697 | 3114 | <P> |
| @@ -2702,9 +3119,9 @@ measured in bytes from the beginning of the file, · 4 unmodified lines | ||
| 2702 | 3119 | to the position given by <CODE>offset</CODE> plus a base |
| 2703 | 3120 | specified by the string <CODE>whence</CODE>, as follows: |
| 2704 | 3121 | <DL> |
| 2705 | −<DT><B>"set"</B><DD> base is position 0 (beginning of the file); | |
| 2706 | −<DT><B>"cur"</B><DD> base is current position; | |
| 2707 | −<DT><B>"end"</B><DD> base is end of file; | |
| 3122 | +<DT><B>``set''</B><DD> base is position 0 (beginning of the file); | |
| 3123 | +<DT><B>``cur''</B><DD> base is current position; | |
| 3124 | +<DT><B>``end''</B><DD> base is end of file; | |
| 2708 | 3125 | </DL> |
| 2709 | 3126 | In case of success, function <CODE>seek</CODE> returns the final file position, |
| 2710 | 3127 | measured in bytes from the beginning of the file. |
| @@ -2724,62 +3141,35 @@ end of the file, and returns its size. · 13 unmodified lines | ||
| 2724 | 3141 | <P> |
| 2725 | 3142 | Returns a string with a file name that can safely |
| 2726 | 3143 | be used for a temporary file. |
| 2727 | −The file must be explicitly removed when no longer needed. | |
| 3144 | +The file must be explicitly opened before its use | |
| 3145 | +and removed when no longer needed. | |
| 2728 | 3146 | <P> |
| 2729 | −<h3> <TT>read ([filehandle,] readpattern1, ...)</TT></h3><A NAME="read"></A> | |
| 3147 | +<h3> <TT>read ([filehandle,] format1, ...)</TT></h3><A NAME="read"></A> | |
| 2730 | 3148 | <P> |
| 2731 | 3149 | Reads file <CODE>_INPUT</CODE>, |
| 2732 | 3150 | or <CODE>filehandle</CODE> if this argument is given, |
| 2733 | −according to read patterns, which specify how much to read. | |
| 2734 | −For each pattern, | |
| 2735 | −the function returns a string with the characters read, | |
| 2736 | −even if the pattern succeeds only partially, | |
| 2737 | −or <B>nil</B> if the read pattern fails <EM>and</EM> | |
| 2738 | −the result string would be empty. | |
| 2739 | −When called without patterns, | |
| 2740 | −it uses a default pattern that reads the next line | |
| 3151 | +according to the given formats, which specify what to read. | |
| 3152 | +For each format, | |
| 3153 | +the function returns a string (or a number) with the characters read, | |
| 3154 | +or <B>nil</B> if it cannot read data with the specified format. | |
| 3155 | +When called without formats, | |
| 3156 | +it uses a default format that reads the next line | |
| 2741 | 3157 | (see below). |
| 2742 | 3158 | <P> |
| 2743 | −A <A NAME="read pattern"><EM>read pattern</EM></A> is a sequence of read pattern items. | |
| 2744 | −An item may be a single character class | |
| 2745 | −or a character class followed by <CODE>?</CODE>, by <CODE>*</CODE>, or by <CODE>+</CODE>. | |
| 2746 | −A single character class reads the next character from the input | |
| 2747 | −if it belongs to the class, otherwise it fails. | |
| 2748 | −A character class followed by <CODE>?</CODE> reads the next character | |
| 2749 | −from the input if it belongs to the class; | |
| 2750 | −it never fails. | |
| 2751 | −A character class followed by <CODE>*</CODE> reads until a character that | |
| 2752 | −does not belong to the class, or end of file; | |
| 2753 | −since it can match a sequence of zero characters, it never fails. | |
| 2754 | −A character class followed by <CODE>+</CODE> reads until a character that | |
| 2755 | −does not belong to the class, or end of file; | |
| 2756 | −it fails if it cannot read at least one character. | |
| 2757 | −Note that the behavior of read patterns is slightly different from | |
| 2758 | −the regular pattern matching behavior, | |
| 2759 | −where a <CODE>*</CODE> expands to the maximum length <EM>such that</EM> | |
| 2760 | −the rest of the pattern does not fail. | |
| 2761 | −With the read pattern behavior | |
| 2762 | −there is no need for backtracking the reading. | |
| 2763 | −<P> | |
| 2764 | −A pattern item may contain sub-patterns enclosed in curly brackets, | |
| 2765 | −that describe <A NAME="skips"><EM>skips</EM></A>. | |
| 2766 | −Characters matching a skip are read, | |
| 2767 | −but are not included in the resulting string. | |
| 2768 | −<P> | |
| 2769 | −There are some predefined patterns, as follows: | |
| 3159 | +The available formats are | |
| 2770 | 3160 | <DL> |
| 2771 | 3161 | <DT><B>``*n''</B><DD> reads a number; |
| 2772 | −this is the only pattern that returns a number instead of a string. | |
| 2773 | −<DT><B>``*l''</B><DD> returns the next line | |
| 3162 | +this is the only format that returns a number instead of a string. | |
| 3163 | +<DT><B>``*l''</B><DD> reads the next line | |
| 2774 | 3164 | (skipping the end of line), or <B>nil</B> on end of file. |
| 2775 | −This is the default pattern. | |
| 2776 | −It is equivalent to the pattern <CODE>"[^\n]*{\n}"</CODE>. | |
| 2777 | −<DT><B>``*a''</B><DD> reads the whole file. | |
| 2778 | −It is equivalent to the pattern <CODE>".*"</CODE>. | |
| 2779 | −<DT><B>``*w''</B><DD> returns the next word | |
| 2780 | −(maximal sequence of non white-space characters), | |
| 3165 | +This is the default format. | |
| 3166 | +<DT><B>``*a''</B><DD> reads the whole file, starting at the current position. | |
| 3167 | +On end of file, it returns the empty string. | |
| 3168 | +<DT><B>``*w''</B><DD> reads the next word | |
| 3169 | +(maximal sequence of non--white-space characters), | |
| 2781 | 3170 | skipping spaces if necessary, or <B>nil</B> on end of file. |
| 2782 | −It is equivalent to the pattern <CODE>"{%s*}%S+"</CODE>. | |
| 3171 | +<DT><B><EM>number</EM></B><DD> reads a string with up to that number of characters, | |
| 3172 | +or <B>nil</B> on end of file. | |
| 2783 | 3173 | </DL> |
| 2784 | 3174 | <P> |
| 2785 | 3175 | <h3> <TT>write ([filehandle, ] value1, ...)</TT></h3><A NAME="write"></A> |
| @@ -2793,41 +3183,45 @@ use <CODE>tostring</CODE> or <CODE>format</CODE> before <CODE>write</CODE>. · 7 unmodified lines | ||
| 2793 | 3183 | If this function fails, it returns <B>nil</B>, |
| 2794 | 3184 | plus a string describing the error. |
| 2795 | 3185 | <P> |
| 3186 | +<A NAME="libiosys"></A> | |
| 3187 | +<A NAME="6.5"></A> | |
| 3188 | +<H2>6.5 - System Facilities</H2> | |
| 3189 | +<P> | |
| 3190 | +<h3> <TT>clock ()</TT></h3><A NAME="clock"></A> | |
| 3191 | +<P> | |
| 3192 | +Returns an approximation of the amount of CPU time | |
| 3193 | +used by the program, in seconds. | |
| 3194 | +<P> | |
| 2796 | 3195 | <h3> <TT>date ([format])</TT></h3><A NAME="date"></A> |
| 2797 | 3196 | <P> |
| 2798 | 3197 | Returns a string containing date and time |
| 2799 | 3198 | formatted according to the given string <CODE>format</CODE>, |
| 2800 | −following the same rules of the ANSI C function <CODE>strftime</CODE>. | |
| 3199 | +following the same rules of the ANSI C function <CODE>strftime</CODE>. | |
| 2801 | 3200 | When called without arguments, |
| 2802 | 3201 | it returns a reasonable date and time representation that depends on |
| 2803 | −the host system and on the locale. | |
| 3202 | +the host system and on the current locale. | |
| 2804 | 3203 | <P> |
| 2805 | −<h3> <TT>clock ()</TT></h3><A NAME="clock"></A> | |
| 3204 | +<h3> <TT>execute (command)</TT></h3><A NAME="execute"></A> | |
| 2806 | 3205 | <P> |
| 2807 | −Returns an approximation of the amount of CPU time | |
| 2808 | −used by the program, in seconds. | |
| 3206 | +This function is equivalent to the C function <CODE>system</CODE>. | |
| 3207 | +It passes <CODE>command</CODE> to be executed by an operating system shell. | |
| 3208 | +It returns a status code, which is system-dependent. | |
| 2809 | 3209 | <P> |
| 2810 | 3210 | <h3> <TT>exit ([code])</TT></h3><A NAME="exit"></A> |
| 2811 | 3211 | <P> |
| 2812 | −Calls the C function <CODE>exit</CODE>, | |
| 3212 | +Calls the C function <CODE>exit</CODE>, | |
| 2813 | 3213 | with an optional <CODE>code</CODE>, |
| 2814 | 3214 | to terminate the program. |
| 2815 | −The default value for <CODE>code</CODE> is 1. | |
| 3215 | +The default value for <CODE>code</CODE> is the success code. | |
| 2816 | 3216 | <P> |
| 2817 | 3217 | <h3> <TT>getenv (varname)</TT></h3><A NAME="getenv"></A> |
| 2818 | 3218 | <P> |
| 2819 | 3219 | Returns the value of the process environment variable <CODE>varname</CODE>, |
| 2820 | 3220 | or <B>nil</B> if the variable is not defined. |
| 2821 | 3221 | <P> |
| 2822 | −<h3> <TT>execute (command)</TT></h3><A NAME="execute"></A> | |
| 2823 | −<P> | |
| 2824 | −This function is equivalent to the C function <CODE>system</CODE>. | |
| 2825 | −It passes <CODE>command</CODE> to be executed by an operating system shell. | |
| 2826 | −It returns an error code, which is system-dependent. | |
| 2827 | −<P> | |
| 2828 | 3222 | <h3> <TT>setlocale (locale [, category])</TT></h3><A NAME="setlocale"></A> |
| 2829 | 3223 | <P> |
| 2830 | −This function is an interface to the ANSI C function <CODE>setlocale</CODE>. | |
| 3224 | +This function is an interface to the ANSI C function <CODE>setlocale</CODE>. | |
| 2831 | 3225 | <CODE>locale</CODE> is a string specifying a locale; |
| 2832 | 3226 | <CODE>category</CODE> is an optional string describing which category to change: |
| 2833 | 3227 | <CODE>"all"</CODE>, <CODE>"collate"</CODE>, <CODE>"ctype"</CODE>, |
| @@ -2841,7 +3235,7 @@ or <B>nil</B> if the request cannot be honored. · 7 unmodified lines | ||
| 2841 | 3235 | <!-- ====================================================================== --> |
| 2842 | 3236 | <HR> |
| 2843 | 3237 | <A NAME="7."></A> |
| 2844 | −<H1>7 - The Debugger Interface</H1> | |
| 3238 | +<H1>7 - The Debug Interface</H1> | |
| 2845 | 3239 | <P> |
| 2846 | 3240 | Lua has no built-in debugging facilities. |
| 2847 | 3241 | Instead, it offers a special interface, |
| @@ -2849,264 +3243,302 @@ by means of functions and <EM>hooks</EM>, · 1 unmodified line | ||
| 2849 | 3243 | which allows the construction of different |
| 2850 | 3244 | kinds of debuggers, profilers, and other tools |
| 2851 | 3245 | that need ``inside information'' from the interpreter. |
| 2852 | −This interface is declared in the header file <CODE>luadebug.h</CODE>. | |
| 3246 | +This interface is declared in <CODE>luadebug.h</CODE>. | |
| 2853 | 3247 | <P> |
| 2854 | 3248 | <A NAME="7.1"></A> |
| 2855 | 3249 | <H2>7.1 - Stack and Function Information</H2> |
| 2856 | 3250 | <P> |
| 2857 | −The main function to get information about the interpreter stack | |
| 2858 | −is | |
| 3251 | +<A NAME="lua_getstack"></A> | |
| 3252 | +The main function to get information about the interpreter stack is | |
| 2859 | 3253 | <PRE> |
| 2860 | −lua_Function lua_stackedfunction (int level); | |
| 3254 | + int lua_getstack (lua_State *L, int level, lua_Debug *ar); | |
| 2861 | 3255 | </PRE> |
| 2862 | −It returns a handle (<CODE>lua_Function</CODE>) to the <EM>activation record</EM> | |
| 3256 | +It fills parts of a <CODE>lua_Debug</CODE> structure with | |
| 3257 | +an identification of the <EM>activation record</EM> | |
| 2863 | 3258 | of the function executing at a given level. |
| 2864 | 3259 | Level 0 is the current running function, |
| 2865 | −while level <I>n+1</I> is the function that has called level <I>n</I>. | |
| 2866 | −When called with a level greater than the stack depth, | |
| 2867 | −<CODE>lua_stackedfunction</CODE> returns <CODE>LUA_NOOBJECT</CODE>. | |
| 2868 | −<P> | |
| 2869 | −The type <CODE>lua_Function</CODE> is just another name | |
| 2870 | −to <CODE>lua_Object</CODE>. | |
| 2871 | −Although, in this library, | |
| 2872 | −a <CODE>lua_Function</CODE> can be used wherever a <CODE>lua_Object</CODE> is required, | |
| 2873 | −when a parameter has type <CODE>lua_Function</CODE> | |
| 2874 | −it accepts only a handle returned by | |
| 2875 | −<CODE>lua_stackedfunction</CODE>. | |
| 2876 | −<P> | |
| 2877 | −Three other functions produce extra information about a function: | |
| 2878 | −<PRE> | |
| 2879 | −void lua_funcinfo (lua_Object func, char **source, int *linedefined); | |
| 2880 | −int lua_currentline (lua_Function func); | |
| 2881 | −char *lua_getobjname (lua_Object o, char **name); | |
| 2882 | −</PRE> | |
| 2883 | −<CODE>lua_funcinfo</CODE> gives the source and the line where the | |
| 2884 | −given function has been defined: | |
| 3260 | +whereas level <I>n+1</I> is the function that has called level <I>n</I>. | |
| 3261 | +Usually, <CODE>lua_getstack</CODE> returns 1; | |
| 3262 | +when called with a level greater than the stack depth, | |
| 3263 | +it returns 0. | |
| 3264 | +<P> | |
| 3265 | +<A NAME="lua_Debug"></A> | |
| 3266 | +The structure <CODE>lua_Debug</CODE> is used to carry different pieces of | |
| 3267 | +information about an active function: | |
| 3268 | +<PRE> | |
| 3269 | + typedef struct lua_Debug { | |
| 3270 | + const char *event; /* "call", "return" */ | |
| 3271 | + int currentline; /* (l) */ | |
| 3272 | + const char *name; /* (n) */ | |
| 3273 | + const char *namewhat; /* (n) global, tag method, local, field */ | |
| 3274 | + int nups; /* (u) number of upvalues */ | |
| 3275 | + int linedefined; /* (S) */ | |
| 3276 | + const char *what; /* (S) "Lua" function, "C" function, Lua "main" */ | |
| 3277 | + const char *source; /* (S) */ | |
| 3278 | + char short_src[LUA_IDSIZE]; /* (S) */ | |
| 3279 | +<P> | |
| 3280 | + /* private part */ | |
| 3281 | + ... | |
| 3282 | + } lua_Debug; | |
| 3283 | +</PRE> | |
| 3284 | +<CODE>lua_getstack</CODE> fills only the private part | |
| 3285 | +of this structure, for future use. | |
| 3286 | +To fill in the other fields of <CODE>lua_Debug</CODE> with useful information, | |
| 3287 | +call <A NAME="lua_getinfo"></A> | |
| 3288 | +<PRE> | |
| 3289 | + int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); | |
| 3290 | +</PRE> | |
| 3291 | +This function returns 0 on error | |
| 3292 | +(e.g., an invalid option in <CODE>what</CODE>). | |
| 3293 | +Each character in the string <CODE>what</CODE> | |
| 3294 | +selects some fields of <CODE>ar</CODE> to be filled, | |
| 3295 | +as indicated by the letter in parentheses in the definition of <CODE>lua_Debug</CODE>: | |
| 3296 | +`<CODE>S</CODE>' fills in the fields <CODE>source</CODE>, <CODE>linedefined</CODE>, | |
| 3297 | +and <CODE>what</CODE>; | |
| 3298 | +`<CODE>l</CODE>' fills in the field <CODE>currentline</CODE>, etc. | |
| 3299 | +Moreover, `<CODE>f</CODE>' pushes onto the stack the function that is | |
| 3300 | +running at the given level. | |
| 3301 | +<P> | |
| 3302 | +To get information about a function that is not active (that is, | |
| 3303 | +it is not in the stack), | |
| 3304 | +you push the function onto the stack, | |
| 3305 | +and start the <CODE>what</CODE> string with the character <CODE>></CODE>. | |
| 3306 | +For instance, to know in which line a function <CODE>f</CODE> was defined, | |
| 3307 | +you can write | |
| 3308 | +<PRE> | |
| 3309 | + lua_Debug ar; | |
| 3310 | + lua_getglobal(L, "f"); | |
| 3311 | + lua_getinfo(L, ">S", &ar); | |
| 3312 | + printf("%d\n", ar.linedefined); | |
| 3313 | +</PRE> | |
| 3314 | +The fields of <CODE>lua_Debug</CODE> have the following meaning: | |
| 3315 | +<DL> | |
| 3316 | +<P> | |
| 3317 | +<DT><B>source</B><DD> | |
| 2885 | 3318 | If the function was defined in a string, |
| 2886 | 3319 | <CODE>source</CODE> is that string; |
| 2887 | −If the function was defined in a file, | |
| 3320 | +if the function was defined in a file, | |
| 2888 | 3321 | <CODE>source</CODE> starts with a <CODE>@</CODE> followed by the file name. |
| 2889 | −If the ``function'' is in fact the main code of a chunk, | |
| 2890 | −then <CODE>linedefined</CODE> is 0. | |
| 2891 | −If the function is a C function, | |
| 2892 | −then <CODE>linedefined</CODE> is <I>-1</I>, and <CODE>filename</CODE> is <CODE>"(C)"</CODE>. | |
| 2893 | −<P> | |
| 2894 | −The function <CODE>lua_currentline</CODE> gives the current line where | |
| 2895 | −a given function is executing. | |
| 2896 | −It only works if the function has been compiled with debug | |
| 2897 | −information. | |
| 2898 | −When no line information is available, | |
| 2899 | −<CODE>lua_currentline</CODE> returns <I>-1</I>. | |
| 2900 | 3322 | <P> |
| 2901 | −The generation of debug information is controled by an internal flag, | |
| 2902 | −which can be switched with | |
| 2903 | −<PRE> | |
| 2904 | −int lua_setdebug (int debug); | |
| 2905 | −</PRE> | |
| 2906 | −This function sets the flag and returns its previous value. | |
| 2907 | −This flag can also be set from Lua (see Section <A HREF="#pragma">4.9</A>). | |
| 3323 | +<DT><B>short_src</B><DD> | |
| 3324 | +A ``printable'' version of <CODE>source</CODE>, to be used in error messages. | |
| 3325 | +<P> | |
| 3326 | +<DT><B>linedefined</B><DD> | |
| 3327 | +the line number where the definition of the function starts. | |
| 3328 | +<P> | |
| 3329 | +<DT><B>what</B><DD> the string <CODE>"Lua"</CODE> if this is a Lua function, | |
| 3330 | +<CODE>"C"</CODE> if this is a C function, | |
| 3331 | +or <CODE>"main"</CODE> if this is the main part of a chunk. | |
| 3332 | +<P> | |
| 3333 | +<DT><B>currentline</B><DD> | |
| 3334 | +the current line where the given function is executing. | |
| 3335 | +When no line information is available, | |
| 3336 | +<CODE>currentline</CODE> is set to <I>-1</I>. | |
| 2908 | 3337 | <P> |
| 2909 | −Function <CODE>lua_getobjname</CODE> tries to find a reasonable name for | |
| 2910 | −a given function. | |
| 3338 | +<DT><B>name</B><DD> | |
| 3339 | +a reasonable name for the given function. | |
| 2911 | 3340 | Because functions in Lua are first class values, |
| 2912 | 3341 | they do not have a fixed name: |
| 2913 | 3342 | Some functions may be the value of many global variables, |
| 2914 | 3343 | while others may be stored only in a table field. |
| 2915 | −Function <CODE>lua_getobjname</CODE> checks whether the given | |
| 3344 | +The <CODE>lua_getinfo</CODE> function checks whether the given | |
| 2916 | 3345 | function is a tag method or the value of a global variable. |
| 2917 | −If the given function is a tag method, then <CODE>lua_getobjname</CODE> | |
| 2918 | −returns the string <CODE>"tag-method"</CODE>, | |
| 2919 | −and <CODE>name</CODE> is set to point to the event name. | |
| 3346 | +If the given function is a tag method, | |
| 3347 | +then <CODE>name</CODE> points to the event name. | |
| 2920 | 3348 | If the given function is the value of a global variable, |
| 2921 | −then <CODE>lua_getobjname</CODE> returns the string <CODE>"global"</CODE>, | |
| 2922 | −and <CODE>name</CODE> points to the variable name. | |
| 3349 | +then <CODE>name</CODE> points to the variable name. | |
| 2923 | 3350 | If the given function is neither a tag method nor a global variable, |
| 2924 | −then <CODE>lua_getobjname</CODE> returns the empty string, | |
| 2925 | −and <CODE>name</CODE> is set to <CODE>NULL</CODE>. | |
| 3351 | +then <CODE>name</CODE> is set to <CODE>NULL</CODE>. | |
| 3352 | +<P> | |
| 3353 | +<DT><B>namewhat</B><DD> | |
| 3354 | +Explains the previous field. | |
| 3355 | +If the function is a global variable, | |
| 3356 | +<CODE>namewhat</CODE> is <CODE>"global"</CODE>; | |
| 3357 | +if the function is a tag method, | |
| 3358 | +<CODE>namewhat</CODE> is <CODE>"tag-method"</CODE>; | |
| 3359 | +otherwise <CODE>namewhat</CODE> is <CODE>""</CODE> (the empty string). | |
| 3360 | +<P> | |
| 3361 | +<DT><B>nups</B><DD> | |
| 3362 | +Number of upvalues of a function. | |
| 3363 | +<P> | |
| 3364 | +</DL> | |
| 3365 | +<P> | |
| 2926 | 3366 | <P> |
| 2927 | 3367 | <A NAME="7.2"></A> |
| 2928 | 3368 | <H2>7.2 - Manipulating Local Variables</H2> |
| 2929 | 3369 | <P> |
| 3370 | +For the manipulation of local variables, | |
| 3371 | +<CODE>luadebug.h</CODE> uses indices: | |
| 3372 | +The first parameter or local variable has index 1, and so on, | |
| 3373 | +until the last active local variable. | |
| 3374 | +<P> | |
| 3375 | +<A NAME="lua_getlocal"></A><A NAME="lua_setlocal"></A> | |
| 2930 | 3376 | The following functions allow the manipulation of the |
| 2931 | 3377 | local variables of a given activation record. |
| 2932 | −They only work if the function has been compiled with debug | |
| 2933 | −information (see Section <A HREF="#pragma">4.9</A>). | |
| 2934 | −Moreover, for these functions, a local variable becomes | |
| 2935 | −visible in the line after its definition. | |
| 2936 | −<PRE> | |
| 2937 | −lua_Object lua_getlocal (lua_Function func, int local_number, char **name); | |
| 2938 | −int lua_setlocal (lua_Function func, int local_number); | |
| 2939 | −</PRE> | |
| 2940 | −<CODE>lua_getlocal</CODE> returns the value of a local variable, | |
| 2941 | −and sets <CODE>name</CODE> to point to the variable name. | |
| 2942 | −<CODE>local_number</CODE> is an index for local variables. | |
| 2943 | −The first parameter has index 1, and so on, until the | |
| 2944 | −last active local variable. | |
| 2945 | −When called with a <CODE>local_number</CODE> greater than the | |
| 2946 | −number of active local variables, | |
| 2947 | −or if the activation record has no debug information, | |
| 2948 | −<CODE>lua_getlocal</CODE> returns <CODE>LUA_NOOBJECT</CODE>. | |
| 2949 | −Formal parameters are the first local variables. | |
| 2950 | −<P> | |
| 2951 | −The function <CODE>lua_setlocal</CODE> sets the local variable | |
| 2952 | −<CODE>local_number</CODE> to the value previously pushed on the stack | |
| 2953 | −(see Section <A HREF="#valuesCLua">5.2</A>). | |
| 2954 | −If the function succeeds, then it returns 1. | |
| 2955 | −If <CODE>local_number</CODE> is greater than the number | |
| 2956 | −of active local variables, | |
| 2957 | −or if the activation record has no debug information, | |
| 2958 | −then this function fails and returns 0. | |
| 2959 | −<P> | |
| 3378 | +<PRE> | |
| 3379 | + const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); | |
| 3380 | + const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); | |
| 3381 | +</PRE> | |
| 3382 | +The parameter <CODE>ar</CODE> must be a valid activation record, | |
| 3383 | +filled by a previous call to <CODE>lua_getstack</CODE> or | |
| 3384 | +given as argument to a hook (see Section <A HREF="#sub-hooks">7.3</A>). | |
| 3385 | +Function <CODE>lua_getlocal</CODE> gets the index of a local variable | |
| 3386 | +(<CODE>n</CODE>), pushes its value onto the stack, | |
| 3387 | +and returns its name. | |
| 3388 | +For <CODE>lua_setlocal</CODE>, | |
| 3389 | +you push the new value onto the stack, | |
| 3390 | +and the function assigns that value to the variable and returns its name. | |
| 3391 | +Both functions return <CODE>NULL</CODE> on failure; | |
| 3392 | +that happens if the index is greater than | |
| 3393 | +the number of active local variables. | |
| 3394 | +<P> | |
| 3395 | +As an example, the following function lists the names of all | |
| 3396 | +local variables for a function at a given level of the stack: | |
| 3397 | +<PRE> | |
| 3398 | + int listvars (lua_State *L, int level) { | |
| 3399 | + lua_Debug ar; | |
| 3400 | + int i = 1; | |
| 3401 | + const char *name; | |
| 3402 | + if (lua_getstack(L, level, &ar) == 0) | |
| 3403 | + return 0; /* failure: no such level in the stack */ | |
| 3404 | + while ((name = lua_getlocal(L, &ar, i++)) != NULL) { | |
| 3405 | + printf("%s\n", name); | |
| 3406 | + lua_pop(L, 1); /* remove variable value */ | |
| 3407 | + } | |
| 3408 | + return 1; | |
| 3409 | + } | |
| 3410 | +</PRE> | |
| 3411 | +<P> | |
| 3412 | +<P> | |
| 3413 | +<A NAME="sub-hooks"></A> | |
| 2960 | 3414 | <A NAME="7.3"></A> |
| 2961 | 3415 | <H2>7.3 - Hooks</H2> |
| 2962 | 3416 | <P> |
| 2963 | 3417 | The Lua interpreter offers two hooks for debugging purposes: |
| 3418 | +a <EM>call</EM> hook and a <EM>line</EM> hook. | |
| 3419 | +Both have the same type, | |
| 3420 | +<A NAME="lua_Hook"></A> | |
| 2964 | 3421 | <PRE> |
| 2965 | −typedef void (*lua_CHFunction) (lua_Function func, char *file, int line); | |
| 2966 | −lua_CHFunction lua_setcallhook (lua_CHFunction func); | |
| 2967 | −<P> | |
| 2968 | −typedef void (*lua_LHFunction) (int line); | |
| 2969 | −lua_LHFunction lua_setlinehook (lua_LHFunction func); | |
| 3422 | + typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); | |
| 3423 | +</PRE> | |
| 3424 | +and you can set them with the following functions: | |
| 3425 | +<A NAME="lua_setcallhook"></A><A NAME="lua_setlinehook"></A> | |
| 3426 | +<PRE> | |
| 3427 | + lua_Hook lua_setcallhook (lua_State *L, lua_Hook func); | |
| 3428 | + lua_Hook lua_setlinehook (lua_State *L, lua_Hook func); | |
| 2970 | 3429 | </PRE> |
| 2971 | −The first hook is called whenever the interpreter enters or leaves a | |
| 2972 | −function. | |
| 2973 | −When entering a function, | |
| 2974 | −its parameters are a handle to the function activation record, | |
| 2975 | −plus the file and the line where the function is defined | |
| 2976 | −(the same information which is provided by <CODE>lua_funcinfo</CODE>); | |
| 2977 | −when leaving a function, <CODE>func</CODE> is <CODE>LUA_NOOBJECT</CODE>, | |
| 2978 | −<CODE>file</CODE> is <CODE>"(return)"</CODE>, and <CODE>line</CODE> is 0. | |
| 2979 | −<P> | |
| 2980 | −The other hook is called every time the interpreter changes | |
| 2981 | −the line of code it is executing. | |
| 2982 | −Its only parameter is the line number | |
| 2983 | −(the same information which is provided by the call | |
| 2984 | −<CODE>lua_currentline(lua_stackedfunction(0))</CODE>). | |
| 2985 | −This second hook is called only if the active function | |
| 2986 | −has been compiled with debug information (see Section <A HREF="#pragma">4.9</A>). | |
| 2987 | −<P> | |
| 2988 | 3430 | A hook is disabled when its value is <CODE>NULL</CODE>, |
| 2989 | 3431 | which is the initial value of both hooks. |
| 2990 | −Both <CODE>lua_setcallhook</CODE> and <CODE>lua_setlinehook</CODE> | |
| 3432 | +The functions <CODE>lua_setcallhook</CODE> and <CODE>lua_setlinehook</CODE> | |
496 more lines aren’t shown here.
| @@ -6,24 +6,29 @@ · 5 unmodified lines | ||
| 6 | 6 | <BODY BGCOLOR="#FFFFFF"> |
| 7 | 7 | |
| 8 | 8 | <HR> |
| 9 | −<H1><A HREF="http://www.tecgraf.puc-rio.br/lua/">Lua</A> documentation</H1> | |
| 9 | +<H1> | |
| 10 | +<IMG SRC="logo.gif" ALT="Lua" ALIGN="bottom"> | |
| 11 | +Documentation | |
| 12 | +</H1> | |
| 10 | 13 | |
| 11 | 14 | <UL> |
| 15 | +<LI><A HREF="http://www.tecgraf.puc-rio.br/lua/">Official web site</A> | |
| 12 | 16 | <LI><A HREF="index.html">Reference manual</A> |
| 17 | +<LI><A HREF="lua.html">lua man page</A> | |
| 13 | 18 | <LI><A HREF="luac.html">luac man page</A> |
| 14 | −<LI><A HREF="../README">README</A> | |
| 15 | −<LI><A HREF="../src/lib/README">src/lib/README</A> | |
| 16 | −<LI><A HREF="../src/lua/README">src/lua/README</A> | |
| 17 | −<LI><A HREF="../src/luac/README">src/luac/README</A> | |
| 18 | −<LI><A HREF="../etc/README">etc/README</A> | |
| 19 | −<LI><A HREF="../test/README">test/README</A> | |
| 20 | −<LI><A HREF="../test/examples/www/README">test/examples/www/README</A> | |
| 19 | +<LI><A HREF="../README">lua/README</A> | |
| 20 | +<LI><A HREF="../src/lib/README">lua/src/lib/README</A> | |
| 21 | +<LI><A HREF="../src/lua/README">lua/src/lua/README</A> | |
| 22 | +<LI><A HREF="../src/luac/README">lua/src/luac/README</A> | |
| 23 | +<LI><A HREF="../etc/README">lua/etc/README</A> | |
| 24 | +<LI><A HREF="../test/README">lua/test/README</A> | |
| 25 | +<LI><A HREF="../test/examples/www/README">lua/test/examples/www/README</A> | |
| 21 | 26 | </UL> |
| 22 | 27 | |
| 23 | 28 | <HR> |
| 24 | 29 | <SMALL> |
| 25 | 30 | Last update: |
| 26 | −Wed Jul 7 13:24:17 EST 1999 | |
| 31 | +Mon Nov 6 19:13:31 EDT 2000 | |
| 27 | 32 | by <A HREF="http://www.tecgraf.puc-rio.br/~lhf/">lhf</A>. |
| 28 | 33 | </SMALL> |
| 29 | 34 | |
| @@ -4,21 +4,35 @@ LUA= .. · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | include $(LUA)/config |
| 6 | 6 | |
| 7 | −ALL= bin2c min trace | |
| 7 | +LIBLUA=$(LIB)/liblua.a | |
| 8 | +ALL= bin2c min trace lua.def | |
| 9 | + | |
| 10 | +x: | |
| 11 | + @echo 'choose a target:' all $(ALL) | |
| 8 | 12 | |
| 9 | 13 | all: $(ALL) |
| 10 | 14 | |
| 11 | −bin2c: bin2c.c | |
| 12 | − $(CC) -o $@ $< | |
| 15 | +bin2c: bin2c.c | |
| 16 | + $(CC) $(CFLAGS) -o $@ $@.c | |
| 17 | + | |
| 18 | +min: min.c $(LIBLUA) | |
| 19 | + $(CC) $(CFLAGS) -o $@ $@.c -L$(LIB) -llua | |
| 20 | + | |
| 21 | +trace: trace.c $(LIBLUA) | |
| 22 | + $(CC) $(CFLAGS) -o $@ $@.c -L$(LIB) -llua -llualib -lm | |
| 23 | + | |
| 24 | +def: lua.def | |
| 13 | 25 | |
| 14 | −min: min.c $(LIB)/liblua.a | |
| 15 | − $(CC) $(CFLAGS) -o $@ $< -L$(LIB) -llua | |
| 26 | +lua.def: $(INC)/lua.h | |
| 27 | + $(BIN)/lua def.lua < $(INC)/lua.h > $@ | |
| 28 | + # cat $(INC)/l*.h | $(BIN)/lua def.lua > $@ | |
| 16 | 29 | |
| 17 | −trace: trace.c $(LIB)/liblua.a | |
| 18 | − $(CC) $(CFLAGS) -o $@ $< -L$(LIB) -llua | |
| 30 | +stdcall: | |
| 31 | + mkdir -p Stdcall | |
| 32 | + grep -l _API $(LUA)/src/*.[ch] $(LUA)/src/*/*.[ch] | xargs -n1 -i echo $(BIN)/lua stdcall.lua '<{}' '>Stdcall/{}' | |
| 19 | 33 | |
| 20 | −$(LIB)/liblua.a: | |
| 21 | − cd ../src; make | |
| 34 | +$(LIBLUA): | |
| 35 | + cd ../src; $(MAKE) | |
| 22 | 36 | |
| 23 | 37 | clean: |
| 24 | 38 | rm -f $(ALL) |
| @@ -2,25 +2,42 @@ This directory contains some code that might be useful. · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | bin2c.c |
| 4 | 4 | This program converts files to byte arrays that are automatically |
| 5 | − run with lua_dobuffer. | |
| 6 | − This allows C programs to include all necessary Lua code, even in | |
| 7 | − precompiled form. | |
| 8 | − Even if the code is included in source form, bin2c is useful because it | |
| 9 | − avoids the hassle of having to quote special characters in C strings. | |
| 5 | + run with lua_dobuffer. This allows C programs to include all necessary | |
| 6 | + Lua code, even in precompiled form. Even if the code is included in | |
| 7 | + source form, bin2c is useful because it avoids the hassle of having to | |
| 8 | + quote special characters in C strings. | |
| 10 | 9 | Example of usage: Run bin2c file1 file2 ... > init.h. Then, in your C |
| 11 | 10 | program, just do #include "init.h" anywhere in the *body* of a |
| 12 | 11 | function. This will be equivalent to calling |
| 13 | − lua_dofile("file1"); lua_dofile("file2"); ... | |
| 12 | + lua_dofile(L,"file1"); lua_dofile(L,"file2"); ... | |
| 13 | + Note that the Lua state is called "L". If you use a different name, | |
| 14 | + say "mystate", just #define L mystate before #include "init.h". | |
| 15 | + | |
| 16 | +def.lua | |
| 17 | + A Lua script for creating .DEF for Windows DLLs. | |
| 18 | + Just do "make def" to create lua.def. | |
| 14 | 19 | |
| 15 | 20 | min.c |
| 16 | − The smallest Lua interpreter possible. | |
| 21 | + A minimal Lua interpreter. | |
| 22 | + | |
| 23 | +lua.ico | |
| 24 | + A Lua icon for Windows. | |
| 25 | + It was drawn by hand by Markus Gritsch <gritsch@iue.tuwien.ac.at>. | |
| 26 | + | |
| 27 | +lua.xpm | |
| 28 | + The same icon as lua.ico, but in XPM format. | |
| 29 | + It was converted with ImageMagick by Andy Tai <andy@exp.com>. | |
| 30 | + | |
| 31 | +lua.magic | |
| 32 | + Data for teaching file(1) about Lua precompiled chunks. | |
| 33 | + | |
| 34 | +stdcall.lua | |
| 35 | + A Lua script for changing the calling convention to __stdcall. | |
| 36 | + Do "make stdcall" and new modules will be created in stdcall/. | |
| 17 | 37 | |
| 18 | 38 | setfallback.lua |
| 19 | − An implementation of fallbacks on top of tag methods. | |
| 20 | − Useful if you have Lua code written for version 2.5 or earlier, | |
| 21 | − which uses setfallback. | |
| 22 | − If you have C code that uses lua_setfallback, then define LUA_COMPAT2_5 | |
| 23 | − before building Lua (see config). | |
| 39 | + A Lua implementation of fallbacks on top of tag methods. | |
| 40 | + You only need this module if you have Lua code that uses setfallback. | |
| 24 | 41 | |
| 25 | 42 | trace.c |
| 26 | 43 | A simple execution tracer. An example of how to use the debugging hooks. |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * bin2c.c |
| 3 | 3 | * convert binary files to byte arrays |
| 4 | 4 | * Luiz Henrique de Figueiredo (lhf@tecgraf.puc-rio.br) |
| 5 | −* 24 Nov 98 12:15:27 | |
| 5 | +* 11 Sep 2000 22:37:14 | |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #include <ctype.h> |
| @@ -45,7 +45,7 @@ void fdump(char* fn, int n) · 36 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | void emit(char* fn, int n) |
| 47 | 47 | { |
| 48 | − printf(" lua_dobuffer(B%d,sizeof(B%d),\"%s\");\n",n,n,fn); | |
| 48 | + printf(" lua_dobuffer(L,B%d,sizeof(B%d),\"%s\");\n",n,n,fn); | |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | int main(int argc, char* argv[]) |
| @@ -61,7 +61,7 @@ int main(int argc, char* argv[]) · 9 unmodified lines | ||
| 61 | 61 | { |
| 62 | 62 | int i; |
| 63 | 63 | printf("/* #include'ing this file in a C program is equivalent to calling\n"); |
| 64 | − for (i=1; i<argc; i++) printf(" lua_dofile(\"%s\");\n",argv[i]); | |
| 64 | + for (i=1; i<argc; i++) printf(" lua_dofile(L,\"%s\");\n",argv[i]); | |
| 65 | 65 | printf("*/\n"); |
| 66 | 66 | for (i=1; i<argc; i++) fdump(argv[i],i); |
| 67 | 67 | for (i=1; i<argc; i++) emit(argv[i],i); |
| @@ -0,0 +1,9 @@ | ||
| 1 | +-- def.lua | |
| 2 | +-- make .DEF file from lua.h | |
| 3 | +-- usage: lua def.lua <lua.h >lua.def | |
| 4 | + | |
| 5 | +T=read"*a" | |
| 6 | +write("LIBRARY LUA\nVERSION ") | |
| 7 | +gsub(T,"LUA_VERSION.-(%d+%.%d+)",write) | |
| 8 | +write("\nEXPORTS\n") | |
| 9 | +gsub(T,"(lua_%w+)%s+%(",function (f) write(" ",f,"\n") end) | |
Binary file not shown.
| @@ -0,0 +1,10 @@ | ||
| 1 | + | |
| 2 | +# Lua precompiled files | |
| 3 | +0 string \33Lua precompiled chunk for Lua | |
| 4 | +>4 byte 0x23 2.3 | |
| 5 | +>4 byte 0x24 2.4 | |
| 6 | +>4 byte 0x25 2.5 | |
| 7 | +>4 byte 0x30 3.0 | |
| 8 | +>4 byte 0x31 3.1 | |
| 9 | +>4 byte 0x32 3.2 | |
| 10 | +>4 byte 0x40 4.0 | |
| @@ -0,0 +1,44 @@ | ||
| 1 | +/* XPM */ | |
| 2 | +static char *magick[] = { | |
| 3 | +/* columns rows colors chars-per-pixel */ | |
| 4 | +"32 32 6 1", | |
| 5 | +" c Gray0", | |
| 6 | +". c #000000008080", | |
| 7 | +"X c #808080808080", | |
| 8 | +"o c #c0c0c0c0c0c0", | |
| 9 | +"O c Gray100", | |
| 10 | +"+ c None", | |
| 11 | +/* pixels */ | |
| 12 | +"++++++++++++++++++++++++++ooo+++", | |
| 13 | +"++++++++++++++++++++++++oX...Xo+", | |
| 14 | +"++++++++++++++++++++++++X.....X+", | |
| 15 | +"+++++++++++++++++++++++o.......o", | |
| 16 | +"+++++++++XX......XX++++o.......o", | |
| 17 | +"+++++++X............X++o.......o", | |
| 18 | +"+++++o................o+X.....X+", | |
| 19 | +"++++X..................XoX...Xo+", | |
| 20 | +"+++X..............XXX...X+ooo+++", | |
| 21 | +"++o.............XoOOOoX..o++++++", | |
| 22 | +"++..............oOOOOOo...++++++", | |
| 23 | +"+X.............XOOOOOOOX..X+++++", | |
| 24 | +"+..............XOOOOOOOX...+++++", | |
| 25 | +"X..............XOOOOOOOX...X++++", | |
| 26 | +"X...............oOOOOOo....X++++", | |
| 27 | +"................XoOOOoX.....++++", | |
| 28 | +"....XO............XXX.......++++", | |
| 29 | +"....XO......................++++", | |
| 30 | +"....XO.....OX..OX.XOOOo.....++++", | |
| 31 | +"....XO.....OX..OX.OoXXOX....++++", | |
| 32 | +"....XO.....OX..OX....XOX....++++", | |
| 33 | +"X...XO.....OX..OX..OOoOX...X++++", | |
| 34 | +"X...XO.....OX..OX.OX..OX...X++++", | |
| 35 | +"+...XOXXXX.OoXoOX.OXXXOX...+++++", | |
| 36 | +"+X..XOOOOO.XOOXOX.XOOOXo..X+++++", | |
| 37 | +"++........................++++++", | |
| 38 | +"++o......................o++++++", | |
| 39 | +"+++X....................X+++++++", | |
| 40 | +"++++X..................X++++++++", | |
| 41 | +"+++++o................o+++++++++", | |
| 42 | +"+++++++X............X+++++++++++", | |
| 43 | +"+++++++++XX......XX+++++++++++++" | |
| 44 | +}; | |
| @@ -1,13 +1,32 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * min.c |
| 3 | 3 | * a minimal Lua interpreter. loads stdin only. |
| 4 | −* no standard library, only builtin functions. | |
| 4 | +* no standard library, only a "print" function. | |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <stdio.h> | |
| 7 | 8 | #include "lua.h" |
| 8 | 9 | |
| 10 | +/* a simple "print". based on the code in lbaselib.c */ | |
| 11 | +static int print(lua_State *L) | |
| 12 | +{ | |
| 13 | + int n=lua_gettop(L); | |
| 14 | + int i; | |
| 15 | + for (i=1; i<=n; i++) | |
| 16 | + { | |
| 17 | + if (i>1) printf("\t"); | |
| 18 | + if (lua_isstring(L,i)) | |
| 19 | + printf("%s",lua_tostring(L,i)); | |
| 20 | + else | |
| 21 | + printf("%s:%p",lua_typename(L,lua_type(L,i)),lua_topointer(L,i)); | |
| 22 | + } | |
| 23 | + printf("\n"); | |
| 24 | + return 0; | |
| 25 | +} | |
| 26 | + | |
| 9 | 27 | int main(void) |
| 10 | 28 | { |
| 11 | − lua_open(); | |
| 12 | − return lua_dofile(0); | |
| 29 | + lua_State *L=lua_open(0); | |
| 30 | + lua_register(L,"print",print); | |
| 31 | + return lua_dofile(L,NULL); | |
| 13 | 32 | } |
| @@ -0,0 +1,10 @@ | ||
| 1 | +-- stdcall.lua | |
| 2 | +-- add __stdcall where appropriate | |
| 3 | +-- usage: lua stdcall.lua <lua.h >s_lua.h | |
| 4 | +-- usage: lua stdcall.lua <lapi.c >s_lapi.c | |
| 5 | + | |
| 6 | +T=read"*a" | |
| 7 | +T=gsub(T,"(lua_%w+%s+%()","__stdcall %1") | |
| 8 | +T=gsub(T,"(%*lua_CFunction)","__stdcall %1") | |
| 9 | + | |
| 10 | +write(T) | |
| @@ -6,44 +6,51 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <stdio.h> |
| 7 | 7 | #include <string.h> |
| 8 | 8 | #include "lua.h" |
| 9 | +#include "lualib.h" | |
| 9 | 10 | #include "luadebug.h" |
| 10 | 11 | |
| 12 | +lua_State *lua_state = NULL; | |
| 13 | +#define L lua_state /* lazy! */ | |
| 14 | + | |
| 11 | 15 | static FILE* LOG; /* output file */ |
| 12 | −static int L=0; /* indentation level */ | |
| 16 | +static int I=0; /* indentation level */ | |
| 13 | 17 | |
| 14 | −static void linehook(int line) | |
| 18 | +static void linehook(lua_State *L, lua_Debug *ar) | |
| 15 | 19 | { |
| 16 | − fprintf(LOG,"%*sLINE(%d)\t-- %d\n",L,"",line,L); | |
| 20 | + fprintf(LOG,"%*sdo_line(%d)\t-- %d\n",I,"",ar->currentline,I); | |
| 17 | 21 | } |
| 18 | 22 | |
| 19 | −static void callhook(lua_Function func, char* file, int line) | |
| 23 | +static void callhook(lua_State *L, lua_Debug *ar) | |
| 20 | 24 | { |
| 21 | − fprintf(LOG,"%*sCALL('%s',%d)\t-- %d\n",L,"",file,line,L); | |
| 22 | − if (line==0 && strcmp(file,"(return)")==0) --L; else ++L; | |
| 25 | + fprintf(LOG,"%*sdo_%s\t-- %p %d\n",I,"",ar->event,ar->_func,I); | |
| 26 | + if (*ar->event=='r') --I; else ++I; | |
| 23 | 27 | } |
| 24 | 28 | |
| 25 | 29 | void start_trace(FILE* logfile) |
| 26 | 30 | { |
| 27 | − lua_setlinehook(linehook); | |
| 28 | − lua_setcallhook(callhook); | |
| 29 | − lua_setdebug(1); | |
| 31 | + lua_setlinehook(L,linehook); | |
| 32 | + lua_setcallhook(L,callhook); | |
| 30 | 33 | LOG=logfile; |
| 31 | 34 | } |
| 32 | 35 | |
| 33 | 36 | void stop_trace(void) |
| 34 | 37 | { |
| 35 | − lua_setlinehook(NULL); | |
| 36 | − lua_setcallhook(NULL); | |
| 37 | − lua_setdebug(0); | |
| 38 | + lua_setlinehook(L,NULL); | |
| 39 | + lua_setcallhook(L,NULL); | |
| 38 | 40 | fclose(LOG); |
| 39 | 41 | } |
| 40 | 42 | |
| 41 | 43 | int main(void) |
| 42 | 44 | { |
| 43 | 45 | int rc; |
| 44 | − lua_open(); | |
| 46 | + L=lua_open(0); | |
| 47 | + lua_baselibopen(L); | |
| 48 | + lua_iolibopen(L); | |
| 49 | + lua_strlibopen(L); | |
| 50 | + lua_mathlibopen(L); | |
| 51 | + lua_dblibopen(L); | |
| 45 | 52 | start_trace(stderr); |
| 46 | − rc=lua_dofile(0); | |
| 53 | + rc=lua_dofile(L,0); | |
| 47 | 54 | stop_trace(); |
| 48 | 55 | return rc; |
| 49 | 56 | } |
| @@ -1,4 +1,4 @@ | ||
| 1 | −# makefile for lua distribution (includes) | |
| 1 | +# makefile for Lua distribution (includes) | |
| 2 | 2 | |
| 3 | 3 | LUA= .. |
| 4 | 4 | |
| @@ -1,53 +1,100 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lauxlib.h,v 1.12 1999/03/10 14:19:41 roberto Exp $ | |
| 2 | +** $Id: lauxlib.h,v 1.30 2000/10/30 12:38:50 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | −#ifndef auxlib_h | |
| 9 | −#define auxlib_h | |
| 8 | +#ifndef lauxlib_h | |
| 9 | +#define lauxlib_h | |
| 10 | 10 | |
| 11 | 11 | |
| 12 | +#include <stddef.h> | |
| 13 | +#include <stdio.h> | |
| 14 | + | |
| 12 | 15 | #include "lua.h" |
| 13 | 16 | |
| 14 | 17 | |
| 18 | +#ifndef LUALIB_API | |
| 19 | +#define LUALIB_API extern | |
| 20 | +#endif | |
| 21 | + | |
| 22 | + | |
| 15 | 23 | struct luaL_reg { |
| 16 | − char *name; | |
| 24 | + const char *name; | |
| 17 | 25 | lua_CFunction func; |
| 18 | 26 | }; |
| 19 | 27 | |
| 20 | 28 | |
| 21 | −#define luaL_arg_check(cond,numarg,extramsg) if (!(cond)) \ | |
| 22 | − luaL_argerror(numarg,extramsg) | |
| 23 | − | |
| 24 | −void luaL_openlib (struct luaL_reg *l, int n); | |
| 25 | −void luaL_argerror (int numarg, char *extramsg); | |
| 26 | −#define luaL_check_string(n) (luaL_check_lstr((n), NULL)) | |
| 27 | −char *luaL_check_lstr (int numArg, long *len); | |
| 28 | −#define luaL_opt_string(n, d) (luaL_opt_lstr((n), (d), NULL)) | |
| 29 | −char *luaL_opt_lstr (int numArg, char *def, long *len); | |
| 30 | −double luaL_check_number (int numArg); | |
| 31 | −#define luaL_check_int(n) ((int)luaL_check_number(n)) | |
| 32 | −#define luaL_check_long(n) ((long)luaL_check_number(n)) | |
| 33 | −double luaL_opt_number (int numArg, double def); | |
| 34 | −#define luaL_opt_int(n,d) ((int)luaL_opt_number(n,d)) | |
| 35 | −#define luaL_opt_long(n,d) ((long)luaL_opt_number(n,d)) | |
| 36 | −lua_Object luaL_functionarg (int arg); | |
| 37 | −lua_Object luaL_tablearg (int arg); | |
| 38 | −lua_Object luaL_nonnullarg (int numArg); | |
| 39 | −void luaL_verror (char *fmt, ...); | |
| 40 | −char *luaL_openspace (int size); | |
| 41 | −void luaL_resetbuffer (void); | |
| 42 | −void luaL_addchar (int c); | |
| 43 | −int luaL_getsize (void); | |
| 44 | −void luaL_addsize (int n); | |
| 45 | −int luaL_newbuffer (int size); | |
| 46 | −void luaL_oldbuffer (int old); | |
| 47 | −char *luaL_buffer (void); | |
| 48 | −int luaL_findstring (char *name, char *list[]); | |
| 49 | −void luaL_chunkid (char *out, char *source, int len); | |
| 50 | −void luaL_filesource (char *out, char *filename, int len); | |
| 29 | +LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n); | |
| 30 | +LUALIB_API void luaL_argerror (lua_State *L, int numarg, const char *extramsg); | |
| 31 | +LUALIB_API const char *luaL_check_lstr (lua_State *L, int numArg, size_t *len); | |
| 32 | +LUALIB_API const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def, size_t *len); | |
| 33 | +LUALIB_API double luaL_check_number (lua_State *L, int numArg); | |
| 34 | +LUALIB_API double luaL_opt_number (lua_State *L, int numArg, double def); | |
| 35 | + | |
| 36 | +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg); | |
| 37 | +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t); | |
| 38 | +LUALIB_API void luaL_checkany (lua_State *L, int narg); | |
| 39 | + | |
| 40 | +LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...); | |
| 41 | +LUALIB_API int luaL_findstring (const char *name, const char *const list[]); | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | +/* | |
| 46 | +** =============================================================== | |
| 47 | +** some useful macros | |
| 48 | +** =============================================================== | |
| 49 | +*/ | |
| 50 | + | |
| 51 | +#define luaL_arg_check(L, cond,numarg,extramsg) if (!(cond)) \ | |
| 52 | + luaL_argerror(L, numarg,extramsg) | |
| 53 | +#define luaL_check_string(L,n) (luaL_check_lstr(L, (n), NULL)) | |
| 54 | +#define luaL_opt_string(L,n,d) (luaL_opt_lstr(L, (n), (d), NULL)) | |
| 55 | +#define luaL_check_int(L,n) ((int)luaL_check_number(L, n)) | |
| 56 | +#define luaL_check_long(L,n) ((long)luaL_check_number(L, n)) | |
| 57 | +#define luaL_opt_int(L,n,d) ((int)luaL_opt_number(L, n,d)) | |
| 58 | +#define luaL_opt_long(L,n,d) ((long)luaL_opt_number(L, n,d)) | |
| 59 | +#define luaL_openl(L,a) luaL_openlib(L, a, (sizeof(a)/sizeof(a[0]))) | |
| 60 | + | |
| 61 | + | |
| 62 | +/* | |
| 63 | +** {====================================================== | |
| 64 | +** Generic Buffer manipulation | |
| 65 | +** ======================================================= | |
| 66 | +*/ | |
| 67 | + | |
| 68 | + | |
| 69 | +#ifndef LUAL_BUFFERSIZE | |
| 70 | +#define LUAL_BUFFERSIZE BUFSIZ | |
| 71 | +#endif | |
| 72 | + | |
| 73 | + | |
| 74 | +typedef struct luaL_Buffer { | |
| 75 | + char *p; /* current position in buffer */ | |
| 76 | + int level; | |
| 77 | + lua_State *L; | |
| 78 | + char buffer[LUAL_BUFFERSIZE]; | |
| 79 | +} luaL_Buffer; | |
| 80 | + | |
| 81 | +#define luaL_putchar(B,c) \ | |
| 82 | + ((void)((B)->p < &(B)->buffer[LUAL_BUFFERSIZE] || luaL_prepbuffer(B)), \ | |
| 83 | + (*(B)->p++ = (char)(c))) | |
| 84 | + | |
| 85 | +#define luaL_addsize(B,n) ((B)->p += (n)) | |
| 86 | + | |
| 87 | +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B); | |
| 88 | +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B); | |
| 89 | +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l); | |
| 90 | +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s); | |
| 91 | +LUALIB_API void luaL_addvalue (luaL_Buffer *B); | |
| 92 | +LUALIB_API void luaL_pushresult (luaL_Buffer *B); | |
| 93 | + | |
| 94 | + | |
| 95 | +/* }====================================================== */ | |
| 51 | 96 | |
| 52 | 97 | |
| 53 | 98 | #endif |
| 99 | + | |
| 100 | + | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lua.h,v 1.32b 1999/05/11 20:29:19 roberto Exp $ | |
| 2 | +** $Id: lua.h,v 1.79 2000/10/31 12:44:07 roberto Exp $ | |
| 3 | 3 | ** Lua - An Extensible Extension Language |
| 4 | 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil |
| 5 | 5 | ** e-mail: lua@tecgraf.puc-rio.br |
| @@ -11,154 +11,208 @@ · 5 unmodified lines | ||
| 11 | 11 | #ifndef lua_h |
| 12 | 12 | #define lua_h |
| 13 | 13 | |
| 14 | −#define LUA_VERSION "Lua 3.2.2" | |
| 15 | −#define LUA_COPYRIGHT "Copyright (C) 1994-1999 TeCGraf, PUC-Rio" | |
| 14 | + | |
| 15 | +/* definition of `size_t' */ | |
| 16 | +#include <stddef.h> | |
| 17 | + | |
| 18 | + | |
| 19 | +/* mark for all API functions */ | |
| 20 | +#ifndef LUA_API | |
| 21 | +#define LUA_API extern | |
| 22 | +#endif | |
| 23 | + | |
| 24 | + | |
| 25 | +#define LUA_VERSION "Lua 4.0" | |
| 26 | +#define LUA_COPYRIGHT "Copyright (C) 1994-2000 TeCGraf, PUC-Rio" | |
| 16 | 27 | #define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo" |
| 17 | 28 | |
| 18 | 29 | |
| 19 | −#define LUA_NOOBJECT 0 | |
| 30 | +/* name of global variable with error handler */ | |
| 31 | +#define LUA_ERRORMESSAGE "_ERRORMESSAGE" | |
| 20 | 32 | |
| 21 | −#define LUA_ANYTAG (-1) | |
| 22 | 33 | |
| 23 | −typedef struct lua_State lua_State; | |
| 24 | −extern lua_State *lua_state; | |
| 34 | +/* pre-defined references */ | |
| 35 | +#define LUA_NOREF (-2) | |
| 36 | +#define LUA_REFNIL (-1) | |
| 37 | +#define LUA_REFREGISTRY 0 | |
| 38 | + | |
| 39 | +/* pre-defined tags */ | |
| 40 | +#define LUA_ANYTAG (-1) | |
| 41 | +#define LUA_NOTAG (-2) | |
| 25 | 42 | |
| 26 | −typedef void (*lua_CFunction) (void); | |
| 27 | −typedef unsigned int lua_Object; | |
| 28 | 43 | |
| 29 | −void lua_open (void); | |
| 30 | −void lua_close (void); | |
| 31 | −lua_State *lua_setstate (lua_State *st); | |
| 44 | +/* option for multiple returns in lua_call */ | |
| 45 | +#define LUA_MULTRET (-1) | |
| 32 | 46 | |
| 33 | −lua_Object lua_settagmethod (int tag, char *event); /* In: new method */ | |
| 34 | −lua_Object lua_gettagmethod (int tag, char *event); | |
| 35 | 47 | |
| 36 | −int lua_newtag (void); | |
| 37 | −int lua_copytagmethods (int tagto, int tagfrom); | |
| 38 | −void lua_settag (int tag); /* In: object */ | |
| 48 | +/* minimum stack available for a C function */ | |
| 49 | +#define LUA_MINSTACK 20 | |
| 39 | 50 | |
| 40 | −void lua_error (char *s); | |
| 41 | −int lua_dofile (char *filename); /* Out: returns */ | |
| 42 | −int lua_dostring (char *string); /* Out: returns */ | |
| 43 | −int lua_dobuffer (char *buff, int size, char *name); | |
| 44 | − /* Out: returns */ | |
| 45 | −int lua_callfunction (lua_Object f); | |
| 46 | − /* In: parameters; Out: returns */ | |
| 47 | 51 | |
| 48 | −void lua_beginblock (void); | |
| 49 | −void lua_endblock (void); | |
| 52 | +/* error codes for lua_do* */ | |
| 53 | +#define LUA_ERRRUN 1 | |
| 54 | +#define LUA_ERRFILE 2 | |
| 55 | +#define LUA_ERRSYNTAX 3 | |
| 56 | +#define LUA_ERRMEM 4 | |
| 57 | +#define LUA_ERRERR 5 | |
| 50 | 58 | |
| 51 | −lua_Object lua_lua2C (int number); | |
| 52 | −#define lua_getparam(_) lua_lua2C(_) | |
| 53 | −#define lua_getresult(_) lua_lua2C(_) | |
| 54 | 59 | |
| 55 | −int lua_isnil (lua_Object object); | |
| 56 | −int lua_istable (lua_Object object); | |
| 57 | −int lua_isuserdata (lua_Object object); | |
| 58 | −int lua_iscfunction (lua_Object object); | |
| 59 | −int lua_isnumber (lua_Object object); | |
| 60 | −int lua_isstring (lua_Object object); | |
| 61 | −int lua_isfunction (lua_Object object); | |
| 60 | +typedef struct lua_State lua_State; | |
| 61 | + | |
| 62 | +typedef int (*lua_CFunction) (lua_State *L); | |
| 62 | 63 | |
| 63 | −double lua_getnumber (lua_Object object); | |
| 64 | −char *lua_getstring (lua_Object object); | |
| 65 | −long lua_strlen (lua_Object object); | |
| 66 | −lua_CFunction lua_getcfunction (lua_Object object); | |
| 67 | −void *lua_getuserdata (lua_Object object); | |
| 64 | +/* | |
| 65 | +** types returned by `lua_type' | |
| 66 | +*/ | |
| 67 | +#define LUA_TNONE (-1) | |
| 68 | 68 | |
| 69 | +#define LUA_TUSERDATA 0 | |
| 70 | +#define LUA_TNIL 1 | |
| 71 | +#define LUA_TNUMBER 2 | |
| 72 | +#define LUA_TSTRING 3 | |
| 73 | +#define LUA_TTABLE 4 | |
| 74 | +#define LUA_TFUNCTION 5 | |
| 69 | 75 | |
| 70 | −void lua_pushnil (void); | |
| 71 | −void lua_pushnumber (double n); | |
| 72 | −void lua_pushlstring (char *s, long len); | |
| 73 | −void lua_pushstring (char *s); | |
| 74 | −void lua_pushcclosure (lua_CFunction fn, int n); | |
| 75 | −void lua_pushusertag (void *u, int tag); | |
| 76 | −void lua_pushobject (lua_Object object); | |
| 77 | 76 | |
| 78 | −lua_Object lua_pop (void); | |
| 79 | 77 | |
| 80 | −lua_Object lua_getglobal (char *name); | |
| 81 | −lua_Object lua_rawgetglobal (char *name); | |
| 82 | −void lua_setglobal (char *name); /* In: value */ | |
| 83 | −void lua_rawsetglobal (char *name); /* In: value */ | |
| 78 | +/* | |
| 79 | +** state manipulation | |
| 80 | +*/ | |
| 81 | +LUA_API lua_State *lua_open (int stacksize); | |
| 82 | +LUA_API void lua_close (lua_State *L); | |
| 84 | 83 | |
| 85 | −void lua_settable (void); /* In: table, index, value */ | |
| 86 | −void lua_rawsettable (void); /* In: table, index, value */ | |
| 87 | −lua_Object lua_gettable (void); /* In: table, index */ | |
| 88 | −lua_Object lua_rawgettable (void); /* In: table, index */ | |
| 89 | 84 | |
| 90 | −int lua_tag (lua_Object object); | |
| 85 | +/* | |
| 86 | +** basic stack manipulation | |
| 87 | +*/ | |
| 88 | +LUA_API int lua_gettop (lua_State *L); | |
| 89 | +LUA_API void lua_settop (lua_State *L, int index); | |
| 90 | +LUA_API void lua_pushvalue (lua_State *L, int index); | |
| 91 | +LUA_API void lua_remove (lua_State *L, int index); | |
| 92 | +LUA_API void lua_insert (lua_State *L, int index); | |
| 93 | +LUA_API int lua_stackspace (lua_State *L); | |
| 91 | 94 | |
| 92 | −char *lua_nextvar (char *varname); /* Out: value */ | |
| 93 | −int lua_next (lua_Object o, int i); | |
| 94 | − /* Out: ref, value */ | |
| 95 | 95 | |
| 96 | −int lua_ref (int lock); /* In: value */ | |
| 97 | −lua_Object lua_getref (int ref); | |
| 98 | −void lua_unref (int ref); | |
| 96 | +/* | |
| 97 | +** access functions (stack -> C) | |
| 98 | +*/ | |
| 99 | 99 | |
| 100 | −lua_Object lua_createtable (void); | |
| 100 | +LUA_API int lua_type (lua_State *L, int index); | |
| 101 | +LUA_API const char *lua_typename (lua_State *L, int t); | |
| 102 | +LUA_API int lua_isnumber (lua_State *L, int index); | |
| 103 | +LUA_API int lua_isstring (lua_State *L, int index); | |
| 104 | +LUA_API int lua_iscfunction (lua_State *L, int index); | |
| 105 | +LUA_API int lua_tag (lua_State *L, int index); | |
| 101 | 106 | |
| 102 | −long lua_collectgarbage (long limit); | |
| 107 | +LUA_API int lua_equal (lua_State *L, int index1, int index2); | |
| 108 | +LUA_API int lua_lessthan (lua_State *L, int index1, int index2); | |
| 103 | 109 | |
| 110 | +LUA_API double lua_tonumber (lua_State *L, int index); | |
| 111 | +LUA_API const char *lua_tostring (lua_State *L, int index); | |
| 112 | +LUA_API size_t lua_strlen (lua_State *L, int index); | |
| 113 | +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index); | |
| 114 | +LUA_API void *lua_touserdata (lua_State *L, int index); | |
| 115 | +LUA_API const void *lua_topointer (lua_State *L, int index); | |
| 104 | 116 | |
| 105 | −/* =============================================================== */ | |
| 106 | −/* some useful macros/functions */ | |
| 107 | 117 | |
| 108 | −#define lua_call(name) lua_callfunction(lua_getglobal(name)) | |
| 118 | +/* | |
| 119 | +** push functions (C -> stack) | |
| 120 | +*/ | |
| 121 | +LUA_API void lua_pushnil (lua_State *L); | |
| 122 | +LUA_API void lua_pushnumber (lua_State *L, double n); | |
| 123 | +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len); | |
| 124 | +LUA_API void lua_pushstring (lua_State *L, const char *s); | |
| 125 | +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); | |
| 126 | +LUA_API void lua_pushusertag (lua_State *L, void *u, int tag); | |
| 109 | 127 | |
| 110 | −#define lua_pushref(ref) lua_pushobject(lua_getref(ref)) | |
| 111 | 128 | |
| 112 | −#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l)) | |
| 129 | +/* | |
| 130 | +** get functions (Lua -> stack) | |
| 131 | +*/ | |
| 132 | +LUA_API void lua_getglobal (lua_State *L, const char *name); | |
| 133 | +LUA_API void lua_gettable (lua_State *L, int index); | |
| 134 | +LUA_API void lua_rawget (lua_State *L, int index); | |
| 135 | +LUA_API void lua_rawgeti (lua_State *L, int index, int n); | |
| 136 | +LUA_API void lua_getglobals (lua_State *L); | |
| 137 | +LUA_API void lua_gettagmethod (lua_State *L, int tag, const char *event); | |
| 138 | +LUA_API int lua_getref (lua_State *L, int ref); | |
| 139 | +LUA_API void lua_newtable (lua_State *L); | |
| 113 | 140 | |
| 114 | −#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n)) | |
| 115 | 141 | |
| 116 | −#define lua_pushuserdata(u) lua_pushusertag(u, 0) | |
| 142 | +/* | |
| 143 | +** set functions (stack -> Lua) | |
| 144 | +*/ | |
| 145 | +LUA_API void lua_setglobal (lua_State *L, const char *name); | |
| 146 | +LUA_API void lua_settable (lua_State *L, int index); | |
| 147 | +LUA_API void lua_rawset (lua_State *L, int index); | |
| 148 | +LUA_API void lua_rawseti (lua_State *L, int index, int n); | |
| 149 | +LUA_API void lua_setglobals (lua_State *L); | |
| 150 | +LUA_API void lua_settagmethod (lua_State *L, int tag, const char *event); | |
| 151 | +LUA_API int lua_ref (lua_State *L, int lock); | |
| 117 | 152 | |
| 118 | −#define lua_pushcfunction(f) lua_pushcclosure(f, 0) | |
| 119 | 153 | |
| 120 | −#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t)) | |
| 154 | +/* | |
| 155 | +** "do" functions (run Lua code) | |
| 156 | +*/ | |
| 157 | +LUA_API int lua_call (lua_State *L, int nargs, int nresults); | |
| 158 | +LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults); | |
| 159 | +LUA_API int lua_dofile (lua_State *L, const char *filename); | |
| 160 | +LUA_API int lua_dostring (lua_State *L, const char *str); | |
| 161 | +LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name); | |
| 121 | 162 | |
| 122 | −lua_Object lua_seterrormethod (void); /* In: new method */ | |
| 163 | +/* | |
| 164 | +** Garbage-collection functions | |
| 165 | +*/ | |
| 166 | +LUA_API int lua_getgcthreshold (lua_State *L); | |
| 167 | +LUA_API int lua_getgccount (lua_State *L); | |
| 168 | +LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold); | |
| 123 | 169 | |
| 124 | −/* ========================================================================== | |
| 125 | −** for compatibility with old versions. Avoid using these macros/functions | |
| 126 | −** If your program does need any of these, define LUA_COMPAT2_5 | |
| 170 | +/* | |
| 171 | +** miscellaneous functions | |
| 127 | 172 | */ |
| 173 | +LUA_API int lua_newtag (lua_State *L); | |
| 174 | +LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom); | |
| 175 | +LUA_API void lua_settag (lua_State *L, int tag); | |
| 128 | 176 | |
| 177 | +LUA_API void lua_error (lua_State *L, const char *s); | |
| 129 | 178 | |
| 130 | −#ifdef LUA_COMPAT2_5 | |
| 179 | +LUA_API void lua_unref (lua_State *L, int ref); | |
| 131 | 180 | |
| 181 | +LUA_API int lua_next (lua_State *L, int index); | |
| 182 | +LUA_API int lua_getn (lua_State *L, int index); | |
| 132 | 183 | |
| 133 | −lua_Object lua_setfallback (char *event, lua_CFunction fallback); | |
| 184 | +LUA_API void lua_concat (lua_State *L, int n); | |
| 134 | 185 | |
| 135 | −#define lua_storeglobal lua_setglobal | |
| 136 | −#define lua_type lua_tag | |
| 186 | +LUA_API void *lua_newuserdata (lua_State *L, size_t size); | |
| 137 | 187 | |
| 138 | −#define lua_lockobject(o) lua_refobject(o,1) | |
| 139 | −#define lua_lock() lua_ref(1) | |
| 140 | −#define lua_getlocked lua_getref | |
| 141 | −#define lua_pushlocked lua_pushref | |
| 142 | −#define lua_unlock lua_unref | |
| 143 | 188 | |
| 144 | −#define lua_pushliteral(o) lua_pushstring(o) | |
| 189 | +/* | |
| 190 | +** =============================================================== | |
| 191 | +** some useful macros | |
| 192 | +** =============================================================== | |
| 193 | +*/ | |
| 145 | 194 | |
| 146 | −#define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_gettable()) | |
| 147 | −#define lua_getfield(o,f) (lua_pushobject(o), lua_pushstring(f), lua_gettable()) | |
| 195 | +#define lua_pop(L,n) lua_settop(L, -(n)-1) | |
| 148 | 196 | |
| 149 | −#define lua_copystring(o) (strdup(lua_getstring(o))) | |
| 197 | +#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n)) | |
| 198 | +#define lua_pushuserdata(L,u) lua_pushusertag(L, u, 0) | |
| 199 | +#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0) | |
| 200 | +#define lua_clonetag(L,t) lua_copytagmethods(L, lua_newtag(L), (t)) | |
| 150 | 201 | |
| 151 | −#define lua_getsubscript lua_gettable | |
| 152 | −#define lua_storesubscript lua_settable | |
| 202 | +#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION) | |
| 203 | +#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE) | |
| 204 | +#define lua_isuserdata(L,n) (lua_type(L,n) == LUA_TUSERDATA) | |
| 205 | +#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL) | |
| 206 | +#define lua_isnull(L,n) (lua_type(L,n) == LUA_TNONE) | |
| 153 | 207 | |
| 154 | −#endif | |
| 208 | +#define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY) | |
| 155 | 209 | |
| 156 | 210 | #endif |
| 157 | 211 | |
| 158 | 212 | |
| 159 | 213 | |
| 160 | 214 | /****************************************************************************** |
| 161 | −* Copyright (c) 1994-1999 TeCGraf, PUC-Rio. All rights reserved. | |
| 215 | +* Copyright (C) 1994-2000 TeCGraf, PUC-Rio. All rights reserved. | |
| 162 | 216 | * |
| 163 | 217 | * Permission is hereby granted, without written agreement and without license |
| 164 | 218 | * or royalty fees, to use, copy, modify, and distribute this software and its |
| @@ -191,3 +245,4 @@ lua_Object lua_setfallback (char *event, lua_CFunction fallback); · 26 unmodified lines | ||
| 191 | 245 | * |
| 192 | 246 | * This implementation contains no third-party code. |
| 193 | 247 | ******************************************************************************/ |
| 248 | + | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: luadebug.h,v 1.6 1999/03/04 21:17:26 roberto Exp $ | |
| 2 | +** $Id: luadebug.h,v 1.17 2000/10/30 12:38:50 roberto Exp $ | |
| 3 | 3 | ** Debugging API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -11,24 +11,36 @@ · 5 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #include "lua.h" |
| 13 | 13 | |
| 14 | −typedef lua_Object lua_Function; | |
| 14 | +typedef struct lua_Debug lua_Debug; /* activation record */ | |
| 15 | +typedef struct lua_Localvar lua_Localvar; | |
| 15 | 16 | |
| 16 | −typedef void (*lua_LHFunction) (int line); | |
| 17 | −typedef void (*lua_CHFunction) (lua_Function func, char *file, int line); | |
| 17 | +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); | |
| 18 | 18 | |
| 19 | −lua_Function lua_stackedfunction (int level); | |
| 20 | −void lua_funcinfo (lua_Object func, char **source, int *linedefined); | |
| 21 | −int lua_currentline (lua_Function func); | |
| 22 | −char *lua_getobjname (lua_Object o, char **name); | |
| 23 | 19 | |
| 24 | −lua_Object lua_getlocal (lua_Function func, int local_number, char **name); | |
| 25 | −int lua_setlocal (lua_Function func, int local_number); | |
| 20 | +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); | |
| 21 | +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); | |
| 22 | +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); | |
| 23 | +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); | |
| 26 | 24 | |
| 27 | −int lua_nups (lua_Function func); | |
| 25 | +LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func); | |
| 26 | +LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func); | |
| 28 | 27 | |
| 29 | −lua_LHFunction lua_setlinehook (lua_LHFunction func); | |
| 30 | −lua_CHFunction lua_setcallhook (lua_CHFunction func); | |
| 31 | −int lua_setdebug (int debug); | |
| 28 | + | |
| 29 | +#define LUA_IDSIZE 60 | |
| 30 | + | |
| 31 | +struct lua_Debug { | |
| 32 | + const char *event; /* `call', `return' */ | |
| 33 | + int currentline; /* (l) */ | |
| 34 | + const char *name; /* (n) */ | |
| 35 | + const char *namewhat; /* (n) `global', `tag method', `local', `field' */ | |
| 36 | + int nups; /* (u) number of upvalues */ | |
| 37 | + int linedefined; /* (S) */ | |
| 38 | + const char *what; /* (S) `Lua' function, `C' function, Lua `main' */ | |
| 39 | + const char *source; /* (S) */ | |
| 40 | + char short_src[LUA_IDSIZE]; /* (S) */ | |
| 41 | + /* private part */ | |
| 42 | + struct lua_TObject *_func; /* active function */ | |
| 43 | +}; | |
| 32 | 44 | |
| 33 | 45 | |
| 34 | 46 | #endif |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lualib.h,v 1.6 1999/05/05 19:23:11 roberto Exp $ | |
| 2 | +** $Id: lualib.h,v 1.14 2000/10/27 16:15:53 roberto Exp $ | |
| 3 | 3 | ** Lua standard libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -10,27 +10,25 @@ · 4 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include "lua.h" |
| 12 | 12 | |
| 13 | −void lua_iolibopen (void); | |
| 14 | −void lua_strlibopen (void); | |
| 15 | −void lua_mathlibopen (void); | |
| 16 | −void lua_dblibopen (void); | |
| 17 | 13 | |
| 18 | − | |
| 19 | −void lua_userinit (void); | |
| 14 | +#ifndef LUALIB_API | |
| 15 | +#define LUALIB_API extern | |
| 16 | +#endif | |
| 20 | 17 | |
| 21 | 18 | |
| 22 | −/* To keep compatibility with old versions */ | |
| 19 | +#define LUA_ALERT "_ALERT" | |
| 23 | 20 | |
| 24 | −#define iolib_open lua_iolibopen | |
| 25 | −#define strlib_open lua_strlibopen | |
| 26 | −#define mathlib_open lua_mathlibopen | |
| 21 | +LUALIB_API void lua_baselibopen (lua_State *L); | |
| 22 | +LUALIB_API void lua_iolibopen (lua_State *L); | |
| 23 | +LUALIB_API void lua_strlibopen (lua_State *L); | |
| 24 | +LUALIB_API void lua_mathlibopen (lua_State *L); | |
| 25 | +LUALIB_API void lua_dblibopen (lua_State *L); | |
| 27 | 26 | |
| 28 | 27 | |
| 29 | 28 | |
| 30 | 29 | /* Auxiliary functions (private) */ |
| 31 | 30 | |
| 32 | −char *luaI_classend (char *p); | |
| 33 | −int luaI_singlematch (int c, char *p, char *ep); | |
| 31 | +const char *luaI_classend (lua_State *L, const char *p); | |
| 32 | +int luaI_singlematch (int c, const char *p, const char *ep); | |
| 34 | 33 | |
| 35 | 34 | #endif |
| 36 | − | |
| @@ -1,4 +1,4 @@ | ||
| 1 | −# makefile for lua basic library | |
| 1 | +# makefile for Lua core library | |
| 2 | 2 | |
| 3 | 3 | LUA= .. |
| 4 | 4 | |
| @@ -6,9 +6,8 @@ include $(LUA)/config · 1 unmodified line | ||
| 6 | 6 | |
| 7 | 7 | OBJS= \ |
| 8 | 8 | lapi.o \ |
| 9 | − lauxlib.o \ | |
| 10 | − lbuffer.o \ | |
| 11 | − lbuiltin.o \ | |
| 9 | + lcode.o \ | |
| 10 | + ldebug.o \ | |
| 12 | 11 | ldo.o \ |
| 13 | 12 | lfunc.o \ |
| 14 | 13 | lgc.o \ |
| @@ -19,6 +18,7 @@ OBJS= \ · 4 unmodified lines | ||
| 19 | 18 | lstate.o \ |
| 20 | 19 | lstring.o \ |
| 21 | 20 | ltable.o \ |
| 21 | + ltests.o \ | |
| 22 | 22 | ltm.o \ |
| 23 | 23 | lundump.o \ |
| 24 | 24 | lvm.o \ |
| @@ -26,9 +26,8 @@ OBJS= \ · 1 unmodified line | ||
| 26 | 26 | |
| 27 | 27 | SRCS= \ |
| 28 | 28 | lapi.c \ |
| 29 | − lauxlib.c \ | |
| 30 | − lbuffer.c \ | |
| 31 | − lbuiltin.c \ | |
| 29 | + lcode.c \ | |
| 30 | + ldebug.c \ | |
| 32 | 31 | ldo.c \ |
| 33 | 32 | lfunc.c \ |
| 34 | 33 | lgc.c \ |
| @@ -39,16 +38,19 @@ SRCS= \ · 4 unmodified lines | ||
| 39 | 38 | lstate.c \ |
| 40 | 39 | lstring.c \ |
| 41 | 40 | ltable.c \ |
| 41 | + ltests.c \ | |
| 42 | 42 | ltm.c \ |
| 43 | 43 | lundump.c \ |
| 44 | 44 | lvm.c \ |
| 45 | 45 | lzio.c \ |
| 46 | 46 | lapi.h \ |
| 47 | − lbuiltin.h \ | |
| 47 | + lcode.h \ | |
| 48 | + ldebug.h \ | |
| 48 | 49 | ldo.h \ |
| 49 | 50 | lfunc.h \ |
| 50 | 51 | lgc.h \ |
| 51 | 52 | llex.h \ |
| 53 | + llimits.h \ | |
| 52 | 54 | lmem.h \ |
| 53 | 55 | lobject.h \ |
| 54 | 56 | lopcodes.h \ |
| @@ -1,15 +1,15 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lapi.c,v 1.47b 1999/06/22 20:37:23 roberto Exp $ | |
| 2 | +** $Id: lapi.c,v 1.110 2000/10/30 12:50:09 roberto Exp $ | |
| 3 | 3 | ** Lua API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | −#include <stdlib.h> | |
| 9 | 8 | #include <string.h> |
| 10 | 9 | |
| 10 | +#include "lua.h" | |
| 11 | + | |
| 11 | 12 | #include "lapi.h" |
| 12 | −#include "lauxlib.h" | |
| 13 | 13 | #include "ldo.h" |
| 14 | 14 | #include "lfunc.h" |
| 15 | 15 | #include "lgc.h" |
| @@ -19,676 +19,476 @@ · 3 unmodified lines | ||
| 19 | 19 | #include "lstring.h" |
| 20 | 20 | #include "ltable.h" |
| 21 | 21 | #include "ltm.h" |
| 22 | −#include "lua.h" | |
| 23 | −#include "luadebug.h" | |
| 24 | 22 | #include "lvm.h" |
| 25 | 23 | |
| 26 | 24 | |
| 27 | −char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n" | |
| 28 | − "$Authors: " LUA_AUTHORS " $"; | |
| 29 | − | |
| 30 | − | |
| 31 | − | |
| 32 | −TObject *luaA_Address (lua_Object o) { | |
| 33 | − return (o != LUA_NOOBJECT) ? Address(o) : NULL; | |
| 34 | −} | |
| 35 | − | |
| 36 | − | |
| 37 | −static lua_Type normalized_type (TObject *o) | |
| 38 | −{ | |
| 39 | − int t = ttype(o); | |
| 40 | − switch (t) { | |
| 41 | − case LUA_T_PMARK: | |
| 42 | − return LUA_T_PROTO; | |
| 43 | − case LUA_T_CMARK: | |
| 44 | − return LUA_T_CPROTO; | |
| 45 | − case LUA_T_CLMARK: | |
| 46 | − return LUA_T_CLOSURE; | |
| 47 | − default: | |
| 48 | − return t; | |
| 49 | − } | |
| 50 | −} | |
| 25 | +const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n" | |
| 26 | + "$Authors: " LUA_AUTHORS " $"; | |
| 51 | 27 | |
| 52 | 28 | |
| 53 | −static void set_normalized (TObject *d, TObject *s) | |
| 54 | −{ | |
| 55 | − d->value = s->value; | |
| 56 | − d->ttype = normalized_type(s); | |
| 57 | −} | |
| 58 | 29 | |
| 30 | +#define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i))) | |
| 59 | 31 | |
| 60 | −static TObject *luaA_protovalue (TObject *o) | |
| 61 | −{ | |
| 62 | − return (normalized_type(o) == LUA_T_CLOSURE) ? protovalue(o) : o; | |
| 63 | −} | |
| 32 | +#define api_incr_top(L) incr_top | |
| 64 | 33 | |
| 65 | 34 | |
| 66 | −void luaA_packresults (void) | |
| 67 | −{ | |
| 68 | − luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top); | |
| 69 | − incr_top; | |
| 70 | −} | |
| 71 | 35 | |
| 72 | 36 | |
| 73 | −int luaA_passresults (void) { | |
| 74 | − L->Cstack.base = L->Cstack.lua2C; /* position of first result */ | |
| 75 | − return L->Cstack.num; | |
| 37 | +TObject *luaA_index (lua_State *L, int index) { | |
| 38 | + return Index(L, index); | |
| 76 | 39 | } |
| 77 | 40 | |
| 78 | 41 | |
| 79 | −static void checkCparams (int nParams) | |
| 80 | −{ | |
| 81 | − if (L->stack.top-L->stack.stack < L->Cstack.base+nParams) | |
| 82 | − lua_error("API error - wrong number of arguments in C2lua stack"); | |
| 83 | −} | |
| 84 | − | |
| 85 | − | |
| 86 | −static lua_Object put_luaObject (TObject *o) { | |
| 87 | − luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base); | |
| 88 | − L->stack.stack[L->Cstack.base++] = *o; | |
| 89 | − return L->Cstack.base; /* this is +1 real position (see Ref) */ | |
| 42 | +static TObject *luaA_indexAcceptable (lua_State *L, int index) { | |
| 43 | + if (index >= 0) { | |
| 44 | + TObject *o = L->Cbase+(index-1); | |
| 45 | + if (o >= L->top) return NULL; | |
| 46 | + else return o; | |
| 47 | + } | |
| 48 | + else return L->top+index; | |
| 90 | 49 | } |
| 91 | 50 | |
| 92 | 51 | |
| 93 | −static lua_Object put_luaObjectonTop (void) { | |
| 94 | − luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base); | |
| 95 | − L->stack.stack[L->Cstack.base++] = *(--L->stack.top); | |
| 96 | − return L->Cstack.base; /* this is +1 real position (see Ref) */ | |
| 52 | +void luaA_pushobject (lua_State *L, const TObject *o) { | |
| 53 | + *L->top = *o; | |
| 54 | + incr_top; | |
| 97 | 55 | } |
| 98 | 56 | |
| 99 | − | |
| 100 | −static void top2LC (int n) { | |
| 101 | − /* Put the 'n' elements on the top as the Lua2C contents */ | |
| 102 | − L->Cstack.base = (L->stack.top-L->stack.stack); /* new base */ | |
| 103 | − L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */ | |
| 104 | − L->Cstack.num = n; /* number of results */ | |
| 57 | +LUA_API int lua_stackspace (lua_State *L) { | |
| 58 | + return (L->stack_last - L->top); | |
| 105 | 59 | } |
| 106 | 60 | |
| 107 | 61 | |
| 108 | −lua_Object lua_pop (void) { | |
| 109 | − checkCparams(1); | |
| 110 | − return put_luaObjectonTop(); | |
| 111 | −} | |
| 112 | − | |
| 113 | 62 | |
| 114 | 63 | /* |
| 115 | −** Get a parameter, returning the object handle or LUA_NOOBJECT on error. | |
| 116 | −** 'number' must be 1 to get the first parameter. | |
| 64 | +** basic stack manipulation | |
| 117 | 65 | */ |
| 118 | −lua_Object lua_lua2C (int number) | |
| 119 | −{ | |
| 120 | − if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT; | |
| 121 | − /* Ref(L->stack.stack+(L->Cstack.lua2C+number-1)) == | |
| 122 | − L->stack.stack+(L->Cstack.lua2C+number-1)-L->stack.stack+1 == */ | |
| 123 | − return L->Cstack.lua2C+number; | |
| 124 | −} | |
| 125 | 66 | |
| 126 | 67 | |
| 127 | −int lua_callfunction (lua_Object function) | |
| 128 | −{ | |
| 129 | − if (function == LUA_NOOBJECT) | |
| 130 | − return 1; | |
| 131 | − else { | |
| 132 | − luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base); | |
| 133 | − set_normalized(L->stack.stack+L->Cstack.base, Address(function)); | |
| 134 | − return luaD_protectedrun(); | |
| 135 | − } | |
| 68 | +LUA_API int lua_gettop (lua_State *L) { | |
| 69 | + return (L->top - L->Cbase); | |
| 136 | 70 | } |
| 137 | 71 | |
| 138 | 72 | |
| 139 | −lua_Object lua_gettagmethod (int tag, char *event) | |
| 140 | −{ | |
| 141 | − return put_luaObject(luaT_gettagmethod(tag, event)); | |
| 73 | +LUA_API void lua_settop (lua_State *L, int index) { | |
| 74 | + if (index >= 0) | |
| 75 | + luaD_adjusttop(L, L->Cbase, index); | |
| 76 | + else | |
| 77 | + L->top = L->top+index+1; /* index is negative */ | |
| 142 | 78 | } |
| 143 | 79 | |
| 144 | 80 | |
| 145 | −lua_Object lua_settagmethod (int tag, char *event) | |
| 146 | −{ | |
| 147 | − checkCparams(1); | |
| 148 | − luaT_settagmethod(tag, event, L->stack.top-1); | |
| 149 | − return put_luaObjectonTop(); | |
| 81 | +LUA_API void lua_remove (lua_State *L, int index) { | |
| 82 | + StkId p = luaA_index(L, index); | |
| 83 | + while (++p < L->top) *(p-1) = *p; | |
| 84 | + L->top--; | |
| 150 | 85 | } |
| 151 | 86 | |
| 152 | 87 | |
| 153 | −lua_Object lua_seterrormethod (void) { | |
| 154 | − lua_Object temp; | |
| 155 | − checkCparams(1); | |
| 156 | − temp = lua_getglobal("_ERRORMESSAGE"); | |
| 157 | − lua_setglobal("_ERRORMESSAGE"); | |
| 158 | − return temp; | |
| 88 | +LUA_API void lua_insert (lua_State *L, int index) { | |
| 89 | + StkId p = luaA_index(L, index); | |
| 90 | + StkId q; | |
| 91 | + for (q = L->top; q>p; q--) | |
| 92 | + *q = *(q-1); | |
| 93 | + *p = *L->top; | |
| 159 | 94 | } |
| 160 | 95 | |
| 161 | 96 | |
| 162 | −lua_Object lua_gettable (void) | |
| 163 | −{ | |
| 164 | − checkCparams(2); | |
| 165 | − luaV_gettable(); | |
| 166 | − return put_luaObjectonTop(); | |
| 97 | +LUA_API void lua_pushvalue (lua_State *L, int index) { | |
| 98 | + *L->top = *luaA_index(L, index); | |
| 99 | + api_incr_top(L); | |
| 167 | 100 | } |
| 168 | 101 | |
| 169 | 102 | |
| 170 | −lua_Object lua_rawgettable (void) { | |
| 171 | − checkCparams(2); | |
| 172 | − if (ttype(L->stack.top-2) != LUA_T_ARRAY) | |
| 173 | − lua_error("indexed expression not a table in rawgettable"); | |
| 174 | − *(L->stack.top-2) = *luaH_get(avalue(L->stack.top-2), L->stack.top-1); | |
| 175 | − --L->stack.top; | |
| 176 | − return put_luaObjectonTop(); | |
| 177 | −} | |
| 178 | − | |
| 179 | 103 | |
| 180 | −void lua_settable (void) { | |
| 181 | − checkCparams(3); | |
| 182 | − luaD_checkstack(3); /* may need that to call T.M. */ | |
| 183 | − luaV_settable(L->stack.top-3); | |
| 184 | − L->stack.top -= 2; /* pop table and index */ | |
| 185 | −} | |
| 104 | +/* | |
| 105 | +** access functions (stack -> C) | |
| 106 | +*/ | |
| 186 | 107 | |
| 187 | 108 | |
| 188 | −void lua_rawsettable (void) { | |
| 189 | − checkCparams(3); | |
| 190 | − luaV_rawsettable(L->stack.top-3); | |
| 109 | +LUA_API int lua_type (lua_State *L, int index) { | |
| 110 | + StkId o = luaA_indexAcceptable(L, index); | |
| 111 | + return (o == NULL) ? LUA_TNONE : ttype(o); | |
| 191 | 112 | } |
| 192 | 113 | |
| 193 | − | |
| 194 | −lua_Object lua_createtable (void) | |
| 195 | −{ | |
| 196 | − TObject o; | |
| 197 | − luaC_checkGC(); | |
| 198 | − avalue(&o) = luaH_new(0); | |
| 199 | − ttype(&o) = LUA_T_ARRAY; | |
| 200 | − return put_luaObject(&o); | |
| 114 | +LUA_API const char *lua_typename (lua_State *L, int t) { | |
| 115 | + UNUSED(L); | |
| 116 | + return (t == LUA_TNONE) ? "no value" : luaO_typenames[t]; | |
| 201 | 117 | } |
| 202 | 118 | |
| 203 | 119 | |
| 204 | −lua_Object lua_getglobal (char *name) | |
| 205 | −{ | |
| 206 | − luaD_checkstack(2); /* may need that to call T.M. */ | |
| 207 | − luaV_getglobal(luaS_new(name)); | |
| 208 | − return put_luaObjectonTop(); | |
| 120 | +LUA_API int lua_iscfunction (lua_State *L, int index) { | |
| 121 | + StkId o = luaA_indexAcceptable(L, index); | |
| 122 | + return (o == NULL) ? 0 : iscfunction(o); | |
| 209 | 123 | } |
| 210 | 124 | |
| 125 | +LUA_API int lua_isnumber (lua_State *L, int index) { | |
| 126 | + TObject *o = luaA_indexAcceptable(L, index); | |
| 127 | + return (o == NULL) ? 0 : (tonumber(o) == 0); | |
| 128 | +} | |
| 211 | 129 | |
| 212 | −lua_Object lua_rawgetglobal (char *name) | |
| 213 | −{ | |
| 214 | − TaggedString *ts = luaS_new(name); | |
| 215 | − return put_luaObject(&ts->u.s.globalval); | |
| 130 | +LUA_API int lua_isstring (lua_State *L, int index) { | |
| 131 | + int t = lua_type(L, index); | |
| 132 | + return (t == LUA_TSTRING || t == LUA_TNUMBER); | |
| 216 | 133 | } |
| 217 | 134 | |
| 218 | 135 | |
| 219 | −void lua_setglobal (char *name) | |
| 220 | −{ | |
| 221 | − checkCparams(1); | |
| 222 | − luaD_checkstack(2); /* may need that to call T.M. */ | |
| 223 | − luaV_setglobal(luaS_new(name)); | |
| 136 | +LUA_API int lua_tag (lua_State *L, int index) { | |
| 137 | + StkId o = luaA_indexAcceptable(L, index); | |
| 138 | + return (o == NULL) ? LUA_NOTAG : luaT_tag(o); | |
| 224 | 139 | } |
| 225 | 140 | |
| 141 | +LUA_API int lua_equal (lua_State *L, int index1, int index2) { | |
| 142 | + StkId o1 = luaA_indexAcceptable(L, index1); | |
| 143 | + StkId o2 = luaA_indexAcceptable(L, index2); | |
| 144 | + if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */ | |
| 145 | + else return luaO_equalObj(o1, o2); | |
| 146 | +} | |
| 226 | 147 | |
| 227 | −void lua_rawsetglobal (char *name) | |
| 228 | −{ | |
| 229 | − TaggedString *ts = luaS_new(name); | |
| 230 | − checkCparams(1); | |
| 231 | − luaS_rawsetglobal(ts, --L->stack.top); | |
| 148 | +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { | |
| 149 | + StkId o1 = luaA_indexAcceptable(L, index1); | |
| 150 | + StkId o2 = luaA_indexAcceptable(L, index2); | |
| 151 | + if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */ | |
| 152 | + else return luaV_lessthan(L, o1, o2, L->top); | |
| 232 | 153 | } |
| 233 | 154 | |
| 234 | 155 | |
| 235 | 156 | |
| 236 | −int lua_isnil (lua_Object o) | |
| 237 | −{ | |
| 238 | − return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_NIL); | |
| 157 | +LUA_API double lua_tonumber (lua_State *L, int index) { | |
| 158 | + StkId o = luaA_indexAcceptable(L, index); | |
| 159 | + return (o == NULL || tonumber(o)) ? 0 : nvalue(o); | |
| 239 | 160 | } |
| 240 | 161 | |
| 241 | −int lua_istable (lua_Object o) | |
| 242 | −{ | |
| 243 | − return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_ARRAY); | |
| 162 | +LUA_API const char *lua_tostring (lua_State *L, int index) { | |
| 163 | + StkId o = luaA_indexAcceptable(L, index); | |
| 164 | + return (o == NULL || tostring(L, o)) ? NULL : svalue(o); | |
| 244 | 165 | } |
| 245 | 166 | |
| 246 | −int lua_isuserdata (lua_Object o) | |
| 247 | −{ | |
| 248 | − return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_USERDATA); | |
| 167 | +LUA_API size_t lua_strlen (lua_State *L, int index) { | |
| 168 | + StkId o = luaA_indexAcceptable(L, index); | |
| 169 | + return (o == NULL || tostring(L, o)) ? 0 : tsvalue(o)->len; | |
| 249 | 170 | } |
| 250 | 171 | |
| 251 | −int lua_iscfunction (lua_Object o) | |
| 252 | −{ | |
| 253 | − return (lua_tag(o) == LUA_T_CPROTO); | |
| 172 | +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) { | |
| 173 | + StkId o = luaA_indexAcceptable(L, index); | |
| 174 | + return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->f.c; | |
| 254 | 175 | } |
| 255 | 176 | |
| 256 | −int lua_isnumber (lua_Object o) | |
| 257 | −{ | |
| 258 | − return (o!= LUA_NOOBJECT) && (tonumber(Address(o)) == 0); | |
| 177 | +LUA_API void *lua_touserdata (lua_State *L, int index) { | |
| 178 | + StkId o = luaA_indexAcceptable(L, index); | |
| 179 | + return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL : | |
| 180 | + tsvalue(o)->u.d.value; | |
| 259 | 181 | } |
| 260 | 182 | |
| 261 | −int lua_isstring (lua_Object o) | |
| 262 | −{ | |
| 263 | − int t = lua_tag(o); | |
| 264 | − return (t == LUA_T_STRING) || (t == LUA_T_NUMBER); | |
| 183 | +LUA_API const void *lua_topointer (lua_State *L, int index) { | |
| 184 | + StkId o = luaA_indexAcceptable(L, index); | |
| 185 | + if (o == NULL) return NULL; | |
| 186 | + switch (ttype(o)) { | |
| 187 | + case LUA_TTABLE: | |
| 188 | + return hvalue(o); | |
| 189 | + case LUA_TFUNCTION: | |
| 190 | + return clvalue(o); | |
| 191 | + default: return NULL; | |
| 192 | + } | |
| 265 | 193 | } |
| 266 | 194 | |
| 267 | −int lua_isfunction (lua_Object o) | |
| 268 | −{ | |
| 269 | − int t = lua_tag(o); | |
| 270 | − return (t == LUA_T_PROTO) || (t == LUA_T_CPROTO); | |
| 271 | −} | |
| 272 | 195 | |
| 273 | 196 | |
| 274 | −double lua_getnumber (lua_Object object) | |
| 275 | −{ | |
| 276 | − if (object == LUA_NOOBJECT) return 0.0; | |
| 277 | − if (tonumber(Address(object))) return 0.0; | |
| 278 | − else return (nvalue(Address(object))); | |
| 279 | −} | |
| 197 | +/* | |
| 198 | +** push functions (C -> stack) | |
| 199 | +*/ | |
| 280 | 200 | |
| 281 | −char *lua_getstring (lua_Object object) | |
| 282 | −{ | |
| 283 | − luaC_checkGC(); /* "tostring" may create a new string */ | |
| 284 | − if (object == LUA_NOOBJECT || tostring(Address(object))) | |
| 285 | − return NULL; | |
| 286 | − else return (svalue(Address(object))); | |
| 287 | −} | |
| 288 | 201 | |
| 289 | −long lua_strlen (lua_Object object) | |
| 290 | −{ | |
| 291 | − luaC_checkGC(); /* "tostring" may create a new string */ | |
| 292 | − if (object == LUA_NOOBJECT || tostring(Address(object))) | |
| 293 | − return 0L; | |
| 294 | − else return (tsvalue(Address(object))->u.s.len); | |
| 202 | +LUA_API void lua_pushnil (lua_State *L) { | |
| 203 | + ttype(L->top) = LUA_TNIL; | |
| 204 | + api_incr_top(L); | |
| 295 | 205 | } |
| 296 | 206 | |
| 297 | −void *lua_getuserdata (lua_Object object) | |
| 298 | −{ | |
| 299 | − if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA) | |
| 300 | − return NULL; | |
| 301 | − else return tsvalue(Address(object))->u.d.v; | |
| 302 | −} | |
| 303 | 207 | |
| 304 | −lua_CFunction lua_getcfunction (lua_Object object) | |
| 305 | −{ | |
| 306 | − if (!lua_iscfunction(object)) | |
| 307 | − return NULL; | |
| 308 | − else return fvalue(luaA_protovalue(Address(object))); | |
| 208 | +LUA_API void lua_pushnumber (lua_State *L, double n) { | |
| 209 | + nvalue(L->top) = n; | |
| 210 | + ttype(L->top) = LUA_TNUMBER; | |
| 211 | + api_incr_top(L); | |
| 309 | 212 | } |
| 310 | 213 | |
| 311 | 214 | |
| 312 | −void lua_pushnil (void) | |
| 313 | −{ | |
| 314 | − ttype(L->stack.top) = LUA_T_NIL; | |
| 315 | − incr_top; | |
| 215 | +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { | |
| 216 | + tsvalue(L->top) = luaS_newlstr(L, s, len); | |
| 217 | + ttype(L->top) = LUA_TSTRING; | |
| 218 | + api_incr_top(L); | |
| 316 | 219 | } |
| 317 | 220 | |
| 318 | −void lua_pushnumber (double n) | |
| 319 | −{ | |
| 320 | − ttype(L->stack.top) = LUA_T_NUMBER; | |
| 321 | − nvalue(L->stack.top) = n; | |
| 322 | − incr_top; | |
| 323 | −} | |
| 324 | 221 | |
| 325 | −void lua_pushlstring (char *s, long len) | |
| 326 | −{ | |
| 327 | − tsvalue(L->stack.top) = luaS_newlstr(s, len); | |
| 328 | − ttype(L->stack.top) = LUA_T_STRING; | |
| 329 | − incr_top; | |
| 330 | − luaC_checkGC(); | |
| 331 | −} | |
| 332 | − | |
| 333 | −void lua_pushstring (char *s) | |
| 334 | −{ | |
| 222 | +LUA_API void lua_pushstring (lua_State *L, const char *s) { | |
| 335 | 223 | if (s == NULL) |
| 336 | − lua_pushnil(); | |
| 224 | + lua_pushnil(L); | |
| 337 | 225 | else |
| 338 | − lua_pushlstring(s, strlen(s)); | |
| 226 | + lua_pushlstring(L, s, strlen(s)); | |
| 339 | 227 | } |
| 340 | 228 | |
| 341 | −void lua_pushcclosure (lua_CFunction fn, int n) | |
| 342 | −{ | |
| 343 | − if (fn == NULL) | |
| 344 | − lua_error("API error - attempt to push a NULL Cfunction"); | |
| 345 | − checkCparams(n); | |
| 346 | − ttype(L->stack.top) = LUA_T_CPROTO; | |
| 347 | − fvalue(L->stack.top) = fn; | |
| 348 | − incr_top; | |
| 349 | − luaV_closure(n); | |
| 350 | − luaC_checkGC(); | |
| 351 | −} | |
| 352 | 229 | |
| 353 | −void lua_pushusertag (void *u, int tag) | |
| 354 | −{ | |
| 355 | − if (tag < 0 && tag != LUA_ANYTAG) | |
| 356 | − luaT_realtag(tag); /* error if tag is not valid */ | |
| 357 | − tsvalue(L->stack.top) = luaS_createudata(u, tag); | |
| 358 | − ttype(L->stack.top) = LUA_T_USERDATA; | |
| 359 | − incr_top; | |
| 360 | − luaC_checkGC(); | |
| 230 | +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | |
| 231 | + luaV_Cclosure(L, fn, n); | |
| 361 | 232 | } |
| 362 | 233 | |
| 363 | −void luaA_pushobject (TObject *o) | |
| 364 | −{ | |
| 365 | − *L->stack.top = *o; | |
| 366 | − incr_top; | |
| 367 | −} | |
| 368 | 234 | |
| 369 | −void lua_pushobject (lua_Object o) { | |
| 370 | − if (o == LUA_NOOBJECT) | |
| 371 | − lua_error("API error - attempt to push a NOOBJECT"); | |
| 372 | − set_normalized(L->stack.top, Address(o)); | |
| 373 | − incr_top; | |
| 235 | +LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) { | |
| 236 | + /* ORDER LUA_T */ | |
| 237 | + if (!(tag == LUA_ANYTAG || tag == LUA_TUSERDATA || validtag(tag))) | |
| 238 | + luaO_verror(L, "invalid tag for a userdata (%d)", tag); | |
| 239 | + tsvalue(L->top) = luaS_createudata(L, u, tag); | |
| 240 | + ttype(L->top) = LUA_TUSERDATA; | |
| 241 | + api_incr_top(L); | |
| 374 | 242 | } |
| 375 | 243 | |
| 376 | 244 | |
| 377 | −int lua_tag (lua_Object lo) | |
| 378 | −{ | |
| 379 | − if (lo == LUA_NOOBJECT) | |
| 380 | − return LUA_T_NIL; | |
| 381 | − else { | |
| 382 | − TObject *o = Address(lo); | |
| 383 | − int t; | |
| 384 | − switch (t = ttype(o)) { | |
| 385 | − case LUA_T_USERDATA: | |
| 386 | − return o->value.ts->u.d.tag; | |
| 387 | − case LUA_T_ARRAY: | |
| 388 | − return o->value.a->htag; | |
| 389 | − case LUA_T_PMARK: | |
| 390 | − return LUA_T_PROTO; | |
| 391 | − case LUA_T_CMARK: | |
| 392 | − return LUA_T_CPROTO; | |
| 393 | − case LUA_T_CLOSURE: case LUA_T_CLMARK: | |
| 394 | − return o->value.cl->consts[0].ttype; | |
| 395 | −#ifdef DEBUG | |
| 396 | − case LUA_T_LINE: | |
| 397 | − LUA_INTERNALERROR("invalid type"); | |
| 398 | −#endif | |
| 399 | − default: | |
| 400 | − return t; | |
| 401 | − } | |
| 402 | − } | |
| 403 | −} | |
| 404 | − | |
| 405 | 245 | |
| 406 | −void lua_settag (int tag) | |
| 407 | −{ | |
| 408 | − checkCparams(1); | |
| 409 | − luaT_realtag(tag); | |
| 410 | − switch (ttype(L->stack.top-1)) { | |
| 411 | − case LUA_T_ARRAY: | |
| 412 | − (L->stack.top-1)->value.a->htag = tag; | |
| 413 | − break; | |
| 414 | − case LUA_T_USERDATA: | |
| 415 | − (L->stack.top-1)->value.ts->u.d.tag = tag; | |
| 416 | − break; | |
| 417 | − default: | |
| 418 | − luaL_verror("cannot change the tag of a %.20s", | |
| 419 | − luaO_typename(L->stack.top-1)); | |
| 420 | − } | |
| 421 | − L->stack.top--; | |
| 422 | −} | |
| 246 | +/* | |
| 247 | +** get functions (Lua -> stack) | |
| 248 | +*/ | |
| 423 | 249 | |
| 424 | 250 | |
| 425 | −TaggedString *luaA_nextvar (TaggedString *g) { | |
| 426 | − if (g == NULL) | |
| 427 | − g = (TaggedString *)L->rootglobal.next; /* first variable */ | |
| 428 | − else { | |
| 429 | − /* check whether name is in global var list */ | |
| 430 | − luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected"); | |
| 431 | − g = (TaggedString *)g->head.next; /* get next */ | |
| 432 | − } | |
| 433 | − while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */ | |
| 434 | − g = (TaggedString *)g->head.next; | |
| 435 | − if (g) { | |
| 436 | − ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g; | |
| 437 | − incr_top; | |
| 438 | − luaA_pushobject(&g->u.s.globalval); | |
| 439 | − } | |
| 440 | − return g; | |
| 251 | +LUA_API void lua_getglobal (lua_State *L, const char *name) { | |
| 252 | + StkId top = L->top; | |
| 253 | + *top = *luaV_getglobal(L, luaS_new(L, name)); | |
| 254 | + L->top = top; | |
| 255 | + api_incr_top(L); | |
| 441 | 256 | } |
| 442 | 257 | |
| 443 | 258 | |
| 444 | −char *lua_nextvar (char *varname) { | |
| 445 | − TaggedString *g = (varname == NULL) ? NULL : luaS_new(varname); | |
| 446 | − g = luaA_nextvar(g); | |
| 447 | − if (g) { | |
| 448 | − top2LC(2); | |
| 449 | − return g->str; | |
| 450 | − } | |
| 451 | − else { | |
| 452 | − top2LC(0); | |
| 453 | − return NULL; | |
| 454 | − } | |
| 259 | +LUA_API void lua_gettable (lua_State *L, int index) { | |
| 260 | + StkId t = Index(L, index); | |
| 261 | + StkId top = L->top; | |
| 262 | + *(top-1) = *luaV_gettable(L, t); | |
| 263 | + L->top = top; /* tag method may change top */ | |
| 455 | 264 | } |
| 456 | 265 | |
| 457 | 266 | |
| 458 | −int luaA_next (Hash *t, int i) { | |
| 459 | − int tsize = nhash(t); | |
| 460 | − for (; i<tsize; i++) { | |
| 461 | − Node *n = node(t, i); | |
| 462 | − if (ttype(val(n)) != LUA_T_NIL) { | |
| 463 | − luaA_pushobject(ref(n)); | |
| 464 | − luaA_pushobject(val(n)); | |
| 465 | − return i+1; /* index to be used next time */ | |
| 466 | − } | |
| 467 | − } | |
| 468 | − return 0; /* no more elements */ | |
| 267 | +LUA_API void lua_rawget (lua_State *L, int index) { | |
| 268 | + StkId t = Index(L, index); | |
| 269 | + LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected"); | |
| 270 | + *(L->top - 1) = *luaH_get(L, hvalue(t), L->top - 1); | |
| 469 | 271 | } |
| 470 | 272 | |
| 471 | 273 | |
| 472 | −int lua_next (lua_Object o, int i) { | |
| 473 | − TObject *t = Address(o); | |
| 474 | − if (ttype(t) != LUA_T_ARRAY) | |
| 475 | − lua_error("API error - object is not a table in `lua_next'"); | |
| 476 | − i = luaA_next(avalue(t), i); | |
| 477 | − top2LC((i==0) ? 0 : 2); | |
| 478 | − return i; | |
| 274 | +LUA_API void lua_rawgeti (lua_State *L, int index, int n) { | |
| 275 | + StkId o = Index(L, index); | |
| 276 | + LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected"); | |
| 277 | + *L->top = *luaH_getnum(hvalue(o), n); | |
| 278 | + api_incr_top(L); | |
| 479 | 279 | } |
| 480 | 280 | |
| 481 | 281 | |
| 482 | − | |
| 483 | −/* | |
| 484 | −** {====================================================== | |
| 485 | −** To manipulate some state information | |
| 486 | −** ======================================================= | |
| 487 | −*/ | |
| 488 | − | |
| 489 | −lua_State *lua_setstate (lua_State *st) { | |
| 490 | − lua_State *old = lua_state; | |
| 491 | − lua_state = st; | |
| 492 | − return old; | |
| 282 | +LUA_API void lua_getglobals (lua_State *L) { | |
| 283 | + hvalue(L->top) = L->gt; | |
| 284 | + ttype(L->top) = LUA_TTABLE; | |
| 285 | + api_incr_top(L); | |
| 493 | 286 | } |
| 494 | 287 | |
| 495 | −lua_LHFunction lua_setlinehook (lua_LHFunction func) { | |
| 496 | − lua_LHFunction old = L->linehook; | |
| 497 | − L->linehook = func; | |
| 498 | − return old; | |
| 499 | −} | |
| 500 | 288 | |
| 501 | −lua_CHFunction lua_setcallhook (lua_CHFunction func) { | |
| 502 | − lua_CHFunction old = L->callhook; | |
| 503 | − L->callhook = func; | |
| 504 | − return old; | |
| 289 | +LUA_API int lua_getref (lua_State *L, int ref) { | |
| 290 | + if (ref == LUA_REFNIL) | |
| 291 | + ttype(L->top) = LUA_TNIL; | |
| 292 | + else if (0 <= ref && ref < L->refSize && | |
| 293 | + (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD)) | |
| 294 | + *L->top = L->refArray[ref].o; | |
| 295 | + else | |
| 296 | + return 0; | |
| 297 | + api_incr_top(L); | |
| 298 | + return 1; | |
| 505 | 299 | } |
| 506 | 300 | |
| 507 | −int lua_setdebug (int debug) { | |
| 508 | − int old = L->debug; | |
| 509 | − L->debug = debug; | |
| 510 | − return old; | |
| 301 | + | |
| 302 | +LUA_API void lua_newtable (lua_State *L) { | |
| 303 | + hvalue(L->top) = luaH_new(L, 0); | |
| 304 | + ttype(L->top) = LUA_TTABLE; | |
| 305 | + api_incr_top(L); | |
| 511 | 306 | } |
| 512 | 307 | |
| 513 | −/* }====================================================== */ | |
| 514 | 308 | |
| 515 | 309 | |
| 516 | 310 | /* |
| 517 | −** {====================================================== | |
| 518 | −** Debug interface | |
| 519 | −** ======================================================= | |
| 311 | +** set functions (stack -> Lua) | |
| 520 | 312 | */ |
| 521 | 313 | |
| 522 | 314 | |
| 523 | −lua_Function lua_stackedfunction (int level) | |
| 524 | −{ | |
| 525 | − StkId i; | |
| 526 | − for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) { | |
| 527 | − int t = L->stack.stack[i].ttype; | |
| 528 | − if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK) | |
| 529 | − if (level-- == 0) | |
| 530 | − return Ref(L->stack.stack+i); | |
| 531 | − } | |
| 532 | − return LUA_NOOBJECT; | |
| 315 | +LUA_API void lua_setglobal (lua_State *L, const char *name) { | |
| 316 | + StkId top = L->top; | |
| 317 | + luaV_setglobal(L, luaS_new(L, name)); | |
| 318 | + L->top = top-1; /* remove element from the top */ | |
| 533 | 319 | } |
| 534 | 320 | |
| 535 | 321 | |
| 536 | −int lua_nups (lua_Function func) { | |
| 537 | − TObject *o = luaA_Address(func); | |
| 538 | − return (!o || normalized_type(o) != LUA_T_CLOSURE) ? 0 : o->value.cl->nelems; | |
| 322 | +LUA_API void lua_settable (lua_State *L, int index) { | |
| 323 | + StkId t = Index(L, index); | |
| 324 | + StkId top = L->top; | |
| 325 | + luaV_settable(L, t, top-2); | |
| 326 | + L->top = top-2; /* pop index and value */ | |
| 539 | 327 | } |
| 540 | 328 | |
| 541 | 329 | |
| 542 | −int lua_currentline (lua_Function func) | |
| 543 | −{ | |
| 544 | − TObject *f = Address(func); | |
| 545 | − return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ? | |
| 546 | − (f+1)->value.i : -1; | |
| 330 | +LUA_API void lua_rawset (lua_State *L, int index) { | |
| 331 | + StkId t = Index(L, index); | |
| 332 | + LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected"); | |
| 333 | + *luaH_set(L, hvalue(t), L->top-2) = *(L->top-1); | |
| 334 | + L->top -= 2; | |
| 547 | 335 | } |
| 548 | 336 | |
| 549 | 337 | |
| 550 | −lua_Object lua_getlocal (lua_Function func, int local_number, char **name) { | |
| 551 | − /* check whether func is a Lua function */ | |
| 552 | − if (lua_tag(func) != LUA_T_PROTO) | |
| 553 | − return LUA_NOOBJECT; | |
| 554 | − else { | |
| 555 | − TObject *f = Address(func); | |
| 556 | − TProtoFunc *fp = luaA_protovalue(f)->value.tf; | |
| 557 | − *name = luaF_getlocalname(fp, local_number, lua_currentline(func)); | |
| 558 | − if (*name) { | |
| 559 | − /* if "*name", there must be a LUA_T_LINE */ | |
| 560 | − /* therefore, f+2 points to function base */ | |
| 561 | − return put_luaObject((f+2)+(local_number-1)); | |
| 562 | − } | |
| 563 | − else | |
| 564 | − return LUA_NOOBJECT; | |
| 565 | − } | |
| 338 | +LUA_API void lua_rawseti (lua_State *L, int index, int n) { | |
| 339 | + StkId o = Index(L, index); | |
| 340 | + LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected"); | |
| 341 | + *luaH_setint(L, hvalue(o), n) = *(L->top-1); | |
| 342 | + L->top--; | |
| 566 | 343 | } |
| 567 | 344 | |
| 568 | 345 | |
| 569 | −int lua_setlocal (lua_Function func, int local_number) | |
| 570 | −{ | |
| 571 | − /* check whether func is a Lua function */ | |
| 572 | − if (lua_tag(func) != LUA_T_PROTO) | |
| 573 | − return 0; | |
| 574 | − else { | |
| 575 | − TObject *f = Address(func); | |
| 576 | − TProtoFunc *fp = luaA_protovalue(f)->value.tf; | |
| 577 | − char *name = luaF_getlocalname(fp, local_number, lua_currentline(func)); | |
| 578 | − checkCparams(1); | |
| 579 | − --L->stack.top; | |
| 580 | − if (name) { | |
| 581 | − /* if "name", there must be a LUA_T_LINE */ | |
| 582 | − /* therefore, f+2 points to function base */ | |
| 583 | − *((f+2)+(local_number-1)) = *L->stack.top; | |
| 584 | − return 1; | |
| 585 | − } | |
| 586 | − else | |
| 587 | − return 0; | |
| 588 | − } | |
| 346 | +LUA_API void lua_setglobals (lua_State *L) { | |
| 347 | + StkId newtable = --L->top; | |
| 348 | + LUA_ASSERT(ttype(newtable) == LUA_TTABLE, "table expected"); | |
| 349 | + L->gt = hvalue(newtable); | |
| 589 | 350 | } |
| 590 | 351 | |
| 591 | 352 | |
| 592 | −void lua_funcinfo (lua_Object func, char **source, int *linedefined) { | |
| 593 | − if (!lua_isfunction(func)) | |
| 594 | − lua_error("API error - `funcinfo' called with a non-function value"); | |
| 353 | +LUA_API int lua_ref (lua_State *L, int lock) { | |
| 354 | + int ref; | |
| 355 | + if (ttype(L->top-1) == LUA_TNIL) | |
| 356 | + ref = LUA_REFNIL; | |
| 595 | 357 | else { |
| 596 | − TObject *f = luaA_protovalue(Address(func)); | |
| 597 | − if (normalized_type(f) == LUA_T_PROTO) { | |
| 598 | − *source = tfvalue(f)->source->str; | |
| 599 | − *linedefined = tfvalue(f)->lineDefined; | |
| 358 | + if (L->refFree != NONEXT) { /* is there a free place? */ | |
| 359 | + ref = L->refFree; | |
| 360 | + L->refFree = L->refArray[ref].st; | |
| 600 | 361 | } |
| 601 | − else { | |
| 602 | − *source = "(C)"; | |
| 603 | − *linedefined = -1; | |
| 362 | + else { /* no more free places */ | |
| 363 | + luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref, | |
| 364 | + "reference table overflow", MAX_INT); | |
| 365 | + L->nblocks += sizeof(struct Ref); | |
| 366 | + ref = L->refSize++; | |
| 604 | 367 | } |
| 368 | + L->refArray[ref].o = *(L->top-1); | |
| 369 | + L->refArray[ref].st = lock ? LOCK : HOLD; | |
| 605 | 370 | } |
| 371 | + L->top--; | |
| 372 | + return ref; | |
| 606 | 373 | } |
| 607 | 374 | |
| 608 | 375 | |
| 609 | −static int checkfunc (TObject *o) | |
| 610 | −{ | |
| 611 | − return luaO_equalObj(o, L->stack.top); | |
| 612 | −} | |
| 613 | − | |
| 376 | +/* | |
| 377 | +** "do" functions (run Lua code) | |
| 378 | +** (most of them are in ldo.c) | |
| 379 | +*/ | |
| 614 | 380 | |
| 615 | −char *lua_getobjname (lua_Object o, char **name) | |
| 616 | −{ /* try to find a name for given function */ | |
| 617 | − set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */ | |
| 618 | − if ((*name = luaS_travsymbol(checkfunc)) != NULL) | |
| 619 | − return "global"; | |
| 620 | − else if ((*name = luaT_travtagmethods(checkfunc)) != NULL) | |
| 621 | − return "tag-method"; | |
| 622 | − else return ""; | |
| 381 | +LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) { | |
| 382 | + luaD_call(L, L->top-(nargs+1), nresults); | |
| 623 | 383 | } |
| 624 | 384 | |
| 625 | −/* }====================================================== */ | |
| 626 | − | |
| 627 | 385 | |
| 628 | 386 | /* |
| 629 | −** {====================================================== | |
| 630 | −** BLOCK mechanism | |
| 631 | −** ======================================================= | |
| 387 | +** Garbage-collection functions | |
| 632 | 388 | */ |
| 633 | 389 | |
| 390 | +/* GC values are expressed in Kbytes: #bytes/2^10 */ | |
| 391 | +#define GCscale(x) ((int)((x)>>10)) | |
| 392 | +#define GCunscale(x) ((unsigned long)(x)<<10) | |
| 634 | 393 | |
| 635 | −#ifndef MAX_C_BLOCKS | |
| 636 | −#define MAX_C_BLOCKS 1000 /* arbitrary limit */ | |
| 637 | −#endif | |
| 638 | − | |
| 394 | +LUA_API int lua_getgcthreshold (lua_State *L) { | |
| 395 | + return GCscale(L->GCthreshold); | |
| 396 | +} | |
| 639 | 397 | |
| 640 | −void lua_beginblock (void) { | |
| 641 | − luaM_growvector(L->Cblocks, L->numCblocks, 1, struct C_Lua_Stack, | |
| 642 | − "too many nested blocks", MAX_C_BLOCKS); | |
| 643 | − L->Cblocks[L->numCblocks] = L->Cstack; | |
| 644 | − L->numCblocks++; | |
| 398 | +LUA_API int lua_getgccount (lua_State *L) { | |
| 399 | + return GCscale(L->nblocks); | |
| 645 | 400 | } |
| 646 | 401 | |
| 647 | −void lua_endblock (void) { | |
| 648 | − --L->numCblocks; | |
| 649 | − L->Cstack = L->Cblocks[L->numCblocks]; | |
| 650 | − luaD_adjusttop(L->Cstack.base); | |
| 402 | +LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) { | |
| 403 | + if (newthreshold > GCscale(ULONG_MAX)) | |
| 404 | + L->GCthreshold = ULONG_MAX; | |
| 405 | + else | |
| 406 | + L->GCthreshold = GCunscale(newthreshold); | |
| 407 | + luaC_checkGC(L); | |
| 651 | 408 | } |
| 652 | 409 | |
| 653 | 410 | |
| 411 | +/* | |
| 412 | +** miscellaneous functions | |
| 413 | +*/ | |
| 654 | 414 | |
| 655 | −int lua_ref (int lock) { | |
| 656 | − int ref; | |
| 657 | − checkCparams(1); | |
| 658 | − ref = luaC_ref(L->stack.top-1, lock); | |
| 659 | − L->stack.top--; | |
| 660 | − return ref; | |
| 415 | +LUA_API void lua_settag (lua_State *L, int tag) { | |
| 416 | + luaT_realtag(L, tag); | |
| 417 | + switch (ttype(L->top-1)) { | |
| 418 | + case LUA_TTABLE: | |
| 419 | + hvalue(L->top-1)->htag = tag; | |
| 420 | + break; | |
| 421 | + case LUA_TUSERDATA: | |
| 422 | + tsvalue(L->top-1)->u.d.tag = tag; | |
| 423 | + break; | |
| 424 | + default: | |
| 425 | + luaO_verror(L, "cannot change the tag of a %.20s", | |
| 426 | + luaO_typename(L->top-1)); | |
| 427 | + } | |
| 661 | 428 | } |
| 662 | 429 | |
| 663 | 430 | |
| 664 | − | |
| 665 | −lua_Object lua_getref (int ref) { | |
| 666 | − TObject *o = luaC_getref(ref); | |
| 667 | − return (o ? put_luaObject(o) : LUA_NOOBJECT); | |
| 431 | +LUA_API void lua_unref (lua_State *L, int ref) { | |
| 432 | + if (ref >= 0) { | |
| 433 | + LUA_ASSERT(ref < L->refSize && L->refArray[ref].st < 0, "invalid ref"); | |
| 434 | + L->refArray[ref].st = L->refFree; | |
| 435 | + L->refFree = ref; | |
| 436 | + } | |
| 668 | 437 | } |
| 669 | 438 | |
| 670 | −/* }====================================================== */ | |
| 671 | 439 | |
| 440 | +LUA_API int lua_next (lua_State *L, int index) { | |
| 441 | + StkId t = luaA_index(L, index); | |
| 442 | + Node *n; | |
| 443 | + LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected"); | |
| 444 | + n = luaH_next(L, hvalue(t), luaA_index(L, -1)); | |
| 445 | + if (n) { | |
| 446 | + *(L->top-1) = *key(n); | |
| 447 | + *L->top = *val(n); | |
| 448 | + api_incr_top(L); | |
| 449 | + return 1; | |
| 450 | + } | |
| 451 | + else { /* no more elements */ | |
| 452 | + L->top -= 1; /* remove key */ | |
| 453 | + return 0; | |
| 454 | + } | |
| 455 | +} | |
| 672 | 456 | |
| 673 | 457 | |
| 674 | −#ifdef LUA_COMPAT2_5 | |
| 675 | −/* | |
| 676 | −** API: set a function as a fallback | |
| 677 | −*/ | |
| 458 | +LUA_API int lua_getn (lua_State *L, int index) { | |
| 459 | + Hash *h = hvalue(luaA_index(L, index)); | |
| 460 | + const TObject *value = luaH_getstr(h, luaS_new(L, "n")); /* value = h.n */ | |
| 461 | + if (ttype(value) == LUA_TNUMBER) | |
| 462 | + return (int)nvalue(value); | |
| 463 | + else { | |
| 464 | + Number max = 0; | |
| 465 | + int i = h->size; | |
| 466 | + Node *n = h->node; | |
| 467 | + while (i--) { | |
| 468 | + if (ttype(key(n)) == LUA_TNUMBER && | |
| 469 | + ttype(val(n)) != LUA_TNIL && | |
| 470 | + nvalue(key(n)) > max) | |
| 471 | + max = nvalue(key(n)); | |
| 472 | + n++; | |
| 473 | + } | |
| 474 | + return (int)max; | |
| 475 | + } | |
| 476 | +} | |
| 477 | + | |
| 678 | 478 | |
| 679 | −static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults) { | |
| 680 | − luaD_openstack(nParams); | |
| 681 | − (L->stack.top-nParams)->ttype = LUA_T_CPROTO; | |
| 682 | − (L->stack.top-nParams)->value.f = f; | |
| 683 | − luaD_calln(nParams, nResults); | |
| 479 | +LUA_API void lua_concat (lua_State *L, int n) { | |
| 480 | + StkId top = L->top; | |
| 481 | + luaV_strconc(L, n, top); | |
| 482 | + L->top = top-(n-1); | |
| 483 | + luaC_checkGC(L); | |
| 684 | 484 | } |
| 685 | 485 | |
| 686 | 486 | |
| 687 | −lua_Object lua_setfallback (char *name, lua_CFunction fallback) { | |
| 688 | − lua_pushstring(name); | |
| 689 | − lua_pushcfunction(fallback); | |
| 690 | − do_unprotectedrun(luaT_setfallback, 2, 1); | |
| 691 | − return put_luaObjectonTop(); | |
| 487 | +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | |
| 488 | + TString *ts = luaS_newudata(L, size, NULL); | |
| 489 | + tsvalue(L->top) = ts; | |
| 490 | + ttype(L->top) = LUA_TUSERDATA; | |
| 491 | + api_incr_top(L); | |
| 492 | + return ts->u.d.value; | |
| 692 | 493 | } |
| 693 | −#endif | |
| 694 | 494 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lapi.h,v 1.4 1999/02/23 14:57:28 roberto Exp $ | |
| 2 | +** $Id: lapi.h,v 1.20 2000/08/31 14:08:27 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions from Lua API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,15 +8,10 @@ · 2 unmodified lines | ||
| 8 | 8 | #define lapi_h |
| 9 | 9 | |
| 10 | 10 | |
| 11 | −#include "lua.h" | |
| 12 | 11 | #include "lobject.h" |
| 13 | 12 | |
| 14 | 13 | |
| 15 | −TObject *luaA_Address (lua_Object o); | |
| 16 | −void luaA_pushobject (TObject *o); | |
| 17 | −void luaA_packresults (void); | |
| 18 | −int luaA_passresults (void); | |
| 19 | −TaggedString *luaA_nextvar (TaggedString *g); | |
| 20 | −int luaA_next (Hash *t, int i); | |
| 14 | +TObject *luaA_index (lua_State *L, int index); | |
| 15 | +void luaA_pushobject (lua_State *L, const TObject *o); | |
| 21 | 16 | |
| 22 | 17 | #endif |
| @@ -1,133 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** $Id: lauxlib.c,v 1.17 1999/03/11 18:59:19 roberto Exp $ | |
| 3 | −** Auxiliary functions for building Lua libraries | |
| 4 | −** See Copyright Notice in lua.h | |
| 5 | −*/ | |
| 6 | − | |
| 7 | − | |
| 8 | −#include <stdarg.h> | |
| 9 | −#include <stdio.h> | |
| 10 | −#include <string.h> | |
| 11 | − | |
| 12 | −/* Please Notice: This file uses only the official API of Lua | |
| 13 | −** Any function declared here could be written as an application function. | |
| 14 | −** With care, these functions can be used by other libraries. | |
| 15 | −*/ | |
| 16 | − | |
| 17 | −#include "lauxlib.h" | |
| 18 | −#include "lua.h" | |
| 19 | −#include "luadebug.h" | |
| 20 | − | |
| 21 | − | |
| 22 | − | |
| 23 | −int luaL_findstring (char *name, char *list[]) { | |
| 24 | − int i; | |
| 25 | − for (i=0; list[i]; i++) | |
| 26 | − if (strcmp(list[i], name) == 0) | |
| 27 | − return i; | |
| 28 | − return -1; /* name not found */ | |
| 29 | −} | |
| 30 | − | |
| 31 | −void luaL_argerror (int numarg, char *extramsg) { | |
| 32 | − lua_Function f = lua_stackedfunction(0); | |
| 33 | − char *funcname; | |
| 34 | − lua_getobjname(f, &funcname); | |
| 35 | − numarg -= lua_nups(f); | |
| 36 | − if (funcname == NULL) | |
| 37 | − funcname = "?"; | |
| 38 | − if (extramsg == NULL) | |
| 39 | − luaL_verror("bad argument #%d to function `%.50s'", numarg, funcname); | |
| 40 | − else | |
| 41 | − luaL_verror("bad argument #%d to function `%.50s' (%.100s)", | |
| 42 | − numarg, funcname, extramsg); | |
| 43 | −} | |
| 44 | − | |
| 45 | −char *luaL_check_lstr (int numArg, long *len) | |
| 46 | −{ | |
| 47 | − lua_Object o = lua_getparam(numArg); | |
| 48 | − luaL_arg_check(lua_isstring(o), numArg, "string expected"); | |
| 49 | − if (len) *len = lua_strlen(o); | |
| 50 | − return lua_getstring(o); | |
| 51 | −} | |
| 52 | − | |
| 53 | −char *luaL_opt_lstr (int numArg, char *def, long *len) | |
| 54 | −{ | |
| 55 | − return (lua_getparam(numArg) == LUA_NOOBJECT) ? def : | |
| 56 | − luaL_check_lstr(numArg, len); | |
| 57 | −} | |
| 58 | − | |
| 59 | −double luaL_check_number (int numArg) | |
| 60 | −{ | |
| 61 | − lua_Object o = lua_getparam(numArg); | |
| 62 | − luaL_arg_check(lua_isnumber(o), numArg, "number expected"); | |
| 63 | − return lua_getnumber(o); | |
| 64 | −} | |
| 65 | − | |
| 66 | − | |
| 67 | −double luaL_opt_number (int numArg, double def) | |
| 68 | −{ | |
| 69 | − return (lua_getparam(numArg) == LUA_NOOBJECT) ? def : | |
| 70 | − luaL_check_number(numArg); | |
| 71 | −} | |
| 72 | − | |
| 73 | − | |
| 74 | −lua_Object luaL_tablearg (int arg) | |
| 75 | −{ | |
| 76 | − lua_Object o = lua_getparam(arg); | |
| 77 | − luaL_arg_check(lua_istable(o), arg, "table expected"); | |
| 78 | − return o; | |
| 79 | −} | |
| 80 | − | |
| 81 | −lua_Object luaL_functionarg (int arg) | |
| 82 | −{ | |
| 83 | − lua_Object o = lua_getparam(arg); | |
| 84 | − luaL_arg_check(lua_isfunction(o), arg, "function expected"); | |
| 85 | − return o; | |
| 86 | −} | |
| 87 | − | |
| 88 | −lua_Object luaL_nonnullarg (int numArg) | |
| 89 | −{ | |
| 90 | − lua_Object o = lua_getparam(numArg); | |
| 91 | − luaL_arg_check(o != LUA_NOOBJECT, numArg, "value expected"); | |
| 92 | − return o; | |
| 93 | −} | |
| 94 | − | |
| 95 | −void luaL_openlib (struct luaL_reg *l, int n) | |
| 96 | −{ | |
| 97 | − int i; | |
| 98 | − lua_open(); /* make sure lua is already open */ | |
| 99 | − for (i=0; i<n; i++) | |
| 100 | − lua_register(l[i].name, l[i].func); | |
| 101 | −} | |
| 102 | − | |
| 103 | − | |
| 104 | −void luaL_verror (char *fmt, ...) | |
| 105 | −{ | |
| 106 | − char buff[500]; | |
| 107 | − va_list argp; | |
| 108 | − va_start(argp, fmt); | |
| 109 | − vsprintf(buff, fmt, argp); | |
| 110 | − va_end(argp); | |
| 111 | − lua_error(buff); | |
| 112 | −} | |
| 113 | − | |
| 114 | − | |
| 115 | −void luaL_chunkid (char *out, char *source, int len) { | |
| 116 | − len -= 13; /* 13 = strlen("string ''...\0") */ | |
| 117 | − if (*source == '@') | |
| 118 | − sprintf(out, "file `%.*s'", len, source+1); | |
| 119 | − else if (*source == '(') | |
| 120 | − strcpy(out, "(C code)"); | |
| 121 | − else { | |
| 122 | − char *b = strchr(source , '\n'); /* stop string at first new line */ | |
| 123 | − int lim = (b && (b-source)<len) ? b-source : len; | |
| 124 | − sprintf(out, "string `%.*s'", lim, source); | |
| 125 | − strcpy(out+lim+(13-5), "...'"); /* 5 = strlen("...'\0") */ | |
| 126 | − } | |
| 127 | −} | |
| 128 | − | |
| 129 | − | |
| 130 | −void luaL_filesource (char *out, char *filename, int len) { | |
| 131 | − if (filename == NULL) filename = "(stdin)"; | |
| 132 | − sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */ | |
| 133 | −} | |
| @@ -1,75 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** $Id: lbuffer.c,v 1.9 1999/02/26 15:48:55 roberto Exp $ | |
| 3 | −** Auxiliary functions for building Lua libraries | |
| 4 | −** See Copyright Notice in lua.h | |
| 5 | −*/ | |
| 6 | − | |
| 7 | − | |
| 8 | −#include <stdio.h> | |
| 9 | − | |
| 10 | −#include "lauxlib.h" | |
| 11 | −#include "lmem.h" | |
| 12 | −#include "lstate.h" | |
| 13 | − | |
| 14 | − | |
| 15 | −/*------------------------------------------------------- | |
| 16 | −** Auxiliary buffer | |
| 17 | −-------------------------------------------------------*/ | |
| 18 | − | |
| 19 | − | |
| 20 | −#define EXTRABUFF 32 | |
| 21 | − | |
| 22 | − | |
| 23 | −#define openspace(size) if (L->Mbuffnext+(size) > L->Mbuffsize) Openspace(size) | |
| 24 | − | |
| 25 | −static void Openspace (int size) { | |
| 26 | − lua_State *l = L; /* to optimize */ | |
| 27 | − size += EXTRABUFF; | |
| 28 | − l->Mbuffsize = l->Mbuffnext+size; | |
| 29 | − luaM_growvector(l->Mbuffer, l->Mbuffnext, size, char, arrEM, MAX_INT); | |
| 30 | −} | |
| 31 | − | |
| 32 | − | |
| 33 | −char *luaL_openspace (int size) { | |
| 34 | − openspace(size); | |
| 35 | − return L->Mbuffer+L->Mbuffnext; | |
| 36 | −} | |
| 37 | − | |
| 38 | − | |
| 39 | −void luaL_addchar (int c) { | |
| 40 | − openspace(1); | |
| 41 | − L->Mbuffer[L->Mbuffnext++] = (char)c; | |
| 42 | −} | |
| 43 | − | |
| 44 | − | |
| 45 | −void luaL_resetbuffer (void) { | |
| 46 | − L->Mbuffnext = L->Mbuffbase; | |
| 47 | −} | |
| 48 | − | |
| 49 | − | |
| 50 | −void luaL_addsize (int n) { | |
| 51 | − L->Mbuffnext += n; | |
| 52 | −} | |
| 53 | − | |
| 54 | −int luaL_getsize (void) { | |
| 55 | − return L->Mbuffnext-L->Mbuffbase; | |
| 56 | −} | |
| 57 | − | |
| 58 | −int luaL_newbuffer (int size) { | |
| 59 | − int old = L->Mbuffbase; | |
| 60 | − openspace(size); | |
| 61 | − L->Mbuffbase = L->Mbuffnext; | |
| 62 | − return old; | |
| 63 | −} | |
| 64 | − | |
| 65 | − | |
| 66 | −void luaL_oldbuffer (int old) { | |
| 67 | − L->Mbuffnext = L->Mbuffbase; | |
| 68 | − L->Mbuffbase = old; | |
| 69 | −} | |
| 70 | − | |
| 71 | − | |
| 72 | −char *luaL_buffer (void) { | |
| 73 | − return L->Mbuffer+L->Mbuffbase; | |
| 74 | −} | |
| 75 | − | |
| @@ -1,736 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** $Id: lbuiltin.c,v 1.59 1999/06/17 17:04:03 roberto Exp $ | |
| 3 | −** Built-in functions | |
| 4 | −** See Copyright Notice in lua.h | |
| 5 | −*/ | |
| 6 | − | |
| 7 | − | |
| 8 | −#include <ctype.h> | |
| 9 | −#include <stdio.h> | |
| 10 | −#include <stdlib.h> | |
| 11 | −#include <string.h> | |
| 12 | − | |
| 13 | −#include "lapi.h" | |
| 14 | −#include "lauxlib.h" | |
| 15 | −#include "lbuiltin.h" | |
| 16 | −#include "ldo.h" | |
| 17 | −#include "lfunc.h" | |
| 18 | −#include "lmem.h" | |
| 19 | −#include "lobject.h" | |
| 20 | −#include "lstate.h" | |
| 21 | −#include "lstring.h" | |
| 22 | −#include "ltable.h" | |
| 23 | −#include "ltm.h" | |
| 24 | −#include "lua.h" | |
| 25 | −#include "lundump.h" | |
| 26 | −#include "lvm.h" | |
| 27 | − | |
| 28 | − | |
| 29 | − | |
| 30 | −/* | |
| 31 | −** {====================================================== | |
| 32 | −** Auxiliary functions | |
| 33 | −** ======================================================= | |
| 34 | −*/ | |
| 35 | − | |
| 36 | − | |
| 37 | −static void pushtagstring (TaggedString *s) { | |
| 38 | − TObject o; | |
| 39 | − o.ttype = LUA_T_STRING; | |
| 40 | − o.value.ts = s; | |
| 41 | − luaA_pushobject(&o); | |
| 42 | −} | |
| 43 | − | |
| 44 | − | |
| 45 | −static real getsize (Hash *h) { | |
| 46 | − real max = 0; | |
| 47 | − int i; | |
| 48 | − for (i = 0; i<nhash(h); i++) { | |
| 49 | − Node *n = h->node+i; | |
| 50 | − if (ttype(ref(n)) == LUA_T_NUMBER && | |
| 51 | − ttype(val(n)) != LUA_T_NIL && | |
| 52 | − nvalue(ref(n)) > max) | |
| 53 | − max = nvalue(ref(n)); | |
| 54 | − } | |
| 55 | − return max; | |
| 56 | −} | |
| 57 | − | |
| 58 | − | |
| 59 | −static real getnarg (Hash *a) { | |
| 60 | − TObject index; | |
| 61 | − TObject *value; | |
| 62 | − /* value = table.n */ | |
| 63 | − ttype(&index) = LUA_T_STRING; | |
| 64 | − tsvalue(&index) = luaS_new("n"); | |
| 65 | − value = luaH_get(a, &index); | |
| 66 | − return (ttype(value) == LUA_T_NUMBER) ? nvalue(value) : getsize(a); | |
| 67 | −} | |
| 68 | − | |
| 69 | − | |
| 70 | −static Hash *gethash (int arg) { | |
| 71 | − return avalue(luaA_Address(luaL_tablearg(arg))); | |
| 72 | −} | |
| 73 | − | |
| 74 | −/* }====================================================== */ | |
| 75 | − | |
| 76 | − | |
| 77 | −/* | |
| 78 | −** {====================================================== | |
| 79 | −** Functions that use only the official API | |
| 80 | −** ======================================================= | |
| 81 | −*/ | |
| 82 | − | |
| 83 | − | |
| 84 | −/* | |
| 85 | −** If your system does not support "stderr", redefine this function, or | |
| 86 | −** redefine _ERRORMESSAGE so that it won't need _ALERT. | |
| 87 | −*/ | |
| 88 | −static void luaB_alert (void) { | |
| 89 | − fputs(luaL_check_string(1), stderr); | |
| 90 | −} | |
| 91 | − | |
| 92 | − | |
| 93 | −/* | |
| 94 | −** Standard implementation of _ERRORMESSAGE. | |
| 95 | −** The library "iolib" redefines _ERRORMESSAGE for better error information. | |
| 96 | −*/ | |
| 97 | −static void error_message (void) { | |
| 98 | − lua_Object al = lua_rawgetglobal("_ALERT"); | |
| 99 | − if (lua_isfunction(al)) { /* avoid error loop if _ALERT is not defined */ | |
| 100 | − char buff[600]; | |
| 101 | − sprintf(buff, "lua error: %.500s\n", luaL_check_string(1)); | |
| 102 | − lua_pushstring(buff); | |
| 103 | − lua_callfunction(al); | |
| 104 | − } | |
| 105 | −} | |
| 106 | − | |
| 107 | − | |
| 108 | −/* | |
| 109 | −** If your system does not support "stdout", just remove this function. | |
| 110 | −** If you need, you can define your own "print" function, following this | |
| 111 | −** model but changing "fputs" to put the strings at a proper place | |
| 112 | −** (a console window or a log file, for instance). | |
| 113 | −*/ | |
| 114 | −#ifndef MAXPRINT | |
| 115 | −#define MAXPRINT 40 /* arbitrary limit */ | |
| 116 | −#endif | |
| 117 | − | |
| 118 | −static void luaB_print (void) { | |
| 119 | − lua_Object args[MAXPRINT]; | |
| 120 | − lua_Object obj; | |
| 121 | − int n = 0; | |
| 122 | − int i; | |
| 123 | − while ((obj = lua_getparam(n+1)) != LUA_NOOBJECT) { | |
| 124 | − luaL_arg_check(n < MAXPRINT, n+1, "too many arguments"); | |
| 125 | − args[n++] = obj; | |
| 126 | − } | |
| 127 | − for (i=0; i<n; i++) { | |
| 128 | − lua_pushobject(args[i]); | |
| 129 | − if (lua_call("tostring")) | |
| 130 | − lua_error("error in `tostring' called by `print'"); | |
| 131 | − obj = lua_getresult(1); | |
| 132 | − if (!lua_isstring(obj)) | |
| 133 | − lua_error("`tostring' must return a string to `print'"); | |
| 134 | − if (i>0) fputs("\t", stdout); | |
| 135 | − fputs(lua_getstring(obj), stdout); | |
| 136 | − } | |
| 137 | − fputs("\n", stdout); | |
| 138 | −} | |
| 139 | − | |
| 140 | − | |
| 141 | −static void luaB_tonumber (void) { | |
| 142 | − int base = luaL_opt_int(2, 10); | |
| 143 | − if (base == 10) { /* standard conversion */ | |
| 144 | − lua_Object o = lua_getparam(1); | |
| 145 | − if (lua_isnumber(o)) lua_pushnumber(lua_getnumber(o)); | |
| 146 | − else lua_pushnil(); /* not a number */ | |
| 147 | − } | |
| 148 | − else { | |
| 149 | − char *s = luaL_check_string(1); | |
| 150 | − long n; | |
| 151 | − luaL_arg_check(0 <= base && base <= 36, 2, "base out of range"); | |
| 152 | − n = strtol(s, &s, base); | |
| 153 | − while (isspace((unsigned char)*s)) s++; /* skip trailing spaces */ | |
| 154 | − if (*s) lua_pushnil(); /* invalid format: return nil */ | |
| 155 | − else lua_pushnumber(n); | |
| 156 | − } | |
| 157 | −} | |
| 158 | − | |
| 159 | − | |
| 160 | −static void luaB_error (void) { | |
| 161 | − lua_error(lua_getstring(lua_getparam(1))); | |
| 162 | −} | |
| 163 | − | |
| 164 | −static void luaB_setglobal (void) { | |
| 165 | − char *n = luaL_check_string(1); | |
| 166 | − lua_Object value = luaL_nonnullarg(2); | |
| 167 | − lua_pushobject(value); | |
| 168 | − lua_setglobal(n); | |
| 169 | − lua_pushobject(value); /* return given value */ | |
| 170 | −} | |
| 171 | − | |
| 172 | −static void luaB_rawsetglobal (void) { | |
| 173 | − char *n = luaL_check_string(1); | |
| 174 | − lua_Object value = luaL_nonnullarg(2); | |
| 175 | − lua_pushobject(value); | |
| 176 | − lua_rawsetglobal(n); | |
| 177 | − lua_pushobject(value); /* return given value */ | |
| 178 | −} | |
| 179 | − | |
| 180 | −static void luaB_getglobal (void) { | |
| 181 | − lua_pushobject(lua_getglobal(luaL_check_string(1))); | |
| 182 | −} | |
| 183 | − | |
| 184 | −static void luaB_rawgetglobal (void) { | |
| 185 | − lua_pushobject(lua_rawgetglobal(luaL_check_string(1))); | |
| 186 | −} | |
| 187 | − | |
| 188 | −static void luaB_luatag (void) { | |
| 189 | − lua_pushnumber(lua_tag(lua_getparam(1))); | |
| 190 | −} | |
| 191 | − | |
| 192 | −static void luaB_settag (void) { | |
| 193 | − lua_Object o = luaL_tablearg(1); | |
| 194 | − lua_pushobject(o); | |
| 195 | − lua_settag(luaL_check_int(2)); | |
| 196 | − lua_pushobject(o); /* return first argument */ | |
| 197 | −} | |
| 198 | − | |
| 199 | −static void luaB_newtag (void) { | |
| 200 | − lua_pushnumber(lua_newtag()); | |
| 201 | −} | |
| 202 | − | |
| 203 | −static void luaB_copytagmethods (void) { | |
| 204 | − lua_pushnumber(lua_copytagmethods(luaL_check_int(1), | |
| 205 | − luaL_check_int(2))); | |
| 206 | −} | |
| 207 | − | |
| 208 | −static void luaB_rawgettable (void) { | |
| 209 | − lua_pushobject(luaL_nonnullarg(1)); | |
| 210 | − lua_pushobject(luaL_nonnullarg(2)); | |
| 211 | − lua_pushobject(lua_rawgettable()); | |
| 212 | −} | |
| 213 | − | |
| 214 | −static void luaB_rawsettable (void) { | |
| 215 | − lua_pushobject(luaL_nonnullarg(1)); | |
| 216 | − lua_pushobject(luaL_nonnullarg(2)); | |
| 217 | − lua_pushobject(luaL_nonnullarg(3)); | |
| 218 | − lua_rawsettable(); | |
| 219 | −} | |
| 220 | − | |
| 221 | −static void luaB_settagmethod (void) { | |
| 222 | − lua_Object nf = luaL_nonnullarg(3); | |
| 223 | − lua_pushobject(nf); | |
| 224 | − lua_pushobject(lua_settagmethod(luaL_check_int(1), luaL_check_string(2))); | |
| 225 | −} | |
| 226 | − | |
| 227 | −static void luaB_gettagmethod (void) { | |
| 228 | − lua_pushobject(lua_gettagmethod(luaL_check_int(1), luaL_check_string(2))); | |
| 229 | −} | |
| 230 | − | |
| 231 | −static void luaB_seterrormethod (void) { | |
| 232 | − lua_Object nf = luaL_functionarg(1); | |
| 233 | − lua_pushobject(nf); | |
| 234 | − lua_pushobject(lua_seterrormethod()); | |
| 235 | −} | |
| 236 | − | |
| 237 | −static void luaB_collectgarbage (void) { | |
| 238 | − lua_pushnumber(lua_collectgarbage(luaL_opt_int(1, 0))); | |
| 239 | −} | |
| 240 | − | |
| 241 | −/* }====================================================== */ | |
| 242 | − | |
| 243 | − | |
| 244 | −/* | |
| 245 | −** {====================================================== | |
| 246 | −** Functions that could use only the official API but | |
| 247 | −** do not, for efficiency. | |
| 248 | −** ======================================================= | |
| 249 | −*/ | |
| 250 | − | |
| 251 | −static void luaB_dostring (void) { | |
| 252 | − long l; | |
| 253 | − char *s = luaL_check_lstr(1, &l); | |
| 254 | − if (*s == ID_CHUNK) | |
| 255 | − lua_error("`dostring' cannot run pre-compiled code"); | |
| 256 | − if (lua_dobuffer(s, l, luaL_opt_string(2, s)) == 0) | |
| 257 | − if (luaA_passresults() == 0) | |
| 258 | − lua_pushuserdata(NULL); /* at least one result to signal no errors */ | |
| 259 | −} | |
| 260 | − | |
| 261 | − | |
| 262 | −static void luaB_dofile (void) { | |
| 263 | − char *fname = luaL_opt_string(1, NULL); | |
| 264 | − if (lua_dofile(fname) == 0) | |
| 265 | − if (luaA_passresults() == 0) | |
| 266 | − lua_pushuserdata(NULL); /* at least one result to signal no errors */ | |
| 267 | −} | |
| 268 | − | |
| 269 | − | |
| 270 | −static void luaB_call (void) { | |
| 271 | − lua_Object f = luaL_nonnullarg(1); | |
| 272 | − Hash *arg = gethash(2); | |
| 273 | − char *options = luaL_opt_string(3, ""); | |
| 274 | − lua_Object err = lua_getparam(4); | |
| 275 | − int narg = (int)getnarg(arg); | |
| 276 | − int i, status; | |
| 277 | − if (err != LUA_NOOBJECT) { /* set new error method */ | |
| 278 | − lua_pushobject(err); | |
| 279 | − err = lua_seterrormethod(); | |
| 280 | − } | |
| 281 | − /* push arg[1...n] */ | |
| 282 | − luaD_checkstack(narg); | |
| 283 | − for (i=0; i<narg; i++) | |
| 284 | − *(L->stack.top++) = *luaH_getint(arg, i+1); | |
| 285 | − status = lua_callfunction(f); | |
| 286 | − if (err != LUA_NOOBJECT) { /* restore old error method */ | |
| 287 | − lua_pushobject(err); | |
| 288 | − lua_seterrormethod(); | |
| 289 | − } | |
| 290 | − if (status != 0) { /* error in call? */ | |
| 291 | − if (strchr(options, 'x')) { | |
| 292 | − lua_pushnil(); | |
| 293 | − return; /* return nil to signal the error */ | |
| 294 | − } | |
| 295 | − else | |
| 296 | − lua_error(NULL); | |
| 297 | − } | |
| 298 | − else { /* no errors */ | |
| 299 | − if (strchr(options, 'p')) | |
| 300 | − luaA_packresults(); | |
| 301 | − else | |
| 302 | − luaA_passresults(); | |
| 303 | − } | |
| 304 | −} | |
| 305 | − | |
| 306 | − | |
| 307 | −static void luaB_nextvar (void) { | |
| 308 | − TObject *o = luaA_Address(luaL_nonnullarg(1)); | |
| 309 | − TaggedString *g; | |
| 310 | − if (ttype(o) == LUA_T_NIL) | |
| 311 | − g = NULL; | |
| 312 | − else { | |
| 313 | − luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected"); | |
| 314 | − g = tsvalue(o); | |
| 315 | − } | |
| 316 | − if (!luaA_nextvar(g)) | |
| 317 | − lua_pushnil(); | |
| 318 | −} | |
| 319 | − | |
| 320 | − | |
| 321 | −static void luaB_next (void) { | |
| 322 | − Hash *a = gethash(1); | |
| 323 | − TObject *k = luaA_Address(luaL_nonnullarg(2)); | |
| 324 | − int i = (ttype(k) == LUA_T_NIL) ? 0 : luaH_pos(a, k)+1; | |
| 325 | − if (luaA_next(a, i) == 0) | |
| 326 | − lua_pushnil(); | |
| 327 | −} | |
| 328 | − | |
| 329 | − | |
| 330 | −static void luaB_tostring (void) { | |
| 331 | − lua_Object obj = lua_getparam(1); | |
| 332 | − TObject *o = luaA_Address(obj); | |
| 333 | − char buff[64]; | |
| 334 | − switch (ttype(o)) { | |
| 335 | − case LUA_T_NUMBER: | |
| 336 | − lua_pushstring(lua_getstring(obj)); | |
| 337 | − return; | |
| 338 | − case LUA_T_STRING: | |
| 339 | − lua_pushobject(obj); | |
| 340 | − return; | |
| 341 | − case LUA_T_ARRAY: | |
| 342 | − sprintf(buff, "table: %p", (void *)o->value.a); | |
| 343 | − break; | |
| 344 | − case LUA_T_CLOSURE: | |
| 345 | − sprintf(buff, "function: %p", (void *)o->value.cl); | |
| 346 | − break; | |
| 347 | − case LUA_T_PROTO: | |
| 348 | − sprintf(buff, "function: %p", (void *)o->value.tf); | |
| 349 | − break; | |
| 350 | − case LUA_T_CPROTO: | |
| 351 | − sprintf(buff, "function: %p", (void *)o->value.f); | |
| 352 | − break; | |
| 353 | − case LUA_T_USERDATA: | |
| 354 | − sprintf(buff, "userdata: %p", o->value.ts->u.d.v); | |
| 355 | − break; | |
| 356 | − case LUA_T_NIL: | |
| 357 | − lua_pushstring("nil"); | |
| 358 | − return; | |
| 359 | − default: | |
| 360 | − LUA_INTERNALERROR("invalid type"); | |
| 361 | − } | |
| 362 | − lua_pushstring(buff); | |
| 363 | −} | |
| 364 | − | |
| 365 | − | |
| 366 | −static void luaB_type (void) { | |
| 367 | − lua_Object o = luaL_nonnullarg(1); | |
| 368 | − lua_pushstring(luaO_typename(luaA_Address(o))); | |
| 369 | − lua_pushnumber(lua_tag(o)); | |
| 370 | −} | |
| 371 | − | |
| 372 | −/* }====================================================== */ | |
| 373 | − | |
| 374 | − | |
| 375 | − | |
| 376 | −/* | |
| 377 | −** {====================================================== | |
| 378 | −** "Extra" functions | |
| 379 | −** These functions can be written in Lua, so you can | |
| 380 | −** delete them if you need a tiny Lua implementation. | |
| 381 | −** If you delete them, remove their entries in array | |
| 382 | −** "builtin_funcs". | |
| 383 | −** ======================================================= | |
| 384 | −*/ | |
| 385 | − | |
| 386 | −static void luaB_assert (void) { | |
| 387 | − lua_Object p = lua_getparam(1); | |
| 388 | − if (p == LUA_NOOBJECT || lua_isnil(p)) | |
| 389 | − luaL_verror("assertion failed! %.100s", luaL_opt_string(2, "")); | |
| 390 | −} | |
| 391 | − | |
| 392 | − | |
| 393 | −static void luaB_foreachi (void) { | |
| 394 | − Hash *t = gethash(1); | |
| 395 | − int i; | |
| 396 | − int n = (int)getnarg(t); | |
| 397 | − TObject f; | |
| 398 | − /* 'f' cannot be a pointer to TObject, because it is on the stack, and the | |
| 399 | − stack may be reallocated by the call. Moreover, some C compilers do not | |
| 400 | − initialize structs, so we must do the assignment after the declaration */ | |
| 401 | − f = *luaA_Address(luaL_functionarg(2)); | |
| 402 | − luaD_checkstack(3); /* for f, ref, and val */ | |
| 403 | − for (i=1; i<=n; i++) { | |
| 404 | − *(L->stack.top++) = f; | |
| 405 | − ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i; | |
| 406 | − *(L->stack.top++) = *luaH_getint(t, i); | |
| 407 | − luaD_calln(2, 1); | |
| 408 | − if (ttype(L->stack.top-1) != LUA_T_NIL) | |
| 409 | − return; | |
| 410 | − L->stack.top--; | |
| 411 | − } | |
| 412 | −} | |
| 413 | − | |
| 414 | − | |
| 415 | −static void luaB_foreach (void) { | |
| 416 | − Hash *a = gethash(1); | |
| 417 | − int i; | |
| 418 | − TObject f; /* see comment in 'foreachi' */ | |
| 419 | − f = *luaA_Address(luaL_functionarg(2)); | |
| 420 | − luaD_checkstack(3); /* for f, ref, and val */ | |
| 421 | − for (i=0; i<a->nhash; i++) { | |
| 422 | − Node *nd = &(a->node[i]); | |
| 423 | − if (ttype(val(nd)) != LUA_T_NIL) { | |
| 424 | − *(L->stack.top++) = f; | |
| 425 | − *(L->stack.top++) = *ref(nd); | |
| 426 | − *(L->stack.top++) = *val(nd); | |
| 427 | − luaD_calln(2, 1); | |
| 428 | − if (ttype(L->stack.top-1) != LUA_T_NIL) | |
| 429 | − return; | |
| 430 | − L->stack.top--; /* remove result */ | |
| 431 | − } | |
| 432 | − } | |
| 433 | −} | |
| 434 | − | |
| 435 | − | |
| 436 | −static void luaB_foreachvar (void) { | |
| 437 | − GCnode *g; | |
| 438 | − TObject f; /* see comment in 'foreachi' */ | |
| 439 | − f = *luaA_Address(luaL_functionarg(1)); | |
| 440 | − luaD_checkstack(4); /* for extra var name, f, var name, and globalval */ | |
| 441 | − for (g = L->rootglobal.next; g; g = g->next) { | |
| 442 | − TaggedString *s = (TaggedString *)g; | |
| 443 | − if (s->u.s.globalval.ttype != LUA_T_NIL) { | |
| 444 | − pushtagstring(s); /* keep (extra) s on stack to avoid GC */ | |
| 445 | − *(L->stack.top++) = f; | |
| 446 | − pushtagstring(s); | |
| 447 | − *(L->stack.top++) = s->u.s.globalval; | |
| 448 | − luaD_calln(2, 1); | |
| 449 | − if (ttype(L->stack.top-1) != LUA_T_NIL) { | |
| 450 | − L->stack.top--; | |
| 451 | − *(L->stack.top-1) = *L->stack.top; /* remove extra s */ | |
| 452 | − return; | |
| 453 | − } | |
| 454 | − L->stack.top-=2; /* remove result and extra s */ | |
| 455 | − } | |
| 456 | − } | |
| 457 | −} | |
| 458 | − | |
| 459 | − | |
| 460 | −static void luaB_getn (void) { | |
| 461 | − lua_pushnumber(getnarg(gethash(1))); | |
| 462 | −} | |
| 463 | − | |
| 464 | − | |
| 465 | −static void luaB_tinsert (void) { | |
| 466 | − Hash *a = gethash(1); | |
| 467 | − lua_Object v = lua_getparam(3); | |
| 468 | − int n = (int)getnarg(a); | |
| 469 | − int pos; | |
| 470 | − if (v != LUA_NOOBJECT) | |
| 471 | − pos = luaL_check_int(2); | |
| 472 | − else { /* called with only 2 arguments */ | |
| 473 | − v = luaL_nonnullarg(2); | |
| 474 | − pos = n+1; | |
| 475 | − } | |
| 476 | − luaV_setn(a, n+1); /* a.n = n+1 */ | |
| 477 | − for ( ;n>=pos; n--) | |
| 478 | − luaH_move(a, n, n+1); /* a[n+1] = a[n] */ | |
| 479 | − luaH_setint(a, pos, luaA_Address(v)); /* a[pos] = v */ | |
| 480 | −} | |
| 481 | − | |
| 482 | − | |
| 483 | −static void luaB_tremove (void) { | |
| 484 | − Hash *a = gethash(1); | |
| 485 | − int n = (int)getnarg(a); | |
| 486 | − int pos = luaL_opt_int(2, n); | |
| 487 | − if (n <= 0) return; /* table is "empty" */ | |
| 488 | − luaA_pushobject(luaH_getint(a, pos)); /* result = a[pos] */ | |
| 489 | − for ( ;pos<n; pos++) | |
| 490 | − luaH_move(a, pos+1, pos); /* a[pos] = a[pos+1] */ | |
| 491 | − luaV_setn(a, n-1); /* a.n = n-1 */ | |
| 492 | − luaH_setint(a, n, &luaO_nilobject); /* a[n] = nil */ | |
| 493 | −} | |
| 494 | − | |
| 495 | − | |
| 496 | −/* { | |
| 497 | −** Quicksort | |
| 498 | −*/ | |
| 499 | − | |
| 500 | −static void swap (Hash *a, int i, int j) { | |
| 501 | − TObject temp; | |
| 502 | − temp = *luaH_getint(a, i); | |
| 503 | − luaH_move(a, j, i); | |
| 504 | − luaH_setint(a, j, &temp); | |
| 505 | −} | |
| 506 | − | |
| 507 | −static int sort_comp (lua_Object f, TObject *a, TObject *b) { | |
| 508 | − /* notice: the caller (auxsort) must check stack space */ | |
| 509 | − if (f != LUA_NOOBJECT) { | |
| 510 | − *(L->stack.top) = *luaA_Address(f); | |
| 511 | − *(L->stack.top+1) = *a; | |
| 512 | − *(L->stack.top+2) = *b; | |
| 513 | − L->stack.top += 3; | |
| 514 | − luaD_calln(2, 1); | |
| 515 | − } | |
| 516 | − else { /* a < b? */ | |
| 517 | − *(L->stack.top) = *a; | |
| 518 | − *(L->stack.top+1) = *b; | |
| 519 | − L->stack.top += 2; | |
| 520 | − luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); | |
| 521 | − } | |
| 522 | − return ttype(--(L->stack.top)) != LUA_T_NIL; | |
| 523 | −} | |
| 524 | − | |
| 525 | −static void auxsort (Hash *a, int l, int u, lua_Object f) { | |
| 526 | − while (l < u) { /* for tail recursion */ | |
| 527 | − TObject *P; | |
| 528 | − int i, j; | |
| 529 | − /* sort elements a[l], a[(l+u)/2] and a[u] */ | |
| 530 | − if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[l]>a[u]? */ | |
| 531 | − swap(a, l, u); | |
| 532 | − if (u-l == 1) break; /* only 2 elements */ | |
| 533 | − i = (l+u)/2; | |
| 534 | − P = luaH_getint(a, i); | |
| 535 | − if (sort_comp(f, P, luaH_getint(a, l))) /* a[l]>a[i]? */ | |
| 536 | − swap(a, l, i); | |
| 537 | − else if (sort_comp(f, luaH_getint(a, u), P)) /* a[i]>a[u]? */ | |
| 538 | − swap(a, i, u); | |
| 539 | − if (u-l == 2) break; /* only 3 elements */ | |
| 540 | − P = L->stack.top++; | |
| 541 | − *P = *luaH_getint(a, i); /* save pivot on stack (for GC) */ | |
| 542 | − swap(a, i, u-1); /* put median element as pivot (a[u-1]) */ | |
| 543 | − /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */ | |
| 544 | − i = l; j = u-1; | |
| 545 | − for (;;) { | |
| 546 | − /* invariant: a[l..i] <= P <= a[j..u] */ | |
| 547 | − while (sort_comp(f, luaH_getint(a, ++i), P)) /* stop when a[i] >= P */ | |
| 548 | − if (i>u) lua_error("invalid order function for sorting"); | |
| 549 | − while (sort_comp(f, P, luaH_getint(a, --j))) /* stop when a[j] <= P */ | |
| 550 | − if (j<l) lua_error("invalid order function for sorting"); | |
| 551 | − if (j<i) break; | |
| 552 | − swap(a, i, j); | |
| 553 | − } | |
| 554 | − swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */ | |
| 555 | − L->stack.top--; /* remove pivot from stack */ | |
| 556 | − /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ | |
| 557 | − /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */ | |
| 558 | − if (i-l < u-i) { | |
| 559 | − j=l; i=i-1; l=i+2; | |
| 560 | − } | |
| 561 | − else { | |
| 562 | − j=i+1; i=u; u=j-2; | |
| 563 | − } | |
| 564 | − auxsort(a, j, i, f); /* call recursively the smaller one */ | |
| 565 | − } /* repeat the routine for the larger one */ | |
| 566 | −} | |
| 567 | − | |
| 568 | −static void luaB_sort (void) { | |
| 569 | − lua_Object t = lua_getparam(1); | |
| 570 | − Hash *a = gethash(1); | |
| 571 | − int n = (int)getnarg(a); | |
| 572 | − lua_Object func = lua_getparam(2); | |
| 573 | − luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2, | |
| 574 | − "function expected"); | |
| 575 | − luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */ | |
| 576 | − auxsort(a, 1, n, func); | |
| 577 | − lua_pushobject(t); | |
| 578 | −} | |
| 579 | − | |
| 580 | −/* }}===================================================== */ | |
| 581 | − | |
| 582 | − | |
| 583 | −/* | |
| 584 | −** ====================================================== */ | |
| 585 | − | |
| 586 | − | |
| 587 | − | |
| 588 | −#ifdef DEBUG | |
| 589 | −/* | |
| 590 | −** {====================================================== | |
| 591 | −** some DEBUG functions | |
| 592 | −** ======================================================= | |
| 593 | −*/ | |
| 594 | − | |
| 595 | −static void mem_query (void) { | |
| 596 | − lua_pushnumber(totalmem); | |
| 597 | − lua_pushnumber(numblocks); | |
| 598 | −} | |
| 599 | − | |
| 600 | − | |
| 601 | −static void query_strings (void) { | |
| 602 | − lua_pushnumber(L->string_root[luaL_check_int(1)].nuse); | |
| 603 | −} | |
| 604 | − | |
| 605 | − | |
| 606 | −static void countlist (void) { | |
| 607 | − char *s = luaL_check_string(1); | |
| 608 | − GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next : | |
| 609 | − (s[0]=='p') ? L->rootproto.next : L->rootglobal.next; | |
| 610 | − int i=0; | |
| 611 | − while (l) { | |
| 612 | − i++; | |
| 613 | − l = l->next; | |
| 614 | − } | |
| 615 | − lua_pushnumber(i); | |
| 616 | −} | |
| 617 | − | |
| 618 | − | |
| 619 | −static void testC (void) { | |
| 620 | −#define getnum(s) ((*s++) - '0') | |
| 621 | −#define getname(s) (nome[0] = *s++, nome) | |
| 622 | − | |
| 623 | − static int locks[10]; | |
| 624 | − lua_Object reg[10]; | |
| 625 | − char nome[2]; | |
| 626 | − char *s = luaL_check_string(1); | |
| 627 | − nome[1] = 0; | |
| 628 | − for (;;) { | |
| 629 | − switch (*s++) { | |
| 630 | − case '0': case '1': case '2': case '3': case '4': | |
| 631 | − case '5': case '6': case '7': case '8': case '9': | |
| 632 | − lua_pushnumber(*(s-1) - '0'); | |
| 633 | − break; | |
| 634 | − | |
| 635 | − case 'c': reg[getnum(s)] = lua_createtable(); break; | |
| 636 | − case 'C': { lua_CFunction f = lua_getcfunction(lua_getglobal(getname(s))); | |
| 637 | − lua_pushcclosure(f, getnum(s)); | |
| 638 | − break; | |
| 639 | − } | |
| 640 | − case 'P': reg[getnum(s)] = lua_pop(); break; | |
| 641 | − case 'g': { int n=getnum(s); reg[n]=lua_getglobal(getname(s)); break; } | |
| 642 | − case 'G': { int n = getnum(s); | |
| 643 | − reg[n] = lua_rawgetglobal(getname(s)); | |
| 644 | − break; | |
| 645 | − } | |
| 646 | − case 'l': locks[getnum(s)] = lua_ref(1); break; | |
| 647 | − case 'L': locks[getnum(s)] = lua_ref(0); break; | |
| 648 | − case 'r': { int n=getnum(s); reg[n]=lua_getref(locks[getnum(s)]); break; } | |
| 649 | − case 'u': lua_unref(locks[getnum(s)]); break; | |
| 650 | − case 'p': { int n = getnum(s); reg[n] = lua_getparam(getnum(s)); break; } | |
| 651 | − case '=': lua_setglobal(getname(s)); break; | |
| 652 | − case 's': lua_pushstring(getname(s)); break; | |
| 653 | − case 'o': lua_pushobject(reg[getnum(s)]); break; | |
| 654 | − case 'f': lua_call(getname(s)); break; | |
| 655 | − case 'i': reg[getnum(s)] = lua_gettable(); break; | |
| 656 | − case 'I': reg[getnum(s)] = lua_rawgettable(); break; | |
| 657 | − case 't': lua_settable(); break; | |
| 658 | − case 'T': lua_rawsettable(); break; | |
| 659 | − case 'N' : lua_pushstring(lua_nextvar(lua_getstring(reg[getnum(s)]))); | |
| 660 | − break; | |
| 661 | − case 'n' : { int n=getnum(s); | |
| 662 | − n=lua_next(reg[n], (int)lua_getnumber(reg[getnum(s)])); | |
| 663 | − lua_pushnumber(n); break; | |
| 664 | − } | |
| 665 | − default: luaL_verror("unknown command in `testC': %c", *(s-1)); | |
| 666 | − } | |
| 667 | − if (*s == 0) return; | |
| 668 | − if (*s++ != ' ') lua_error("missing ` ' between commands in `testC'"); | |
| 669 | − } | |
| 670 | −} | |
| 671 | − | |
| 672 | −/* }====================================================== */ | |
| 673 | −#endif | |
| 674 | − | |
| 675 | − | |
| 676 | − | |
| 677 | −static struct luaL_reg builtin_funcs[] = { | |
| 678 | −#ifdef LUA_COMPAT2_5 | |
| 679 | − {"setfallback", luaT_setfallback}, | |
| 680 | −#endif | |
| 681 | −#ifdef DEBUG | |
| 682 | − {"testC", testC}, | |
| 683 | − {"totalmem", mem_query}, | |
| 684 | − {"count", countlist}, | |
| 685 | − {"querystr", query_strings}, | |
| 686 | −#endif | |
| 687 | − {"_ALERT", luaB_alert}, | |
| 688 | − {"_ERRORMESSAGE", error_message}, | |
| 689 | − {"call", luaB_call}, | |
| 690 | − {"collectgarbage", luaB_collectgarbage}, | |
| 691 | − {"copytagmethods", luaB_copytagmethods}, | |
| 692 | − {"dofile", luaB_dofile}, | |
| 693 | − {"dostring", luaB_dostring}, | |
| 694 | − {"error", luaB_error}, | |
| 695 | − {"getglobal", luaB_getglobal}, | |
| 696 | − {"gettagmethod", luaB_gettagmethod}, | |
| 697 | − {"newtag", luaB_newtag}, | |
| 698 | − {"next", luaB_next}, | |
| 699 | − {"nextvar", luaB_nextvar}, | |
| 700 | − {"print", luaB_print}, | |
| 701 | − {"rawgetglobal", luaB_rawgetglobal}, | |
| 702 | − {"rawgettable", luaB_rawgettable}, | |
| 703 | − {"rawsetglobal", luaB_rawsetglobal}, | |
| 704 | − {"rawsettable", luaB_rawsettable}, | |
| 705 | − {"seterrormethod", luaB_seterrormethod}, | |
| 706 | − {"setglobal", luaB_setglobal}, | |
| 707 | − {"settag", luaB_settag}, | |
| 708 | − {"settagmethod", luaB_settagmethod}, | |
| 709 | − {"tag", luaB_luatag}, | |
| 710 | − {"tonumber", luaB_tonumber}, | |
| 711 | − {"tostring", luaB_tostring}, | |
| 712 | − {"type", luaB_type}, | |
| 713 | − /* "Extra" functions */ | |
| 714 | − {"assert", luaB_assert}, | |
| 715 | − {"foreach", luaB_foreach}, | |
| 716 | − {"foreachi", luaB_foreachi}, | |
| 717 | − {"foreachvar", luaB_foreachvar}, | |
| 718 | − {"getn", luaB_getn}, | |
| 719 | − {"sort", luaB_sort}, | |
| 720 | − {"tinsert", luaB_tinsert}, | |
| 721 | − {"tremove", luaB_tremove} | |
| 722 | −}; | |
| 723 | − | |
| 724 | − | |
| 725 | −#define INTFUNCSIZE (sizeof(builtin_funcs)/sizeof(builtin_funcs[0])) | |
| 726 | − | |
| 727 | − | |
| 728 | −void luaB_predefine (void) { | |
| 729 | − /* pre-register mem error messages, to avoid loop when error arises */ | |
| 730 | − luaS_newfixedstring(tableEM); | |
| 731 | − luaS_newfixedstring(memEM); | |
| 732 | − luaL_openlib(builtin_funcs, (sizeof(builtin_funcs)/sizeof(builtin_funcs[0]))); | |
| 733 | − lua_pushstring(LUA_VERSION); | |
| 734 | − lua_setglobal("_VERSION"); | |
| 735 | −} | |
| 736 | − | |
| @@ -1,14 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** $Id: lbuiltin.h,v 1.1 1997/09/16 19:25:59 roberto Exp $ | |
| 3 | −** Built-in functions | |
| 4 | −** See Copyright Notice in lua.h | |
| 5 | −*/ | |
| 6 | − | |
| 7 | −#ifndef lbuiltin_h | |
| 8 | −#define lbuiltin_h | |
| 9 | − | |
| 10 | − | |
| 11 | −void luaB_predefine (void); | |
| 12 | − | |
| 13 | − | |
| 14 | −#endif | |
| @@ -0,0 +1,701 @@ | ||
| 1 | +/* | |
| 2 | +** $Id: lcode.c,v 1.51 2000/09/29 12:42:13 roberto Exp $ | |
| 3 | +** Code generator for Lua | |
| 4 | +** See Copyright Notice in lua.h | |
| 5 | +*/ | |
| 6 | + | |
| 7 | + | |
| 8 | +#include "stdlib.h" | |
| 9 | + | |
| 10 | +#include "lua.h" | |
| 11 | + | |
| 12 | +#include "lcode.h" | |
| 13 | +#include "ldo.h" | |
| 14 | +#include "llex.h" | |
| 15 | +#include "lmem.h" | |
| 16 | +#include "lobject.h" | |
| 17 | +#include "lopcodes.h" | |
| 18 | +#include "lparser.h" | |
| 19 | + | |
| 20 | + | |
| 21 | +void luaK_error (LexState *ls, const char *msg) { | |
| 22 | + luaX_error(ls, msg, ls->t.token); | |
| 23 | +} | |
| 24 | + | |
| 25 | + | |
| 26 | +/* | |
| 27 | +** Returns the the previous instruction, for optimizations. | |
| 28 | +** If there is a jump target between this and the current instruction, | |
| 29 | +** returns a dummy instruction to avoid wrong optimizations. | |
| 30 | +*/ | |
| 31 | +static Instruction previous_instruction (FuncState *fs) { | |
| 32 | + if (fs->pc > fs->lasttarget) /* no jumps to current position? */ | |
| 33 | + return fs->f->code[fs->pc-1]; /* returns previous instruction */ | |
| 34 | + else | |
| 35 | + return CREATE_0(OP_END); /* no optimizations after an `END' */ | |
| 36 | +} | |
| 37 | + | |
| 38 | + | |
| 39 | +int luaK_jump (FuncState *fs) { | |
| 40 | + int j = luaK_code1(fs, OP_JMP, NO_JUMP); | |
| 41 | + if (j == fs->lasttarget) { /* possible jumps to this jump? */ | |
| 42 | + luaK_concat(fs, &j, fs->jlt); /* keep them on hold */ | |
| 43 | + fs->jlt = NO_JUMP; | |
| 44 | + } | |
| 45 | + return j; | |
| 46 | +} | |
| 47 | + | |
| 48 | + | |
| 49 | +static void luaK_fixjump (FuncState *fs, int pc, int dest) { | |
| 50 | + Instruction *jmp = &fs->f->code[pc]; | |
| 51 | + if (dest == NO_JUMP) | |
| 52 | + SETARG_S(*jmp, NO_JUMP); /* point to itself to represent end of list */ | |
| 53 | + else { /* jump is relative to position following jump instruction */ | |
| 54 | + int offset = dest-(pc+1); | |
| 55 | + if (abs(offset) > MAXARG_S) | |
| 56 | + luaK_error(fs->ls, "control structure too long"); | |
| 57 | + SETARG_S(*jmp, offset); | |
| 58 | + } | |
| 59 | +} | |
| 60 | + | |
| 61 | + | |
| 62 | +static int luaK_getjump (FuncState *fs, int pc) { | |
| 63 | + int offset = GETARG_S(fs->f->code[pc]); | |
| 64 | + if (offset == NO_JUMP) /* point to itself represents end of list */ | |
| 65 | + return NO_JUMP; /* end of list */ | |
| 66 | + else | |
| 67 | + return (pc+1)+offset; /* turn offset into absolute position */ | |
| 68 | +} | |
| 69 | + | |
| 70 | + | |
| 71 | +/* | |
| 72 | +** returns current `pc' and marks it as a jump target (to avoid wrong | |
| 73 | +** optimizations with consecutive instructions not in the same basic block). | |
| 74 | +** discharge list of jumps to last target. | |
| 75 | +*/ | |
| 76 | +int luaK_getlabel (FuncState *fs) { | |
| 77 | + if (fs->pc != fs->lasttarget) { | |
| 78 | + int lasttarget = fs->lasttarget; | |
| 79 | + fs->lasttarget = fs->pc; | |
| 80 | + luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */ | |
| 81 | + fs->jlt = NO_JUMP; /* nobody jumps to this new label (yet) */ | |
| 82 | + } | |
| 83 | + return fs->pc; | |
| 84 | +} | |
| 85 | + | |
| 86 | + | |
| 87 | +void luaK_deltastack (FuncState *fs, int delta) { | |
| 88 | + fs->stacklevel += delta; | |
| 89 | + if (fs->stacklevel > fs->f->maxstacksize) { | |
| 90 | + if (fs->stacklevel > MAXSTACK) | |
| 91 | + luaK_error(fs->ls, "function or expression too complex"); | |
| 92 | + fs->f->maxstacksize = fs->stacklevel; | |
| 93 | + } | |
| 94 | +} | |
| 95 | + | |
| 96 | + | |
| 97 | +void luaK_kstr (LexState *ls, int c) { | |
| 98 | + luaK_code1(ls->fs, OP_PUSHSTRING, c); | |
| 99 | +} | |
| 100 | + | |
| 101 | + | |
| 102 | +static int number_constant (FuncState *fs, Number r) { | |
| 103 | + /* check whether `r' has appeared within the last LOOKBACKNUMS entries */ | |
| 104 | + Proto *f = fs->f; | |
| 105 | + int c = f->nknum; | |
| 106 | + int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS; | |
| 107 | + while (--c >= lim) | |
| 108 | + if (f->knum[c] == r) return c; | |
| 109 | + /* not found; create a new entry */ | |
| 110 | + luaM_growvector(fs->L, f->knum, f->nknum, 1, Number, | |
| 111 | + "constant table overflow", MAXARG_U); | |
| 112 | + c = f->nknum++; | |
| 113 | + f->knum[c] = r; | |
| 114 | + return c; | |
| 115 | +} | |
| 116 | + | |
| 117 | + | |
| 118 | +void luaK_number (FuncState *fs, Number f) { | |
| 119 | + if (f <= (Number)MAXARG_S && (Number)(int)f == f) | |
| 120 | + luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */ | |
| 121 | + else | |
| 122 | + luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f)); | |
| 123 | +} | |
| 124 | + | |
| 125 | + | |
| 126 | +void luaK_adjuststack (FuncState *fs, int n) { | |
| 127 | + if (n > 0) | |
| 128 | + luaK_code1(fs, OP_POP, n); | |
| 129 | + else | |
| 130 | + luaK_code1(fs, OP_PUSHNIL, -n); | |
| 131 | +} | |
| 132 | + | |
| 133 | + | |
| 134 | +int luaK_lastisopen (FuncState *fs) { | |
| 135 | + /* check whether last instruction is an open function call */ | |
| 136 | + Instruction i = previous_instruction(fs); | |
| 137 | + if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) | |
| 138 | + return 1; | |
| 139 | + else return 0; | |
| 140 | +} | |
| 141 | + | |
| 142 | + | |
| 143 | +void luaK_setcallreturns (FuncState *fs, int nresults) { | |
| 144 | + if (luaK_lastisopen(fs)) { /* expression is an open function call? */ | |
| 145 | + SETARG_B(fs->f->code[fs->pc-1], nresults); /* set number of results */ | |
| 146 | + luaK_deltastack(fs, nresults); /* push results */ | |
| 147 | + } | |
| 148 | +} | |
| 149 | + | |
| 150 | + | |
| 151 | +static int discharge (FuncState *fs, expdesc *var) { | |
| 152 | + switch (var->k) { | |
| 153 | + case VLOCAL: | |
| 154 | + luaK_code1(fs, OP_GETLOCAL, var->u.index); | |
| 155 | + break; | |
| 156 | + case VGLOBAL: | |
| 157 | + luaK_code1(fs, OP_GETGLOBAL, var->u.index); | |
| 158 | + break; | |
| 159 | + case VINDEXED: | |
| 160 | + luaK_code0(fs, OP_GETTABLE); | |
| 161 | + break; | |
| 162 | + case VEXP: | |
| 163 | + return 0; /* nothing to do */ | |
| 164 | + } | |
| 165 | + var->k = VEXP; | |
| 166 | + var->u.l.t = var->u.l.f = NO_JUMP; | |
| 167 | + return 1; | |
| 168 | +} | |
| 169 | + | |
| 170 | + | |
| 171 | +static void discharge1 (FuncState *fs, expdesc *var) { | |
| 172 | + discharge(fs, var); | |
| 173 | + /* if it has jumps then it is already discharged */ | |
| 174 | + if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP) | |
| 175 | + luaK_setcallreturns(fs, 1); /* call must return 1 value */ | |
| 176 | +} | |
| 177 | + | |
| 178 | + | |
| 179 | +void luaK_storevar (LexState *ls, const expdesc *var) { | |
| 180 | + FuncState *fs = ls->fs; | |
| 181 | + switch (var->k) { | |
| 182 | + case VLOCAL: | |
| 183 | + luaK_code1(fs, OP_SETLOCAL, var->u.index); | |
| 184 | + break; | |
| 185 | + case VGLOBAL: | |
| 186 | + luaK_code1(fs, OP_SETGLOBAL, var->u.index); | |
| 187 | + break; | |
| 188 | + case VINDEXED: /* table is at top-3; pop 3 elements after operation */ | |
| 189 | + luaK_code2(fs, OP_SETTABLE, 3, 3); | |
| 190 | + break; | |
| 191 | + default: | |
| 192 | + LUA_INTERNALERROR("invalid var kind to store"); | |
| 193 | + } | |
| 194 | +} | |
| 195 | + | |
| 196 | + | |
| 197 | +static OpCode invertjump (OpCode op) { | |
| 198 | + switch (op) { | |
| 199 | + case OP_JMPNE: return OP_JMPEQ; | |
| 200 | + case OP_JMPEQ: return OP_JMPNE; | |
| 201 | + case OP_JMPLT: return OP_JMPGE; | |
| 202 | + case OP_JMPLE: return OP_JMPGT; | |
| 203 | + case OP_JMPGT: return OP_JMPLE; | |
| 204 | + case OP_JMPGE: return OP_JMPLT; | |
| 205 | + case OP_JMPT: case OP_JMPONT: return OP_JMPF; | |
| 206 | + case OP_JMPF: case OP_JMPONF: return OP_JMPT; | |
| 207 | + default: | |
| 208 | + LUA_INTERNALERROR("invalid jump instruction"); | |
| 209 | + return OP_END; /* to avoid warnings */ | |
| 210 | + } | |
| 211 | +} | |
| 212 | + | |
| 213 | + | |
| 214 | +static void luaK_patchlistaux (FuncState *fs, int list, int target, | |
| 215 | + OpCode special, int special_target) { | |
| 216 | + Instruction *code = fs->f->code; | |
| 217 | + while (list != NO_JUMP) { | |
| 218 | + int next = luaK_getjump(fs, list); | |
| 219 | + Instruction *i = &code[list]; | |
| 220 | + OpCode op = GET_OPCODE(*i); | |
| 221 | + if (op == special) /* this `op' already has a value */ | |
| 222 | + luaK_fixjump(fs, list, special_target); | |
| 223 | + else { | |
| 224 | + luaK_fixjump(fs, list, target); /* do the patch */ | |
| 225 | + if (op == OP_JMPONT) /* remove eventual values */ | |
| 226 | + SET_OPCODE(*i, OP_JMPT); | |
| 227 | + else if (op == OP_JMPONF) | |
| 228 | + SET_OPCODE(*i, OP_JMPF); | |
| 229 | + } | |
| 230 | + list = next; | |
| 231 | + } | |
| 232 | +} | |
| 233 | + | |
| 234 | + | |
| 235 | +void luaK_patchlist (FuncState *fs, int list, int target) { | |
| 236 | + if (target == fs->lasttarget) /* same target that list `jlt'? */ | |
| 237 | + luaK_concat(fs, &fs->jlt, list); /* delay fixing */ | |
| 238 | + else | |
| 239 | + luaK_patchlistaux(fs, list, target, OP_END, 0); | |
| 240 | +} | |
| 241 | + | |
| 242 | + | |
| 243 | +static int need_value (FuncState *fs, int list, OpCode hasvalue) { | |
| 244 | + /* check whether list has a jump without a value */ | |
| 245 | + for (; list != NO_JUMP; list = luaK_getjump(fs, list)) | |
| 246 | + if (GET_OPCODE(fs->f->code[list]) != hasvalue) return 1; | |
| 247 | + return 0; /* not found */ | |
| 248 | +} | |
| 249 | + | |
| 250 | + | |
| 251 | +void luaK_concat (FuncState *fs, int *l1, int l2) { | |
| 252 | + if (*l1 == NO_JUMP) | |
| 253 | + *l1 = l2; | |
| 254 | + else { | |
| 255 | + int list = *l1; | |
| 256 | + for (;;) { /* traverse `l1' */ | |
| 257 | + int next = luaK_getjump(fs, list); | |
| 258 | + if (next == NO_JUMP) { /* end of list? */ | |
| 259 | + luaK_fixjump(fs, list, l2); | |
| 260 | + return; | |
| 261 | + } | |
| 262 | + list = next; | |
| 263 | + } | |
| 264 | + } | |
| 265 | +} | |
| 266 | + | |
| 267 | + | |
| 268 | +static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) { | |
| 269 | + int prevpos; /* position of last instruction */ | |
| 270 | + Instruction *previous; | |
| 271 | + int *golist, *exitlist; | |
| 272 | + if (!invert) { | |
| 273 | + golist = &v->u.l.f; /* go if false */ | |
| 274 | + exitlist = &v->u.l.t; /* exit if true */ | |
| 275 | + } | |
| 276 | + else { | |
| 277 | + golist = &v->u.l.t; /* go if true */ | |
| 278 | + exitlist = &v->u.l.f; /* exit if false */ | |
| 279 | + } | |
| 280 | + discharge1(fs, v); | |
| 281 | + prevpos = fs->pc-1; | |
| 282 | + previous = &fs->f->code[prevpos]; | |
| 283 | + LUA_ASSERT(*previous==previous_instruction(fs), "no jump allowed here"); | |
| 284 | + if (!ISJUMP(GET_OPCODE(*previous))) | |
| 285 | + prevpos = luaK_code1(fs, jump, NO_JUMP); | |
| 286 | + else { /* last instruction is already a jump */ | |
| 287 | + if (invert) | |
| 288 | + SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); | |
| 289 | + } | |
| 290 | + luaK_concat(fs, exitlist, prevpos); /* insert last jump in `exitlist' */ | |
| 291 | + luaK_patchlist(fs, *golist, luaK_getlabel(fs)); | |
| 292 | + *golist = NO_JUMP; | |
| 293 | +} | |
| 294 | + | |
| 295 | + | |
| 296 | +void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) { | |
| 297 | + luaK_testgo(fs, v, 1, keepvalue ? OP_JMPONF : OP_JMPF); | |
| 298 | +} | |
| 299 | + | |
| 300 | + | |
| 301 | +static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) { | |
| 302 | + luaK_testgo(fs, v, 0, keepvalue ? OP_JMPONT : OP_JMPT); | |
| 303 | +} | |
| 304 | + | |
| 305 | + | |
| 306 | +static int code_label (FuncState *fs, OpCode op, int arg) { | |
| 307 | + luaK_getlabel(fs); /* those instructions may be jump targets */ | |
| 308 | + return luaK_code1(fs, op, arg); | |
| 309 | +} | |
| 310 | + | |
| 311 | + | |
| 312 | +void luaK_tostack (LexState *ls, expdesc *v, int onlyone) { | |
| 313 | + FuncState *fs = ls->fs; | |
| 314 | + if (!discharge(fs, v)) { /* `v' is an expression? */ | |
| 315 | + OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]); | |
| 316 | + if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) { | |
| 317 | + /* expression has no jumps */ | |
| 318 | + if (onlyone) | |
| 319 | + luaK_setcallreturns(fs, 1); /* call must return 1 value */ | |
| 320 | + } | |
| 321 | + else { /* expression has jumps */ | |
| 322 | + int final; /* position after whole expression */ | |
| 323 | + int j = NO_JUMP; /* eventual jump over values */ | |
| 324 | + int p_nil = NO_JUMP; /* position of an eventual PUSHNIL */ | |
| 325 | + int p_1 = NO_JUMP; /* position of an eventual PUSHINT */ | |
| 326 | + if (ISJUMP(previous) || need_value(fs, v->u.l.f, OP_JMPONF) | |
| 327 | + || need_value(fs, v->u.l.t, OP_JMPONT)) { | |
| 328 | + /* expression needs values */ | |
| 329 | + if (ISJUMP(previous)) | |
| 330 | + luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */ | |
| 331 | + else { | |
| 332 | + j = code_label(fs, OP_JMP, NO_JUMP); /* to jump over both pushes */ | |
| 333 | + /* correct stack for compiler and symbolic execution */ | |
| 334 | + luaK_adjuststack(fs, 1); | |
| 335 | + } | |
| 336 | + p_nil = code_label(fs, OP_PUSHNILJMP, 0); | |
| 337 | + p_1 = code_label(fs, OP_PUSHINT, 1); | |
| 338 | + luaK_patchlist(fs, j, luaK_getlabel(fs)); | |
| 339 | + } | |
| 340 | + final = luaK_getlabel(fs); | |
| 341 | + luaK_patchlistaux(fs, v->u.l.f, p_nil, OP_JMPONF, final); | |
| 342 | + luaK_patchlistaux(fs, v->u.l.t, p_1, OP_JMPONT, final); | |
| 343 | + v->u.l.f = v->u.l.t = NO_JUMP; | |
| 344 | + } | |
| 345 | + } | |
| 346 | +} | |
| 347 | + | |
| 348 | + | |
| 349 | +void luaK_prefix (LexState *ls, UnOpr op, expdesc *v) { | |
| 350 | + FuncState *fs = ls->fs; | |
| 351 | + if (op == OPR_MINUS) { | |
| 352 | + luaK_tostack(ls, v, 1); | |
| 353 | + luaK_code0(fs, OP_MINUS); | |
| 354 | + } | |
| 355 | + else { /* op == NOT */ | |
| 356 | + Instruction *previous; | |
| 357 | + discharge1(fs, v); | |
| 358 | + previous = &fs->f->code[fs->pc-1]; | |
| 359 | + if (ISJUMP(GET_OPCODE(*previous))) | |
| 360 | + SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); | |
| 361 | + else | |
| 362 | + luaK_code0(fs, OP_NOT); | |
| 363 | + /* interchange true and false lists */ | |
| 364 | + { int temp = v->u.l.f; v->u.l.f = v->u.l.t; v->u.l.t = temp; } | |
| 365 | + } | |
| 366 | +} | |
| 367 | + | |
| 368 | + | |
| 369 | +void luaK_infix (LexState *ls, BinOpr op, expdesc *v) { | |
| 370 | + FuncState *fs = ls->fs; | |
| 371 | + switch (op) { | |
| 372 | + case OPR_AND: | |
| 373 | + luaK_goiftrue(fs, v, 1); | |
| 374 | + break; | |
| 375 | + case OPR_OR: | |
| 376 | + luaK_goiffalse(fs, v, 1); | |
| 377 | + break; | |
| 378 | + default: | |
| 379 | + luaK_tostack(ls, v, 1); /* all other binary operators need a value */ | |
| 380 | + } | |
| 381 | +} | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | +static const struct { | |
| 386 | + OpCode opcode; /* opcode for each binary operator */ | |
| 387 | + int arg; /* default argument for the opcode */ | |
| 388 | +} codes[] = { /* ORDER OPR */ | |
| 389 | + {OP_ADD, 0}, {OP_SUB, 0}, {OP_MULT, 0}, {OP_DIV, 0}, | |
| 390 | + {OP_POW, 0}, {OP_CONCAT, 2}, | |
| 391 | + {OP_JMPNE, NO_JUMP}, {OP_JMPEQ, NO_JUMP}, | |
| 392 | + {OP_JMPLT, NO_JUMP}, {OP_JMPLE, NO_JUMP}, | |
| 393 | + {OP_JMPGT, NO_JUMP}, {OP_JMPGE, NO_JUMP} | |
| 394 | +}; | |
| 395 | + | |
| 396 | + | |
| 397 | +void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2) { | |
| 398 | + FuncState *fs = ls->fs; | |
| 399 | + switch (op) { | |
| 400 | + case OPR_AND: { | |
| 401 | + LUA_ASSERT(v1->u.l.t == NO_JUMP, "list must be closed"); | |
| 402 | + discharge1(fs, v2); | |
| 403 | + v1->u.l.t = v2->u.l.t; | |
| 404 | + luaK_concat(fs, &v1->u.l.f, v2->u.l.f); | |
| 405 | + break; | |
| 406 | + } | |
| 407 | + case OPR_OR: { | |
| 408 | + LUA_ASSERT(v1->u.l.f == NO_JUMP, "list must be closed"); | |
| 409 | + discharge1(fs, v2); | |
| 410 | + v1->u.l.f = v2->u.l.f; | |
| 411 | + luaK_concat(fs, &v1->u.l.t, v2->u.l.t); | |
| 412 | + break; | |
| 413 | + } | |
| 414 | + default: { | |
| 415 | + luaK_tostack(ls, v2, 1); /* `v2' must be a value */ | |
| 416 | + luaK_code1(fs, codes[op].opcode, codes[op].arg); | |
| 417 | + } | |
| 418 | + } | |
| 419 | +} | |
| 420 | + | |
| 421 | + | |
| 422 | +static void codelineinfo (FuncState *fs) { | |
| 423 | + Proto *f = fs->f; | |
| 424 | + LexState *ls = fs->ls; | |
| 425 | + if (ls->lastline > fs->lastline) { | |
| 426 | + luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, 2, int, | |
| 427 | + "line info overflow", MAX_INT); | |
| 428 | + if (ls->lastline > fs->lastline+1) | |
| 429 | + f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1)); | |
| 430 | + f->lineinfo[f->nlineinfo++] = fs->pc; | |
| 431 | + fs->lastline = ls->lastline; | |
| 432 | + } | |
| 433 | +} | |
| 434 | + | |
| 435 | + | |
| 436 | +int luaK_code0 (FuncState *fs, OpCode o) { | |
| 437 | + return luaK_code2(fs, o, 0, 0); | |
| 438 | +} | |
| 439 | + | |
| 440 | + | |
| 441 | +int luaK_code1 (FuncState *fs, OpCode o, int arg1) { | |
| 442 | + return luaK_code2(fs, o, arg1, 0); | |
| 443 | +} | |
| 444 | + | |
| 445 | + | |
| 446 | +int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |
| 447 | + Instruction i = previous_instruction(fs); | |
| 448 | + int delta = luaK_opproperties[o].push - luaK_opproperties[o].pop; | |
| 449 | + int optm = 0; /* 1 when there is an optimization */ | |
| 450 | + switch (o) { | |
| 451 | + case OP_CLOSURE: { | |
| 452 | + delta = -arg2+1; | |
| 453 | + break; | |
| 454 | + } | |
| 455 | + case OP_SETTABLE: { | |
| 456 | + delta = -arg2; | |
| 457 | + break; | |
| 458 | + } | |
| 459 | + case OP_SETLIST: { | |
| 460 | + if (arg2 == 0) return NO_JUMP; /* nothing to do */ | |
| 461 | + delta = -arg2; | |
| 462 | + break; | |
| 463 | + } | |
| 464 | + case OP_SETMAP: { | |
| 465 | + if (arg1 == 0) return NO_JUMP; /* nothing to do */ | |
| 466 | + delta = -2*arg1; | |
| 467 | + break; | |
| 468 | + } | |
| 469 | + case OP_RETURN: { | |
| 470 | + if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) { | |
| 471 | + SET_OPCODE(i, OP_TAILCALL); | |
| 472 | + SETARG_B(i, arg1); | |
| 473 | + optm = 1; | |
| 474 | + } | |
| 475 | + break; | |
| 476 | + } | |
| 477 | + case OP_PUSHNIL: { | |
| 478 | + if (arg1 == 0) return NO_JUMP; /* nothing to do */ | |
| 479 | + delta = arg1; | |
| 480 | + switch(GET_OPCODE(i)) { | |
| 481 | + case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; | |
| 482 | + default: break; | |
| 483 | + } | |
| 484 | + break; | |
| 485 | + } | |
| 486 | + case OP_POP: { | |
| 487 | + if (arg1 == 0) return NO_JUMP; /* nothing to do */ | |
| 488 | + delta = -arg1; | |
| 489 | + switch(GET_OPCODE(i)) { | |
| 490 | + case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; | |
| 491 | + default: break; | |
| 492 | + } | |
| 493 | + break; | |
| 494 | + } | |
| 495 | + case OP_GETTABLE: { | |
| 496 | + switch(GET_OPCODE(i)) { | |
| 497 | + case OP_PUSHSTRING: /* `t.x' */ | |
| 498 | + SET_OPCODE(i, OP_GETDOTTED); | |
| 499 | + optm = 1; | |
| 500 | + break; | |
| 501 | + case OP_GETLOCAL: /* `t[i]' */ | |
| 502 | + SET_OPCODE(i, OP_GETINDEXED); | |
| 503 | + optm = 1; | |
| 504 | + break; | |
| 505 | + default: break; | |
| 506 | + } | |
| 507 | + break; | |
| 508 | + } | |
| 509 | + case OP_ADD: { | |
| 510 | + switch(GET_OPCODE(i)) { | |
| 511 | + case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); optm = 1; break; /* `a+k' */ | |
| 512 | + default: break; | |
| 513 | + } | |
| 514 | + break; | |
| 515 | + } | |
| 516 | + case OP_SUB: { | |
| 517 | + switch(GET_OPCODE(i)) { | |
| 518 | + case OP_PUSHINT: /* `a-k' */ | |
| 519 | + i = CREATE_S(OP_ADDI, -GETARG_S(i)); | |
| 520 | + optm = 1; | |
| 521 | + break; | |
| 522 | + default: break; | |
| 523 | + } | |
| 524 | + break; | |
| 525 | + } | |
| 526 | + case OP_CONCAT: { | |
| 527 | + delta = -arg1+1; | |
| 528 | + switch(GET_OPCODE(i)) { | |
| 529 | + case OP_CONCAT: /* `a..b..c' */ | |
| 530 | + SETARG_U(i, GETARG_U(i)+1); | |
| 531 | + optm = 1; | |
| 532 | + break; | |
| 533 | + default: break; | |
| 534 | + } | |
| 535 | + break; | |
| 536 | + } | |
| 537 | + case OP_MINUS: { | |
| 538 | + switch(GET_OPCODE(i)) { | |
| 539 | + case OP_PUSHINT: /* `-k' */ | |
| 540 | + SETARG_S(i, -GETARG_S(i)); | |
| 541 | + optm = 1; | |
| 542 | + break; | |
| 543 | + case OP_PUSHNUM: /* `-k' */ | |
| 544 | + SET_OPCODE(i, OP_PUSHNEGNUM); | |
| 545 | + optm = 1; | |
| 546 | + break; | |
| 547 | + default: break; | |
| 548 | + } | |
| 549 | + break; | |
| 550 | + } | |
| 551 | + case OP_JMPNE: { | |
| 552 | + if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a~=nil' */ | |
| 553 | + i = CREATE_S(OP_JMPT, NO_JUMP); | |
| 554 | + optm = 1; | |
| 555 | + } | |
| 556 | + break; | |
| 557 | + } | |
| 558 | + case OP_JMPEQ: { | |
| 559 | + if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */ | |
| 560 | + i = CREATE_0(OP_NOT); | |
| 561 | + delta = -1; /* just undo effect of previous PUSHNIL */ | |
| 562 | + optm = 1; | |
| 563 | + } | |
| 564 | + break; | |
| 565 | + } | |
| 566 | + case OP_JMPT: | |
| 567 | + case OP_JMPONT: { | |
| 568 | + switch (GET_OPCODE(i)) { | |
| 569 | + case OP_NOT: { | |
| 570 | + i = CREATE_S(OP_JMPF, NO_JUMP); | |
| 571 | + optm = 1; | |
| 572 | + break; | |
| 573 | + } | |
| 574 | + case OP_PUSHINT: { | |
| 575 | + if (o == OP_JMPT) { /* JMPONT must keep original integer value */ | |
| 576 | + i = CREATE_S(OP_JMP, NO_JUMP); | |
| 577 | + optm = 1; | |
| 578 | + } | |
| 579 | + break; | |
| 580 | + } | |
| 581 | + case OP_PUSHNIL: { | |
| 582 | + if (GETARG_U(i) == 1) { | |
| 583 | + fs->pc--; /* erase previous instruction */ | |
| 584 | + luaK_deltastack(fs, -1); /* correct stack */ | |
| 585 | + return NO_JUMP; | |
| 586 | + } | |
| 587 | + break; | |
| 588 | + } | |
| 589 | + default: break; | |
| 590 | + } | |
| 591 | + break; | |
| 592 | + } | |
| 593 | + case OP_JMPF: | |
| 594 | + case OP_JMPONF: { | |
| 595 | + switch (GET_OPCODE(i)) { | |
| 596 | + case OP_NOT: { | |
| 597 | + i = CREATE_S(OP_JMPT, NO_JUMP); | |
| 598 | + optm = 1; | |
| 599 | + break; | |
| 600 | + } | |
| 601 | + case OP_PUSHINT: { /* `while 1 do ...' */ | |
| 602 | + fs->pc--; /* erase previous instruction */ | |
| 603 | + luaK_deltastack(fs, -1); /* correct stack */ | |
| 604 | + return NO_JUMP; | |
| 605 | + } | |
| 606 | + case OP_PUSHNIL: { /* `repeat ... until nil' */ | |
| 607 | + if (GETARG_U(i) == 1) { | |
| 608 | + i = CREATE_S(OP_JMP, NO_JUMP); | |
| 609 | + optm = 1; | |
| 610 | + } | |
| 611 | + break; | |
| 612 | + } | |
| 613 | + default: break; | |
| 614 | + } | |
| 615 | + break; | |
| 616 | + } | |
| 617 | + case OP_GETDOTTED: | |
| 618 | + case OP_GETINDEXED: | |
| 619 | + case OP_TAILCALL: | |
| 620 | + case OP_ADDI: { | |
| 621 | + LUA_INTERNALERROR("instruction used only for optimizations"); | |
| 622 | + break; | |
| 623 | + } | |
| 624 | + default: { | |
| 625 | + LUA_ASSERT(delta != VD, "invalid delta"); | |
| 626 | + break; | |
| 627 | + } | |
| 628 | + } | |
| 629 | + luaK_deltastack(fs, delta); | |
| 630 | + if (optm) { /* optimize: put instruction in place of last one */ | |
| 631 | + fs->f->code[fs->pc-1] = i; /* change previous instruction */ | |
| 632 | + return fs->pc-1; /* do not generate new instruction */ | |
| 633 | + } | |
| 634 | + /* else build new instruction */ | |
| 635 | + switch ((enum Mode)luaK_opproperties[o].mode) { | |
| 636 | + case iO: i = CREATE_0(o); break; | |
| 637 | + case iU: i = CREATE_U(o, arg1); break; | |
| 638 | + case iS: i = CREATE_S(o, arg1); break; | |
| 639 | + case iAB: i = CREATE_AB(o, arg1, arg2); break; | |
| 640 | + } | |
| 641 | + codelineinfo(fs); | |
| 642 | + /* put new instruction in code array */ | |
| 643 | + luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, | |
| 644 | + "code size overflow", MAX_INT); | |
| 645 | + fs->f->code[fs->pc] = i; | |
| 646 | + return fs->pc++; | |
| 647 | +} | |
| 648 | + | |
| 649 | + | |
| 650 | +const struct OpProperties luaK_opproperties[NUM_OPCODES] = { | |
| 651 | + {iO, 0, 0}, /* OP_END */ | |
| 652 | + {iU, 0, 0}, /* OP_RETURN */ | |
| 653 | + {iAB, 0, 0}, /* OP_CALL */ | |
| 654 | + {iAB, 0, 0}, /* OP_TAILCALL */ | |
| 655 | + {iU, VD, 0}, /* OP_PUSHNIL */ | |
| 656 | + {iU, VD, 0}, /* OP_POP */ | |
| 657 | + {iS, 1, 0}, /* OP_PUSHINT */ | |
| 658 | + {iU, 1, 0}, /* OP_PUSHSTRING */ | |
| 659 | + {iU, 1, 0}, /* OP_PUSHNUM */ | |
| 660 | + {iU, 1, 0}, /* OP_PUSHNEGNUM */ | |
| 661 | + {iU, 1, 0}, /* OP_PUSHUPVALUE */ | |
| 662 | + {iU, 1, 0}, /* OP_GETLOCAL */ | |
| 663 | + {iU, 1, 0}, /* OP_GETGLOBAL */ | |
| 664 | + {iO, 1, 2}, /* OP_GETTABLE */ | |
| 665 | + {iU, 1, 1}, /* OP_GETDOTTED */ | |
| 666 | + {iU, 1, 1}, /* OP_GETINDEXED */ | |
| 667 | + {iU, 2, 1}, /* OP_PUSHSELF */ | |
| 668 | + {iU, 1, 0}, /* OP_CREATETABLE */ | |
| 669 | + {iU, 0, 1}, /* OP_SETLOCAL */ | |
| 670 | + {iU, 0, 1}, /* OP_SETGLOBAL */ | |
| 671 | + {iAB, VD, 0}, /* OP_SETTABLE */ | |
| 672 | + {iAB, VD, 0}, /* OP_SETLIST */ | |
| 673 | + {iU, VD, 0}, /* OP_SETMAP */ | |
| 674 | + {iO, 1, 2}, /* OP_ADD */ | |
| 675 | + {iS, 1, 1}, /* OP_ADDI */ | |
| 676 | + {iO, 1, 2}, /* OP_SUB */ | |
| 677 | + {iO, 1, 2}, /* OP_MULT */ | |
| 678 | + {iO, 1, 2}, /* OP_DIV */ | |
| 679 | + {iO, 1, 2}, /* OP_POW */ | |
| 680 | + {iU, VD, 0}, /* OP_CONCAT */ | |
| 681 | + {iO, 1, 1}, /* OP_MINUS */ | |
| 682 | + {iO, 1, 1}, /* OP_NOT */ | |
| 683 | + {iS, 0, 2}, /* OP_JMPNE */ | |
| 684 | + {iS, 0, 2}, /* OP_JMPEQ */ | |
| 685 | + {iS, 0, 2}, /* OP_JMPLT */ | |
| 686 | + {iS, 0, 2}, /* OP_JMPLE */ | |
| 687 | + {iS, 0, 2}, /* OP_JMPGT */ | |
| 688 | + {iS, 0, 2}, /* OP_JMPGE */ | |
| 689 | + {iS, 0, 1}, /* OP_JMPT */ | |
| 690 | + {iS, 0, 1}, /* OP_JMPF */ | |
| 691 | + {iS, 0, 1}, /* OP_JMPONT */ | |
| 692 | + {iS, 0, 1}, /* OP_JMPONF */ | |
| 693 | + {iS, 0, 0}, /* OP_JMP */ | |
| 694 | + {iO, 0, 0}, /* OP_PUSHNILJMP */ | |
| 695 | + {iS, 0, 0}, /* OP_FORPREP */ | |
| 696 | + {iS, 0, 3}, /* OP_FORLOOP */ | |
| 697 | + {iS, 2, 0}, /* OP_LFORPREP */ | |
| 698 | + {iS, 0, 3}, /* OP_LFORLOOP */ | |
| 699 | + {iAB, VD, 0} /* OP_CLOSURE */ | |
| 700 | +}; | |
| 701 | + | |
| @@ -0,0 +1,70 @@ | ||
| 1 | +/* | |
| 2 | +** $Id: lcode.h,v 1.16 2000/08/09 14:49:13 roberto Exp $ | |
| 3 | +** Code generator for Lua | |
| 4 | +** See Copyright Notice in lua.h | |
| 5 | +*/ | |
| 6 | + | |
| 7 | +#ifndef lcode_h | |
| 8 | +#define lcode_h | |
| 9 | + | |
| 10 | +#include "llex.h" | |
| 11 | +#include "lobject.h" | |
| 12 | +#include "lopcodes.h" | |
| 13 | +#include "lparser.h" | |
| 14 | + | |
| 15 | + | |
| 16 | +/* | |
| 17 | +** Marks the end of a patch list. It is an invalid value both as an absolute | |
| 18 | +** address, and as a list link (would link an element to itself). | |
| 19 | +*/ | |
| 20 | +#define NO_JUMP (-1) | |
| 21 | + | |
| 22 | + | |
| 23 | +/* | |
| 24 | +** grep "ORDER OPR" if you change these enums | |
| 25 | +*/ | |
| 26 | +typedef enum BinOpr { | |
| 27 | + OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW, | |
| 28 | + OPR_CONCAT, | |
| 29 | + OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE, | |
| 30 | + OPR_AND, OPR_OR, | |
| 31 | + OPR_NOBINOPR | |
| 32 | +} BinOpr; | |
| 33 | + | |
| 34 | +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr; | |
| 35 | + | |
| 36 | + | |
| 37 | +enum Mode {iO, iU, iS, iAB}; /* instruction format */ | |
| 38 | + | |
| 39 | +#define VD 100 /* flag for variable delta */ | |
| 40 | + | |
| 41 | +extern const struct OpProperties { | |
| 42 | + char mode; | |
| 43 | + unsigned char push; | |
| 44 | + unsigned char pop; | |
| 45 | +} luaK_opproperties[]; | |
| 46 | + | |
| 47 | + | |
| 48 | +void luaK_error (LexState *ls, const char *msg); | |
| 49 | +int luaK_code0 (FuncState *fs, OpCode o); | |
| 50 | +int luaK_code1 (FuncState *fs, OpCode o, int arg1); | |
| 51 | +int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2); | |
| 52 | +int luaK_jump (FuncState *fs); | |
| 53 | +void luaK_patchlist (FuncState *fs, int list, int target); | |
| 54 | +void luaK_concat (FuncState *fs, int *l1, int l2); | |
| 55 | +void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue); | |
| 56 | +int luaK_getlabel (FuncState *fs); | |
| 57 | +void luaK_deltastack (FuncState *fs, int delta); | |
| 58 | +void luaK_kstr (LexState *ls, int c); | |
| 59 | +void luaK_number (FuncState *fs, Number f); | |
| 60 | +void luaK_adjuststack (FuncState *fs, int n); | |
| 61 | +int luaK_lastisopen (FuncState *fs); | |
| 62 | +void luaK_setcallreturns (FuncState *fs, int nresults); | |
| 63 | +void luaK_tostack (LexState *ls, expdesc *v, int onlyone); | |
| 64 | +void luaK_storevar (LexState *ls, const expdesc *var); | |
| 65 | +void luaK_prefix (LexState *ls, UnOpr op, expdesc *v); | |
| 66 | +void luaK_infix (LexState *ls, BinOpr op, expdesc *v); | |
| 67 | +void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2); | |
| 68 | + | |
| 69 | + | |
| 70 | +#endif | |
| @@ -0,0 +1,466 @@ | ||
| 1 | +/* | |
| 2 | +** $Id: ldebug.c,v 1.50 2000/10/30 12:38:50 roberto Exp $ | |
| 3 | +** Debug Interface | |
| 4 | +** See Copyright Notice in lua.h | |
| 5 | +*/ | |
| 6 | + | |
| 7 | + | |
| 8 | +#include <stdlib.h> | |
| 9 | + | |
| 10 | +#include "lua.h" | |
| 11 | + | |
| 12 | +#include "lapi.h" | |
| 13 | +#include "lcode.h" | |
| 14 | +#include "ldebug.h" | |
| 15 | +#include "ldo.h" | |
| 16 | +#include "lfunc.h" | |
| 17 | +#include "lobject.h" | |
| 18 | +#include "lopcodes.h" | |
| 19 | +#include "lstate.h" | |
| 20 | +#include "lstring.h" | |
| 21 | +#include "ltable.h" | |
| 22 | +#include "ltm.h" | |
| 23 | +#include "luadebug.h" | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | +static const char *getfuncname (lua_State *L, StkId f, const char **name); | |
| 28 | + | |
| 29 | + | |
| 30 | +static void setnormalized (TObject *d, const TObject *s) { | |
| 31 | + if (ttype(s) == LUA_TMARK) { | |
| 32 | + clvalue(d) = infovalue(s)->func; | |
| 33 | + ttype(d) = LUA_TFUNCTION; | |
| 34 | + } | |
| 35 | + else *d = *s; | |
| 36 | +} | |
| 37 | + | |
| 38 | + | |
| 39 | +static int isLmark (StkId o) { | |
| 40 | + return (o && ttype(o) == LUA_TMARK && !infovalue(o)->func->isC); | |
| 41 | +} | |
| 42 | + | |
| 43 | + | |
| 44 | +LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) { | |
| 45 | + lua_Hook oldhook = L->callhook; | |
| 46 | + L->callhook = func; | |
| 47 | + return oldhook; | |
| 48 | +} | |
| 49 | + | |
| 50 | + | |
| 51 | +LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) { | |
| 52 | + lua_Hook oldhook = L->linehook; | |
| 53 | + L->linehook = func; | |
| 54 | + return oldhook; | |
| 55 | +} | |
| 56 | + | |
| 57 | + | |
| 58 | +static StkId aux_stackedfunction (lua_State *L, int level, StkId top) { | |
| 59 | + int i; | |
| 60 | + for (i = (top-1) - L->stack; i>=0; i--) { | |
| 61 | + if (is_T_MARK(L->stack[i].ttype)) { | |
| 62 | + if (level == 0) | |
| 63 | + return L->stack+i; | |
| 64 | + level--; | |
| 65 | + } | |
| 66 | + } | |
| 67 | + return NULL; | |
| 68 | +} | |
| 69 | + | |
| 70 | + | |
| 71 | +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { | |
| 72 | + StkId f = aux_stackedfunction(L, level, L->top); | |
| 73 | + if (f == NULL) return 0; /* there is no such level */ | |
| 74 | + else { | |
| 75 | + ar->_func = f; | |
| 76 | + return 1; | |
| 77 | + } | |
| 78 | +} | |
| 79 | + | |
| 80 | + | |
| 81 | +static int nups (StkId f) { | |
| 82 | + switch (ttype(f)) { | |
| 83 | + case LUA_TFUNCTION: | |
| 84 | + return clvalue(f)->nupvalues; | |
| 85 | + case LUA_TMARK: | |
| 86 | + return infovalue(f)->func->nupvalues; | |
| 87 | + default: | |
| 88 | + return 0; | |
| 89 | + } | |
| 90 | +} | |
| 91 | + | |
| 92 | + | |
| 93 | +int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { | |
| 94 | + int refi; | |
| 95 | + if (lineinfo == NULL || pc == -1) | |
| 96 | + return -1; /* no line info or function is not active */ | |
| 97 | + refi = prefi ? *prefi : 0; | |
| 98 | + if (lineinfo[refi] < 0) | |
| 99 | + refline += -lineinfo[refi++]; | |
| 100 | + LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info"); | |
| 101 | + while (lineinfo[refi] > pc) { | |
| 102 | + refline--; | |
| 103 | + refi--; | |
| 104 | + if (lineinfo[refi] < 0) | |
| 105 | + refline -= -lineinfo[refi--]; | |
| 106 | + LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info"); | |
| 107 | + } | |
| 108 | + for (;;) { | |
| 109 | + int nextline = refline + 1; | |
| 110 | + int nextref = refi + 1; | |
| 111 | + if (lineinfo[nextref] < 0) | |
| 112 | + nextline += -lineinfo[nextref++]; | |
| 113 | + LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info"); | |
| 114 | + if (lineinfo[nextref] > pc) | |
| 115 | + break; | |
| 116 | + refline = nextline; | |
| 117 | + refi = nextref; | |
| 118 | + } | |
| 119 | + if (prefi) *prefi = refi; | |
| 120 | + return refline; | |
| 121 | +} | |
| 122 | + | |
| 123 | + | |
| 124 | +static int currentpc (StkId f) { | |
| 125 | + CallInfo *ci = infovalue(f); | |
| 126 | + LUA_ASSERT(isLmark(f), "function has no pc"); | |
| 127 | + if (ci->pc) | |
| 128 | + return (*ci->pc - ci->func->f.l->code) - 1; | |
| 129 | + else | |
| 130 | + return -1; /* function is not active */ | |
| 131 | +} | |
| 132 | + | |
| 133 | + | |
| 134 | +static int currentline (StkId f) { | |
| 135 | + if (!isLmark(f)) | |
| 136 | + return -1; /* only active lua functions have current-line information */ | |
| 137 | + else { | |
| 138 | + CallInfo *ci = infovalue(f); | |
| 139 | + int *lineinfo = ci->func->f.l->lineinfo; | |
| 140 | + return luaG_getline(lineinfo, currentpc(f), 1, NULL); | |
| 141 | + } | |
| 142 | +} | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | +static Proto *getluaproto (StkId f) { | |
| 147 | + return (isLmark(f) ? infovalue(f)->func->f.l : NULL); | |
| 148 | +} | |
| 149 | + | |
| 150 | + | |
| 151 | +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | |
| 152 | + const char *name; | |
| 153 | + StkId f = ar->_func; | |
| 154 | + Proto *fp = getluaproto(f); | |
| 155 | + if (!fp) return NULL; /* `f' is not a Lua function? */ | |
| 156 | + name = luaF_getlocalname(fp, n, currentpc(f)); | |
| 157 | + if (!name) return NULL; | |
| 158 | + luaA_pushobject(L, (f+1)+(n-1)); /* push value */ | |
| 159 | + return name; | |
| 160 | +} | |
| 161 | + | |
| 162 | + | |
| 163 | +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | |
| 164 | + const char *name; | |
| 165 | + StkId f = ar->_func; | |
| 166 | + Proto *fp = getluaproto(f); | |
| 167 | + L->top--; /* pop new value */ | |
| 168 | + if (!fp) return NULL; /* `f' is not a Lua function? */ | |
| 169 | + name = luaF_getlocalname(fp, n, currentpc(f)); | |
| 170 | + if (!name || name[0] == '(') return NULL; /* `(' starts private locals */ | |
| 171 | + *((f+1)+(n-1)) = *L->top; | |
| 172 | + return name; | |
| 173 | +} | |
| 174 | + | |
| 175 | + | |
| 176 | +static void infoLproto (lua_Debug *ar, Proto *f) { | |
| 177 | + ar->source = f->source->str; | |
| 178 | + ar->linedefined = f->lineDefined; | |
| 179 | + ar->what = "Lua"; | |
| 180 | +} | |
| 181 | + | |
| 182 | + | |
| 183 | +static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) { | |
| 184 | + Closure *cl = NULL; | |
| 185 | + switch (ttype(func)) { | |
| 186 | + case LUA_TFUNCTION: | |
| 187 | + cl = clvalue(func); | |
| 188 | + break; | |
| 189 | + case LUA_TMARK: | |
| 190 | + cl = infovalue(func)->func; | |
| 191 | + break; | |
| 192 | + default: | |
| 193 | + lua_error(L, "value for `lua_getinfo' is not a function"); | |
| 194 | + } | |
| 195 | + if (cl->isC) { | |
| 196 | + ar->source = "=C"; | |
| 197 | + ar->linedefined = -1; | |
| 198 | + ar->what = "C"; | |
| 199 | + } | |
| 200 | + else | |
| 201 | + infoLproto(ar, cl->f.l); | |
| 202 | + luaO_chunkid(ar->short_src, ar->source, sizeof(ar->short_src)); | |
| 203 | + if (ar->linedefined == 0) | |
| 204 | + ar->what = "main"; | |
| 205 | +} | |
| 206 | + | |
| 207 | + | |
| 208 | +static const char *travtagmethods (lua_State *L, const TObject *o) { | |
| 209 | + if (ttype(o) == LUA_TFUNCTION) { | |
| 210 | + int e; | |
| 211 | + for (e=0; e<TM_N; e++) { | |
| 212 | + int t; | |
| 213 | + for (t=0; t<=L->last_tag; t++) | |
| 214 | + if (clvalue(o) == luaT_gettm(L, t, e)) | |
| 215 | + return luaT_eventname[e]; | |
| 216 | + } | |
| 217 | + } | |
| 218 | + return NULL; | |
| 219 | +} | |
| 220 | + | |
| 221 | + | |
| 222 | +static const char *travglobals (lua_State *L, const TObject *o) { | |
| 223 | + Hash *g = L->gt; | |
| 224 | + int i; | |
| 225 | + for (i=0; i<g->size; i++) { | |
| 226 | + if (luaO_equalObj(o, val(node(g, i))) && | |
| 227 | + ttype(key(node(g, i))) == LUA_TSTRING) | |
| 228 | + return tsvalue(key(node(g, i)))->str; | |
| 229 | + } | |
| 230 | + return NULL; | |
| 231 | +} | |
| 232 | + | |
| 233 | + | |
| 234 | +static void getname (lua_State *L, StkId f, lua_Debug *ar) { | |
| 235 | + TObject o; | |
| 236 | + setnormalized(&o, f); | |
| 237 | + /* try to find a name for given function */ | |
| 238 | + if ((ar->name = travglobals(L, &o)) != NULL) | |
| 239 | + ar->namewhat = "global"; | |
| 240 | + /* not found: try tag methods */ | |
| 241 | + else if ((ar->name = travtagmethods(L, &o)) != NULL) | |
| 242 | + ar->namewhat = "tag-method"; | |
| 243 | + else ar->namewhat = ""; /* not found at all */ | |
| 244 | +} | |
| 245 | + | |
| 246 | + | |
| 247 | +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |
| 248 | + StkId func; | |
| 249 | + int isactive = (*what != '>'); | |
| 250 | + if (isactive) | |
| 251 | + func = ar->_func; | |
| 252 | + else { | |
| 253 | + what++; /* skip the '>' */ | |
| 254 | + func = L->top - 1; | |
| 255 | + } | |
| 256 | + for (; *what; what++) { | |
| 257 | + switch (*what) { | |
| 258 | + case 'S': { | |
| 259 | + funcinfo(L, ar, func); | |
| 260 | + break; | |
| 261 | + } | |
| 262 | + case 'l': { | |
| 263 | + ar->currentline = currentline(func); | |
| 264 | + break; | |
| 265 | + } | |
| 266 | + case 'u': { | |
| 267 | + ar->nups = nups(func); | |
| 268 | + break; | |
| 269 | + } | |
| 270 | + case 'n': { | |
| 271 | + ar->namewhat = (isactive) ? getfuncname(L, func, &ar->name) : NULL; | |
| 272 | + if (ar->namewhat == NULL) | |
| 273 | + getname(L, func, ar); | |
| 274 | + break; | |
| 275 | + } | |
| 276 | + case 'f': { | |
| 277 | + setnormalized(L->top, func); | |
| 278 | + incr_top; /* push function */ | |
| 279 | + break; | |
| 280 | + } | |
| 281 | + default: return 0; /* invalid option */ | |
| 282 | + } | |
| 283 | + } | |
| 284 | + if (!isactive) L->top--; /* pop function */ | |
| 285 | + return 1; | |
| 286 | +} | |
| 287 | + | |
| 288 | + | |
| 289 | +/* | |
| 290 | +** {====================================================== | |
| 291 | +** Symbolic Execution | |
| 292 | +** ======================================================= | |
| 293 | +*/ | |
| 294 | + | |
| 295 | + | |
| 296 | +static int pushpc (int *stack, int pc, int top, int n) { | |
| 297 | + while (n--) | |
| 298 | + stack[top++] = pc-1; | |
| 299 | + return top; | |
| 300 | +} | |
| 301 | + | |
| 302 | + | |
| 303 | +static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { | |
| 304 | + int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */ | |
| 305 | + const Instruction *code = pt->code; | |
| 306 | + int top = pt->numparams; | |
| 307 | + int pc = 0; | |
| 308 | + if (pt->is_vararg) /* varargs? */ | |
| 309 | + top++; /* `arg' */ | |
| 310 | + while (pc < lastpc) { | |
| 311 | + const Instruction i = code[pc++]; | |
| 312 | + LUA_ASSERT(0 <= top && top <= pt->maxstacksize, "wrong stack"); | |
| 313 | + switch (GET_OPCODE(i)) { | |
| 314 | + case OP_RETURN: { | |
| 315 | + LUA_ASSERT(top >= GETARG_U(i), "wrong stack"); | |
| 316 | + top = GETARG_U(i); | |
| 317 | + break; | |
| 318 | + } | |
| 319 | + case OP_TAILCALL: { | |
| 320 | + LUA_ASSERT(top >= GETARG_A(i), "wrong stack"); | |
| 321 | + top = GETARG_B(i); | |
| 322 | + break; | |
| 323 | + } | |
| 324 | + case OP_CALL: { | |
| 325 | + int nresults = GETARG_B(i); | |
| 326 | + if (nresults == MULT_RET) nresults = 1; | |
| 327 | + LUA_ASSERT(top >= GETARG_A(i), "wrong stack"); | |
| 328 | + top = pushpc(stack, pc, GETARG_A(i), nresults); | |
| 329 | + break; | |
| 330 | + } | |
| 331 | + case OP_PUSHNIL: { | |
| 332 | + top = pushpc(stack, pc, top, GETARG_U(i)); | |
| 333 | + break; | |
| 334 | + } | |
| 335 | + case OP_POP: { | |
| 336 | + top -= GETARG_U(i); | |
| 337 | + break; | |
| 338 | + } | |
| 339 | + case OP_SETTABLE: | |
| 340 | + case OP_SETLIST: { | |
| 341 | + top -= GETARG_B(i); | |
| 342 | + break; | |
| 343 | + } | |
| 344 | + case OP_SETMAP: { | |
| 345 | + top -= 2*GETARG_U(i); | |
| 346 | + break; | |
| 347 | + } | |
| 348 | + case OP_CONCAT: { | |
| 349 | + top -= GETARG_U(i); | |
| 350 | + stack[top++] = pc-1; | |
| 351 | + break; | |
| 352 | + } | |
| 353 | + case OP_CLOSURE: { | |
| 354 | + top -= GETARG_B(i); | |
| 355 | + stack[top++] = pc-1; | |
| 356 | + break; | |
| 357 | + } | |
| 358 | + case OP_JMPONT: | |
| 359 | + case OP_JMPONF: { | |
| 360 | + int newpc = pc + GETARG_S(i); | |
| 361 | + /* jump is forward and do not skip `lastpc'? */ | |
| 362 | + if (pc < newpc && newpc <= lastpc) { | |
| 363 | + stack[top-1] = pc-1; /* value comes from `and'/`or' */ | |
| 364 | + pc = newpc; /* do the jump */ | |
| 365 | + } | |
| 366 | + else | |
| 367 | + top--; /* do not jump; pop value */ | |
| 368 | + break; | |
| 369 | + } | |
| 370 | + default: { | |
| 371 | + OpCode op = GET_OPCODE(i); | |
| 372 | + LUA_ASSERT(luaK_opproperties[op].push != VD, | |
| 373 | + "invalid opcode for default"); | |
| 374 | + top -= luaK_opproperties[op].pop; | |
| 375 | + LUA_ASSERT(top >= 0, "wrong stack"); | |
| 376 | + top = pushpc(stack, pc, top, luaK_opproperties[op].push); | |
| 377 | + } | |
| 378 | + } | |
| 379 | + } | |
| 380 | + return code[stack[stackpos]]; | |
| 381 | +} | |
| 382 | + | |
| 383 | + | |
| 384 | +static const char *getobjname (lua_State *L, StkId obj, const char **name) { | |
| 385 | + StkId func = aux_stackedfunction(L, 0, obj); | |
| 386 | + if (!isLmark(func)) | |
| 387 | + return NULL; /* not an active Lua function */ | |
| 388 | + else { | |
| 389 | + Proto *p = infovalue(func)->func->f.l; | |
| 390 | + int pc = currentpc(func); | |
| 391 | + int stackpos = obj - (func+1); /* func+1 == function base */ | |
| 392 | + Instruction i = luaG_symbexec(p, pc, stackpos); | |
| 393 | + LUA_ASSERT(pc != -1, "function must be active"); | |
| 394 | + switch (GET_OPCODE(i)) { | |
| 395 | + case OP_GETGLOBAL: { | |
| 396 | + *name = p->kstr[GETARG_U(i)]->str; | |
| 397 | + return "global"; | |
| 398 | + } | |
| 399 | + case OP_GETLOCAL: { | |
| 400 | + *name = luaF_getlocalname(p, GETARG_U(i)+1, pc); | |
| 401 | + LUA_ASSERT(*name, "local must exist"); | |
| 402 | + return "local"; | |
| 403 | + } | |
| 404 | + case OP_PUSHSELF: | |
| 405 | + case OP_GETDOTTED: { | |
| 406 | + *name = p->kstr[GETARG_U(i)]->str; | |
| 407 | + return "field"; | |
| 408 | + } | |
| 409 | + default: | |
| 410 | + return NULL; /* no useful name found */ | |
| 411 | + } | |
| 412 | + } | |
| 413 | +} | |
| 414 | + | |
| 415 | + | |
| 416 | +static const char *getfuncname (lua_State *L, StkId f, const char **name) { | |
| 417 | + StkId func = aux_stackedfunction(L, 0, f); /* calling function */ | |
| 418 | + if (!isLmark(func)) | |
| 419 | + return NULL; /* not an active Lua function */ | |
| 420 | + else { | |
| 421 | + Proto *p = infovalue(func)->func->f.l; | |
| 422 | + int pc = currentpc(func); | |
| 423 | + Instruction i; | |
| 424 | + if (pc == -1) return NULL; /* function is not activated */ | |
| 425 | + i = p->code[pc]; | |
| 426 | + switch (GET_OPCODE(i)) { | |
| 427 | + case OP_CALL: case OP_TAILCALL: | |
| 428 | + return getobjname(L, (func+1)+GETARG_A(i), name); | |
| 429 | + default: | |
| 430 | + return NULL; /* no useful name found */ | |
| 431 | + } | |
| 432 | + } | |
| 433 | +} | |
| 434 | + | |
| 435 | + | |
| 436 | +/* }====================================================== */ | |
| 437 | + | |
| 438 | + | |
| 439 | +void luaG_typeerror (lua_State *L, StkId o, const char *op) { | |
| 440 | + const char *name; | |
| 441 | + const char *kind = getobjname(L, o, &name); | |
| 442 | + const char *t = luaO_typename(o); | |
| 443 | + if (kind) | |
| 444 | + luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)", | |
| 445 | + op, kind, name, t); | |
| 446 | + else | |
| 447 | + luaO_verror(L, "attempt to %.30s a %.10s value", op, t); | |
| 448 | +} | |
| 449 | + | |
| 450 | + | |
| 451 | +void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) { | |
| 452 | + if (ttype(p1) == t) p1++; | |
| 453 | + LUA_ASSERT(ttype(p1) != t, "must be an error"); | |
| 454 | + luaG_typeerror(L, p1, op); | |
| 455 | +} | |
| 456 | + | |
| 457 | + | |
| 458 | +void luaG_ordererror (lua_State *L, StkId top) { | |
| 459 | + const char *t1 = luaO_typename(top-2); | |
| 460 | + const char *t2 = luaO_typename(top-1); | |
| 461 | + if (t1[2] == t2[2]) | |
| 462 | + luaO_verror(L, "attempt to compare two %.10s values", t1); | |
| 463 | + else | |
| 464 | + luaO_verror(L, "attempt to compare %.10s with %.10s", t1, t2); | |
| 465 | +} | |
| 466 | + | |
| @@ -0,0 +1,21 @@ | ||
| 1 | +/* | |
| 2 | +** $Id: ldebug.h,v 1.7 2000/10/05 12:14:08 roberto Exp $ | |
| 3 | +** Auxiliary functions from Debug Interface module | |
| 4 | +** See Copyright Notice in lua.h | |
| 5 | +*/ | |
| 6 | + | |
| 7 | +#ifndef ldebug_h | |
| 8 | +#define ldebug_h | |
| 9 | + | |
| 10 | + | |
| 11 | +#include "lstate.h" | |
| 12 | +#include "luadebug.h" | |
| 13 | + | |
| 14 | + | |
| 15 | +void luaG_typeerror (lua_State *L, StkId o, const char *op); | |
| 16 | +void luaG_binerror (lua_State *L, StkId p1, int t, const char *op); | |
| 17 | +int luaG_getline (int *lineinfo, int pc, int refline, int *refi); | |
| 18 | +void luaG_ordererror (lua_State *L, StkId top); | |
| 19 | + | |
| 20 | + | |
| 21 | +#endif | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ldo.c,v 1.45b 1999/06/22 20:37:23 roberto Exp $ | |
| 2 | +** $Id: ldo.c,v 1.109 2000/10/30 12:38:50 roberto Exp $ | |
| 3 | 3 | ** Stack and Call structure of Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -10,378 +10,376 @@ · 4 unmodified lines | ||
| 10 | 10 | #include <stdlib.h> |
| 11 | 11 | #include <string.h> |
| 12 | 12 | |
| 13 | −#include "lauxlib.h" | |
| 13 | +#include "lua.h" | |
| 14 | + | |
| 15 | +#include "ldebug.h" | |
| 14 | 16 | #include "ldo.h" |
| 15 | −#include "lfunc.h" | |
| 16 | 17 | #include "lgc.h" |
| 17 | 18 | #include "lmem.h" |
| 18 | 19 | #include "lobject.h" |
| 19 | 20 | #include "lparser.h" |
| 20 | 21 | #include "lstate.h" |
| 21 | 22 | #include "lstring.h" |
| 23 | +#include "ltable.h" | |
| 22 | 24 | #include "ltm.h" |
| 23 | −#include "lua.h" | |
| 24 | −#include "luadebug.h" | |
| 25 | 25 | #include "lundump.h" |
| 26 | 26 | #include "lvm.h" |
| 27 | 27 | #include "lzio.h" |
| 28 | 28 | |
| 29 | 29 | |
| 30 | +/* space to handle stack overflow errors */ | |
| 31 | +#define EXTRA_STACK (2*LUA_MINSTACK) | |
| 30 | 32 | |
| 31 | −#ifndef STACK_LIMIT | |
| 32 | −#define STACK_LIMIT 6000 /* arbitrary limit */ | |
| 33 | −#endif | |
| 34 | − | |
| 35 | − | |
| 36 | − | |
| 37 | −#define STACK_UNIT 128 | |
| 38 | 33 | |
| 39 | − | |
| 40 | −#ifdef DEBUG | |
| 41 | −#undef STACK_UNIT | |
| 42 | −#define STACK_UNIT 2 | |
| 43 | −#endif | |
| 44 | − | |
| 45 | − | |
| 46 | −void luaD_init (void) { | |
| 47 | − L->stack.stack = luaM_newvector(STACK_UNIT, TObject); | |
| 48 | − L->stack.top = L->stack.stack; | |
| 49 | − L->stack.last = L->stack.stack+(STACK_UNIT-1); | |
| 34 | +void luaD_init (lua_State *L, int stacksize) { | |
| 35 | + L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject); | |
| 36 | + L->nblocks += stacksize*sizeof(TObject); | |
| 37 | + L->stack_last = L->stack+(stacksize-1); | |
| 38 | + L->stacksize = stacksize; | |
| 39 | + L->Cbase = L->top = L->stack; | |
| 50 | 40 | } |
| 51 | 41 | |
| 52 | 42 | |
| 53 | −void luaD_checkstack (int n) { | |
| 54 | − struct Stack *S = &L->stack; | |
| 55 | − if (S->last-S->top <= n) { | |
| 56 | − StkId top = S->top-S->stack; | |
| 57 | − int stacksize = (S->last-S->stack)+STACK_UNIT+n; | |
| 58 | − luaM_reallocvector(S->stack, stacksize, TObject); | |
| 59 | − S->last = S->stack+(stacksize-1); | |
| 60 | − S->top = S->stack + top; | |
| 61 | − if (stacksize >= STACK_LIMIT) { /* stack overflow? */ | |
| 62 | − if (lua_stackedfunction(100) == LUA_NOOBJECT) /* 100 funcs on stack? */ | |
| 63 | − lua_error("Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */ | |
| 64 | − else | |
| 65 | − lua_error("stack size overflow"); | |
| 43 | +void luaD_checkstack (lua_State *L, int n) { | |
| 44 | + if (L->stack_last - L->top <= n) { /* stack overflow? */ | |
| 45 | + if (L->stack_last-L->stack > (L->stacksize-1)) { | |
| 46 | + /* overflow while handling overflow */ | |
| 47 | + luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ | |
| 48 | + } | |
| 49 | + else { | |
| 50 | + L->stack_last += EXTRA_STACK; /* to be used by error message */ | |
| 51 | + lua_error(L, "stack overflow"); | |
| 66 | 52 | } |
| 67 | 53 | } |
| 68 | 54 | } |
| 69 | 55 | |
| 70 | 56 | |
| 57 | +static void restore_stack_limit (lua_State *L) { | |
| 58 | + if (L->top - L->stack < L->stacksize - 1) | |
| 59 | + L->stack_last = L->stack + (L->stacksize-1); | |
| 60 | +} | |
| 61 | + | |
| 62 | + | |
| 71 | 63 | /* |
| 72 | −** Adjust stack. Set top to the given value, pushing NILs if needed. | |
| 64 | +** Adjust stack. Set top to base+extra, pushing NILs if needed. | |
| 65 | +** (we cannot add base+extra unless we are sure it fits in the stack; | |
| 66 | +** otherwise the result of such operation on pointers is undefined) | |
| 73 | 67 | */ |
| 74 | −void luaD_adjusttop (StkId newtop) { | |
| 75 | − int diff = newtop-(L->stack.top-L->stack.stack); | |
| 68 | +void luaD_adjusttop (lua_State *L, StkId base, int extra) { | |
| 69 | + int diff = extra-(L->top-base); | |
| 76 | 70 | if (diff <= 0) |
| 77 | − L->stack.top += diff; | |
| 71 | + L->top = base+extra; | |
| 78 | 72 | else { |
| 79 | − luaD_checkstack(diff); | |
| 73 | + luaD_checkstack(L, diff); | |
| 80 | 74 | while (diff--) |
| 81 | − ttype(L->stack.top++) = LUA_T_NIL; | |
| 75 | + ttype(L->top++) = LUA_TNIL; | |
| 82 | 76 | } |
| 83 | 77 | } |
| 84 | 78 | |
| 85 | 79 | |
| 86 | 80 | /* |
| 87 | −** Open a hole below "nelems" from the L->stack.top. | |
| 81 | +** Open a hole inside the stack at `pos' | |
| 88 | 82 | */ |
| 89 | −void luaD_openstack (int nelems) { | |
| 90 | − luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems, | |
| 91 | − nelems*sizeof(TObject)); | |
| 83 | +static void luaD_openstack (lua_State *L, StkId pos) { | |
| 84 | + int i = L->top-pos; | |
| 85 | + while (i--) pos[i+1] = pos[i]; | |
| 92 | 86 | incr_top; |
| 93 | 87 | } |
| 94 | 88 | |
| 95 | 89 | |
| 96 | −void luaD_lineHook (int line) { | |
| 97 | − struct C_Lua_Stack oldCLS = L->Cstack; | |
| 98 | − StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; | |
| 99 | − L->Cstack.num = 0; | |
| 100 | − (*L->linehook)(line); | |
| 101 | − L->stack.top = L->stack.stack+old_top; | |
| 102 | − L->Cstack = oldCLS; | |
| 90 | +static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { | |
| 91 | + StkId old_Cbase = L->Cbase; | |
| 92 | + StkId old_top = L->Cbase = L->top; | |
| 93 | + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | |
| 94 | + L->allowhooks = 0; /* cannot call hooks inside a hook */ | |
| 95 | + (*hook)(L, ar); | |
| 96 | + LUA_ASSERT(L->allowhooks == 0, "invalid allow"); | |
| 97 | + L->allowhooks = 1; | |
| 98 | + L->top = old_top; | |
| 99 | + L->Cbase = old_Cbase; | |
| 103 | 100 | } |
| 104 | 101 | |
| 105 | 102 | |
| 106 | −void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn) { | |
| 107 | − struct C_Lua_Stack oldCLS = L->Cstack; | |
| 108 | − StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; | |
| 109 | − L->Cstack.num = 0; | |
| 110 | − if (isreturn) | |
| 111 | − (*L->callhook)(LUA_NOOBJECT, "(return)", 0); | |
| 112 | − else { | |
| 113 | − TObject *f = L->stack.stack+base-1; | |
| 114 | − if (tf) | |
| 115 | − (*L->callhook)(Ref(f), tf->source->str, tf->lineDefined); | |
| 116 | − else | |
| 117 | − (*L->callhook)(Ref(f), "(C)", -1); | |
| 103 | +void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) { | |
| 104 | + if (L->allowhooks) { | |
| 105 | + lua_Debug ar; | |
| 106 | + ar._func = func; | |
| 107 | + ar.event = "line"; | |
| 108 | + ar.currentline = line; | |
| 109 | + dohook(L, &ar, linehook); | |
| 118 | 110 | } |
| 119 | − L->stack.top = L->stack.stack+old_top; | |
| 120 | − L->Cstack = oldCLS; | |
| 121 | 111 | } |
| 122 | 112 | |
| 123 | 113 | |
| 124 | −/* | |
| 125 | −** Call a C function. | |
| 126 | −** Cstack.num is the number of arguments; Cstack.lua2C points to the | |
| 127 | −** first argument. Returns an index to the first result from C. | |
| 128 | −*/ | |
| 129 | −static StkId callC (lua_CFunction f, StkId base) { | |
| 130 | − struct C_Lua_Stack *cls = &L->Cstack; | |
| 131 | − struct C_Lua_Stack oldCLS = *cls; | |
| 132 | − StkId firstResult; | |
| 133 | − int numarg = (L->stack.top-L->stack.stack) - base; | |
| 134 | − cls->num = numarg; | |
| 135 | − cls->lua2C = base; | |
| 136 | − cls->base = base+numarg; /* == top-stack */ | |
| 137 | − if (L->callhook) | |
| 138 | − luaD_callHook(base, NULL, 0); | |
| 139 | − (*f)(); /* do the actual call */ | |
| 140 | − if (L->callhook) /* func may have changed callhook */ | |
| 141 | − luaD_callHook(base, NULL, 1); | |
| 142 | − firstResult = cls->base; | |
| 143 | − *cls = oldCLS; | |
| 144 | − return firstResult; | |
| 114 | +static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook, | |
| 115 | + const char *event) { | |
| 116 | + if (L->allowhooks) { | |
| 117 | + lua_Debug ar; | |
| 118 | + ar._func = func; | |
| 119 | + ar.event = event; | |
| 120 | + infovalue(func)->pc = NULL; /* function is not active */ | |
| 121 | + dohook(L, &ar, callhook); | |
| 122 | + } | |
| 145 | 123 | } |
| 146 | 124 | |
| 147 | 125 | |
| 148 | −static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base) { | |
| 149 | − TObject *pbase; | |
| 150 | − int nup = cl->nelems; /* number of upvalues */ | |
| 151 | − luaD_checkstack(nup); | |
| 152 | − pbase = L->stack.stack+base; /* care: previous call may change this */ | |
| 153 | − /* open space for upvalues as extra arguments */ | |
| 154 | − luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject)); | |
| 155 | − /* copy upvalues into stack */ | |
| 156 | − memcpy(pbase, cl->consts+1, nup*sizeof(TObject)); | |
| 157 | − L->stack.top += nup; | |
| 158 | − return callC(f, base); | |
| 126 | +static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) { | |
| 127 | + int nup = cl->nupvalues; /* number of upvalues */ | |
| 128 | + StkId old_Cbase = L->Cbase; | |
| 129 | + int n; | |
| 130 | + L->Cbase = base; /* new base for C function */ | |
| 131 | + luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */ | |
| 132 | + for (n=0; n<nup; n++) /* copy upvalues as extra arguments */ | |
| 133 | + *(L->top++) = cl->upvalue[n]; | |
| 134 | + n = (*cl->f.c)(L); /* do the actual call */ | |
| 135 | + L->Cbase = old_Cbase; /* restore old C base */ | |
| 136 | + return L->top - n; /* return index of first result */ | |
| 159 | 137 | } |
| 160 | 138 | |
| 161 | 139 | |
| 162 | −void luaD_callTM (TObject *f, int nParams, int nResults) { | |
| 163 | − luaD_openstack(nParams); | |
| 164 | − *(L->stack.top-nParams-1) = *f; | |
| 165 | − luaD_calln(nParams, nResults); | |
| 140 | +void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) { | |
| 141 | + StkId base = L->top - nParams; | |
| 142 | + luaD_openstack(L, base); | |
| 143 | + clvalue(base) = f; | |
| 144 | + ttype(base) = LUA_TFUNCTION; | |
| 145 | + luaD_call(L, base, nResults); | |
| 166 | 146 | } |
| 167 | 147 | |
| 168 | 148 | |
| 169 | 149 | /* |
| 170 | −** Call a function (C or Lua). The parameters must be on the stack, | |
| 171 | −** between [top-nArgs,top). The function to be called is right below the | |
| 172 | −** arguments. | |
| 173 | −** When returns, the results are on the stack, between [top-nArgs-1,top). | |
| 174 | −** The number of results is nResults, unless nResults=MULT_RET. | |
| 175 | −*/ | |
| 176 | −void luaD_calln (int nArgs, int nResults) { | |
| 177 | − struct Stack *S = &L->stack; /* to optimize */ | |
| 178 | − StkId base = (S->top-S->stack)-nArgs; | |
| 179 | − TObject *func = S->stack+base-1; | |
| 150 | +** Call a function (C or Lua). The function to be called is at *func. | |
| 151 | +** The arguments are on the stack, right after the function. | |
| 152 | +** When returns, the results are on the stack, starting at the original | |
| 153 | +** function position. | |
| 154 | +** The number of results is nResults, unless nResults=LUA_MULTRET. | |
| 155 | +*/ | |
| 156 | +void luaD_call (lua_State *L, StkId func, int nResults) { | |
| 157 | + lua_Hook callhook; | |
| 180 | 158 | StkId firstResult; |
| 181 | − int i; | |
| 182 | − switch (ttype(func)) { | |
| 183 | − case LUA_T_CPROTO: | |
| 184 | − ttype(func) = LUA_T_CMARK; | |
| 185 | − firstResult = callC(fvalue(func), base); | |
| 186 | − break; | |
| 187 | − case LUA_T_PROTO: | |
| 188 | − ttype(func) = LUA_T_PMARK; | |
| 189 | − firstResult = luaV_execute(NULL, tfvalue(func), base); | |
| 190 | − break; | |
| 191 | − case LUA_T_CLOSURE: { | |
| 192 | − Closure *c = clvalue(func); | |
| 193 | − TObject *proto = &(c->consts[0]); | |
| 194 | − ttype(func) = LUA_T_CLMARK; | |
| 195 | − firstResult = (ttype(proto) == LUA_T_CPROTO) ? | |
| 196 | − callCclosure(c, fvalue(proto), base) : | |
| 197 | − luaV_execute(c, tfvalue(proto), base); | |
| 198 | − break; | |
| 199 | − } | |
| 200 | − default: { /* func is not a function */ | |
| 201 | − /* Check the tag method for invalid functions */ | |
| 202 | − TObject *im = luaT_getimbyObj(func, IM_FUNCTION); | |
| 203 | − if (ttype(im) == LUA_T_NIL) | |
| 204 | − lua_error("call expression not a function"); | |
| 205 | − luaD_callTM(im, (S->top-S->stack)-(base-1), nResults); | |
| 206 | − return; | |
| 159 | + CallInfo ci; | |
| 160 | + Closure *cl; | |
| 161 | + if (ttype(func) != LUA_TFUNCTION) { | |
| 162 | + /* `func' is not a function; check the `function' tag method */ | |
| 163 | + Closure *tm = luaT_gettmbyObj(L, func, TM_FUNCTION); | |
| 164 | + if (tm == NULL) | |
| 165 | + luaG_typeerror(L, func, "call"); | |
| 166 | + luaD_openstack(L, func); | |
| 167 | + clvalue(func) = tm; /* tag method is the new function to be called */ | |
| 168 | + ttype(func) = LUA_TFUNCTION; | |
| 169 | + } | |
| 170 | + cl = clvalue(func); | |
| 171 | + ci.func = cl; | |
| 172 | + infovalue(func) = &ci; | |
| 173 | + ttype(func) = LUA_TMARK; | |
| 174 | + callhook = L->callhook; | |
| 175 | + if (callhook) | |
| 176 | + luaD_callHook(L, func, callhook, "call"); | |
| 177 | + firstResult = (cl->isC ? callCclosure(L, cl, func+1) : | |
| 178 | + luaV_execute(L, cl, func+1)); | |
| 179 | + if (callhook) /* same hook that was active at entry */ | |
| 180 | + luaD_callHook(L, func, callhook, "return"); | |
| 181 | + LUA_ASSERT(ttype(func) == LUA_TMARK, "invalid tag"); | |
| 182 | + /* move results to `func' (to erase parameters and function) */ | |
| 183 | + if (nResults == LUA_MULTRET) { | |
| 184 | + while (firstResult < L->top) /* copy all results */ | |
| 185 | + *func++ = *firstResult++; | |
| 186 | + L->top = func; | |
| 187 | + } | |
| 188 | + else { /* copy at most `nResults' */ | |
| 189 | + for (; nResults > 0 && firstResult < L->top; nResults--) | |
| 190 | + *func++ = *firstResult++; | |
| 191 | + L->top = func; | |
| 192 | + for (; nResults > 0; nResults--) { /* if there are not enough results */ | |
| 193 | + ttype(L->top) = LUA_TNIL; /* adjust the stack */ | |
| 194 | + incr_top; /* must check stack space */ | |
| 207 | 195 | } |
| 208 | 196 | } |
| 209 | − /* adjust the number of results */ | |
| 210 | − if (nResults == MULT_RET) | |
| 211 | − nResults = (S->top-S->stack)-firstResult; | |
| 212 | − else | |
| 213 | − luaD_adjusttop(firstResult+nResults); | |
| 214 | − /* move results to base-1 (to erase parameters and function) */ | |
| 215 | − base--; | |
| 216 | − for (i=0; i<nResults; i++) | |
| 217 | − *(S->stack+base+i) = *(S->stack+firstResult+i); | |
| 218 | − S->top -= firstResult-base; | |
| 197 | + luaC_checkGC(L); | |
| 219 | 198 | } |
| 220 | 199 | |
| 221 | 200 | |
| 222 | 201 | /* |
| 223 | −** Traverse all objects on L->stack.stack | |
| 202 | +** Execute a protected call. | |
| 224 | 203 | */ |
| 225 | −void luaD_travstack (int (*fn)(TObject *)) | |
| 226 | −{ | |
| 227 | − StkId i; | |
| 228 | − for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) | |
| 229 | − fn(L->stack.stack+i); | |
| 204 | +struct CallS { /* data to `f_call' */ | |
| 205 | + StkId func; | |
| 206 | + int nresults; | |
| 207 | +}; | |
| 208 | + | |
| 209 | +static void f_call (lua_State *L, void *ud) { | |
| 210 | + struct CallS *c = (struct CallS *)ud; | |
| 211 | + luaD_call(L, c->func, c->nresults); | |
| 230 | 212 | } |
| 231 | 213 | |
| 232 | 214 | |
| 233 | − | |
| 234 | −static void message (char *s) { | |
| 235 | − TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval); | |
| 236 | − if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO || | |
| 237 | − ttype(em) == LUA_T_CLOSURE) { | |
| 238 | − *L->stack.top = *em; | |
| 239 | − incr_top; | |
| 240 | − lua_pushstring(s); | |
| 241 | − luaD_calln(1, 0); | |
| 242 | − } | |
| 243 | −} | |
| 244 | − | |
| 245 | −/* | |
| 246 | −** Reports an error, and jumps up to the available recover label | |
| 247 | −*/ | |
| 248 | −void lua_error (char *s) { | |
| 249 | − if (s) message(s); | |
| 250 | − if (L->errorJmp) | |
| 251 | − longjmp(L->errorJmp->b, 1); | |
| 252 | − else { | |
| 253 | − message("exit(1). Unable to recover.\n"); | |
| 254 | − exit(1); | |
| 255 | − } | |
| 256 | −} | |
| 257 | − | |
| 258 | − | |
| 259 | −/* | |
| 260 | −** Execute a protected call. Assumes that function is at L->Cstack.base and | |
| 261 | −** parameters are on top of it. Leave nResults on the stack. | |
| 262 | −*/ | |
| 263 | −int luaD_protectedrun (void) { | |
| 264 | − volatile struct C_Lua_Stack oldCLS = L->Cstack; | |
| 265 | − struct lua_longjmp myErrorJmp; | |
| 266 | − volatile int status; | |
| 267 | − struct lua_longjmp *volatile oldErr = L->errorJmp; | |
| 268 | − L->errorJmp = &myErrorJmp; | |
| 269 | − if (setjmp(myErrorJmp.b) == 0) { | |
| 270 | − StkId base = L->Cstack.base; | |
| 271 | − luaD_calln((L->stack.top-L->stack.stack)-base-1, MULT_RET); | |
| 272 | − L->Cstack.lua2C = base; /* position of the new results */ | |
| 273 | − L->Cstack.num = (L->stack.top-L->stack.stack) - base; | |
| 274 | − L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */ | |
| 275 | − status = 0; | |
| 276 | − } | |
| 277 | − else { /* an error occurred: restore L->Cstack and L->stack.top */ | |
| 278 | − L->Cstack = oldCLS; | |
| 279 | − L->stack.top = L->stack.stack+L->Cstack.base; | |
| 280 | − status = 1; | |
| 281 | − } | |
| 282 | − L->errorJmp = oldErr; | |
| 215 | +LUA_API int lua_call (lua_State *L, int nargs, int nresults) { | |
| 216 | + StkId func = L->top - (nargs+1); /* function to be called */ | |
| 217 | + struct CallS c; | |
| 218 | + int status; | |
| 219 | + c.func = func; c.nresults = nresults; | |
| 220 | + status = luaD_runprotected(L, f_call, &c); | |
| 221 | + if (status != 0) /* an error occurred? */ | |
| 222 | + L->top = func; /* remove parameters from the stack */ | |
| 283 | 223 | return status; |
| 284 | 224 | } |
| 285 | 225 | |
| 286 | 226 | |
| 287 | 227 | /* |
| 288 | −** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load | |
| 228 | +** Execute a protected parser. | |
| 289 | 229 | */ |
| 290 | −static int protectedparser (ZIO *z, int bin) { | |
| 291 | − volatile struct C_Lua_Stack oldCLS = L->Cstack; | |
| 292 | − struct lua_longjmp myErrorJmp; | |
| 293 | − volatile int status; | |
| 294 | − TProtoFunc *volatile tf; | |
| 295 | − struct lua_longjmp *volatile oldErr = L->errorJmp; | |
| 296 | − L->errorJmp = &myErrorJmp; | |
| 297 | − if (setjmp(myErrorJmp.b) == 0) { | |
| 298 | − tf = bin ? luaU_undump1(z) : luaY_parser(z); | |
| 299 | − status = 0; | |
| 300 | − } | |
| 301 | − else { /* an error occurred: restore L->Cstack and L->stack.top */ | |
| 302 | − L->Cstack = oldCLS; | |
| 303 | − L->stack.top = L->stack.stack+L->Cstack.base; | |
| 304 | − tf = NULL; | |
| 305 | − status = 1; | |
| 306 | − } | |
| 307 | − L->errorJmp = oldErr; | |
| 308 | − if (status) return 1; /* error code */ | |
| 309 | − if (tf == NULL) return 2; /* 'natural' end */ | |
| 310 | − luaD_adjusttop(L->Cstack.base+1); /* one slot for the pseudo-function */ | |
| 311 | − L->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO; | |
| 312 | − L->stack.stack[L->Cstack.base].value.tf = tf; | |
| 313 | − luaV_closure(0); | |
| 314 | − return 0; | |
| 315 | −} | |
| 316 | − | |
| 230 | +struct ParserS { /* data to `f_parser' */ | |
| 231 | + ZIO *z; | |
| 232 | + int bin; | |
| 233 | +}; | |
| 317 | 234 | |
| 318 | −static int do_main (ZIO *z, int bin) { | |
| 319 | − int status; | |
| 320 | − int debug = L->debug; /* save debug status */ | |
| 321 | − do { | |
| 322 | − long old_blocks = (luaC_checkGC(), L->nblocks); | |
| 323 | − status = protectedparser(z, bin); | |
| 324 | − if (status == 1) return 1; /* error */ | |
| 325 | − else if (status == 2) return 0; /* 'natural' end */ | |
| 326 | − else { | |
| 327 | − unsigned long newelems2 = 2*(L->nblocks-old_blocks); | |
| 328 | − L->GCthreshold += newelems2; | |
| 329 | − status = luaD_protectedrun(); | |
| 330 | − L->GCthreshold -= newelems2; | |
| 331 | − } | |
| 332 | − } while (bin && status == 0); | |
| 333 | − L->debug = debug; /* restore debug status */ | |
| 334 | − return status; | |
| 235 | +static void f_parser (lua_State *L, void *ud) { | |
| 236 | + struct ParserS *p = (struct ParserS *)ud; | |
| 237 | + Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z); | |
| 238 | + luaV_Lclosure(L, tf, 0); | |
| 335 | 239 | } |
| 336 | 240 | |
| 337 | 241 | |
| 338 | −void luaD_gcIM (TObject *o) | |
| 339 | −{ | |
| 340 | − TObject *im = luaT_getimbyObj(o, IM_GC); | |
| 341 | − if (ttype(im) != LUA_T_NIL) { | |
| 342 | − *L->stack.top = *o; | |
| 343 | − incr_top; | |
| 344 | − luaD_callTM(im, 1, 0); | |
| 242 | +static int protectedparser (lua_State *L, ZIO *z, int bin) { | |
| 243 | + struct ParserS p; | |
| 244 | + unsigned long old_blocks; | |
| 245 | + int status; | |
| 246 | + p.z = z; p.bin = bin; | |
| 247 | + luaC_checkGC(L); | |
| 248 | + old_blocks = L->nblocks; | |
| 249 | + status = luaD_runprotected(L, f_parser, &p); | |
| 250 | + if (status == 0) { | |
| 251 | + /* add new memory to threshold (as it probably will stay) */ | |
| 252 | + L->GCthreshold += (L->nblocks - old_blocks); | |
| 345 | 253 | } |
| 254 | + else if (status == LUA_ERRRUN) /* an error occurred: correct error code */ | |
| 255 | + status = LUA_ERRSYNTAX; | |
| 256 | + return status; | |
| 346 | 257 | } |
| 347 | 258 | |
| 348 | 259 | |
| 349 | −#define MAXFILENAME 260 /* maximum part of a file name kept */ | |
| 350 | − | |
| 351 | −int lua_dofile (char *filename) { | |
| 260 | +static int parse_file (lua_State *L, const char *filename) { | |
| 352 | 261 | ZIO z; |
| 353 | 262 | int status; |
| 354 | − int c; | |
| 355 | − int bin; | |
| 356 | − char source[MAXFILENAME]; | |
| 263 | + int bin; /* flag for file mode */ | |
| 264 | + int c; /* look ahead char */ | |
| 357 | 265 | FILE *f = (filename == NULL) ? stdin : fopen(filename, "r"); |
| 358 | − if (f == NULL) | |
| 359 | − return 2; | |
| 360 | − luaL_filesource(source, filename, sizeof(source)); | |
| 266 | + if (f == NULL) return LUA_ERRFILE; /* unable to open file */ | |
| 361 | 267 | c = fgetc(f); |
| 362 | 268 | ungetc(c, f); |
| 363 | 269 | bin = (c == ID_CHUNK); |
| 364 | 270 | if (bin && f != stdin) { |
| 365 | 271 | f = freopen(filename, "rb", f); /* set binary mode */ |
| 366 | − if (f == NULL) return 2; | |
| 272 | + if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */ | |
| 367 | 273 | } |
| 368 | − luaZ_Fopen(&z, f, source); | |
| 369 | − status = do_main(&z, bin); | |
| 274 | + lua_pushstring(L, "@"); | |
| 275 | + lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename); | |
| 276 | + lua_concat(L, 2); | |
| 277 | + filename = lua_tostring(L, -1); /* filename = '@'..filename */ | |
| 278 | + lua_pop(L, 1); /* OK: there is no GC during parser */ | |
| 279 | + luaZ_Fopen(&z, f, filename); | |
| 280 | + status = protectedparser(L, &z, bin); | |
| 370 | 281 | if (f != stdin) |
| 371 | 282 | fclose(f); |
| 372 | 283 | return status; |
| 373 | 284 | } |
| 374 | 285 | |
| 375 | 286 | |
| 376 | −int lua_dostring (char *str) { | |
| 377 | − return lua_dobuffer(str, strlen(str), str); | |
| 287 | +LUA_API int lua_dofile (lua_State *L, const char *filename) { | |
| 288 | + int status = parse_file(L, filename); | |
| 289 | + if (status == 0) /* parse OK? */ | |
| 290 | + status = lua_call(L, 0, LUA_MULTRET); /* call main */ | |
| 291 | + return status; | |
| 378 | 292 | } |
| 379 | 293 | |
| 380 | 294 | |
| 381 | −int lua_dobuffer (char *buff, int size, char *name) { | |
| 295 | +static int parse_buffer (lua_State *L, const char *buff, size_t size, | |
| 296 | + const char *name) { | |
| 382 | 297 | ZIO z; |
| 383 | 298 | if (!name) name = "?"; |
| 384 | 299 | luaZ_mopen(&z, buff, size, name); |
| 385 | − return do_main(&z, buff[0]==ID_CHUNK); | |
| 300 | + return protectedparser(L, &z, buff[0]==ID_CHUNK); | |
| 386 | 301 | } |
| 387 | 302 | |
| 303 | + | |
| 304 | +LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) { | |
| 305 | + int status = parse_buffer(L, buff, size, name); | |
| 306 | + if (status == 0) /* parse OK? */ | |
| 307 | + status = lua_call(L, 0, LUA_MULTRET); /* call main */ | |
| 308 | + return status; | |
| 309 | +} | |
| 310 | + | |
| 311 | + | |
| 312 | +LUA_API int lua_dostring (lua_State *L, const char *str) { | |
| 313 | + return lua_dobuffer(L, str, strlen(str), str); | |
| 314 | +} | |
| 315 | + | |
| 316 | + | |
| 317 | +/* | |
| 318 | +** {====================================================== | |
| 319 | +** Error-recover functions (based on long jumps) | |
| 320 | +** ======================================================= | |
| 321 | +*/ | |
| 322 | + | |
| 323 | +/* chain list of long jump buffers */ | |
| 324 | +struct lua_longjmp { | |
| 325 | + jmp_buf b; | |
| 326 | + struct lua_longjmp *previous; | |
| 327 | + volatile int status; /* error code */ | |
| 328 | +}; | |
| 329 | + | |
| 330 | + | |
| 331 | +static void message (lua_State *L, const char *s) { | |
| 332 | + const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE); | |
| 333 | + if (ttype(em) == LUA_TFUNCTION) { | |
| 334 | + *L->top = *em; | |
| 335 | + incr_top; | |
| 336 | + lua_pushstring(L, s); | |
| 337 | + luaD_call(L, L->top-2, 0); | |
| 338 | + } | |
| 339 | +} | |
| 340 | + | |
| 341 | + | |
| 342 | +/* | |
| 343 | +** Reports an error, and jumps up to the available recovery label | |
| 344 | +*/ | |
| 345 | +LUA_API void lua_error (lua_State *L, const char *s) { | |
| 346 | + if (s) message(L, s); | |
| 347 | + luaD_breakrun(L, LUA_ERRRUN); | |
| 348 | +} | |
| 349 | + | |
| 350 | + | |
| 351 | +void luaD_breakrun (lua_State *L, int errcode) { | |
| 352 | + if (L->errorJmp) { | |
| 353 | + L->errorJmp->status = errcode; | |
| 354 | + longjmp(L->errorJmp->b, 1); | |
| 355 | + } | |
| 356 | + else { | |
| 357 | + if (errcode != LUA_ERRMEM) | |
| 358 | + message(L, "unable to recover; exiting\n"); | |
| 359 | + exit(EXIT_FAILURE); | |
| 360 | + } | |
| 361 | +} | |
| 362 | + | |
| 363 | + | |
| 364 | +int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { | |
| 365 | + StkId oldCbase = L->Cbase; | |
| 366 | + StkId oldtop = L->top; | |
| 367 | + struct lua_longjmp lj; | |
| 368 | + int allowhooks = L->allowhooks; | |
| 369 | + lj.status = 0; | |
| 370 | + lj.previous = L->errorJmp; /* chain new error handler */ | |
| 371 | + L->errorJmp = &lj; | |
| 372 | + if (setjmp(lj.b) == 0) | |
| 373 | + (*f)(L, ud); | |
| 374 | + else { /* an error occurred: restore the state */ | |
| 375 | + L->allowhooks = allowhooks; | |
| 376 | + L->Cbase = oldCbase; | |
| 377 | + L->top = oldtop; | |
| 378 | + restore_stack_limit(L); | |
| 379 | + } | |
| 380 | + L->errorJmp = lj.previous; /* restore old error handler */ | |
| 381 | + return lj.status; | |
| 382 | +} | |
| 383 | + | |
| 384 | +/* }====================================================== */ | |
| 385 | + | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ldo.h,v 1.6 1999/06/22 20:37:23 roberto Exp $ | |
| 2 | +** $Id: ldo.h,v 1.28 2000/10/06 12:45:25 roberto Exp $ | |
| 3 | 3 | ** Stack and Call structure of Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -12,35 +12,22 @@ · 6 unmodified lines | ||
| 12 | 12 | #include "lstate.h" |
| 13 | 13 | |
| 14 | 14 | |
| 15 | −#define MULT_RET 255 | |
| 16 | − | |
| 17 | − | |
| 18 | − | |
| 19 | 15 | /* |
| 20 | 16 | ** macro to increment stack top. |
| 21 | 17 | ** There must be always an empty slot at the L->stack.top |
| 22 | 18 | */ |
| 23 | −#define incr_top { if (L->stack.top >= L->stack.last) luaD_checkstack(1); \ | |
| 24 | − L->stack.top++; } | |
| 25 | − | |
| 26 | − | |
| 27 | −/* macros to convert from lua_Object to (TObject *) and back */ | |
| 19 | +#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;} | |
| 28 | 20 | |
| 29 | −#define Address(lo) ((lo)+L->stack.stack-1) | |
| 30 | −#define Ref(st) ((st)-L->stack.stack+1) | |
| 31 | 21 | |
| 22 | +void luaD_init (lua_State *L, int stacksize); | |
| 23 | +void luaD_adjusttop (lua_State *L, StkId base, int extra); | |
| 24 | +void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook); | |
| 25 | +void luaD_call (lua_State *L, StkId func, int nResults); | |
| 26 | +void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults); | |
| 27 | +void luaD_checkstack (lua_State *L, int n); | |
| 32 | 28 | |
| 33 | −void luaD_init (void); | |
| 34 | −void luaD_adjusttop (StkId newtop); | |
| 35 | −void luaD_openstack (int nelems); | |
| 36 | −void luaD_lineHook (int line); | |
| 37 | −void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn); | |
| 38 | −void luaD_calln (int nArgs, int nResults); | |
| 39 | −void luaD_callTM (TObject *f, int nParams, int nResults); | |
| 40 | −int luaD_protectedrun (void); | |
| 41 | −void luaD_gcIM (TObject *o); | |
| 42 | −void luaD_travstack (int (*fn)(TObject *)); | |
| 43 | −void luaD_checkstack (int n); | |
| 29 | +void luaD_breakrun (lua_State *L, int errcode); | |
| 30 | +int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud); | |
| 44 | 31 | |
| 45 | 32 | |
| 46 | 33 | #endif |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lfunc.c,v 1.10 1999/03/04 21:17:26 roberto Exp $ | |
| 2 | +** $Id: lfunc.c,v 1.34 2000/10/30 12:20:29 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -7,92 +7,103 @@ · 1 unmodified line | ||
| 7 | 7 | |
| 8 | 8 | #include <stdlib.h> |
| 9 | 9 | |
| 10 | +#include "lua.h" | |
| 11 | + | |
| 10 | 12 | #include "lfunc.h" |
| 11 | 13 | #include "lmem.h" |
| 12 | 14 | #include "lstate.h" |
| 13 | 15 | |
| 14 | −#define gcsizeproto(p) 5 /* approximate "weight" for a prototype */ | |
| 15 | −#define gcsizeclosure(c) 1 /* approximate "weight" for a closure */ | |
| 16 | 16 | |
| 17 | +#define sizeclosure(n) ((int)sizeof(Closure) + (int)sizeof(TObject)*((n)-1)) | |
| 17 | 18 | |
| 18 | 19 | |
| 19 | −Closure *luaF_newclosure (int nelems) | |
| 20 | −{ | |
| 21 | − Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject)); | |
| 22 | − luaO_insertlist(&(L->rootcl), (GCnode *)c); | |
| 23 | − L->nblocks += gcsizeclosure(c); | |
| 24 | − c->nelems = nelems; | |
| 20 | +Closure *luaF_newclosure (lua_State *L, int nelems) { | |
| 21 | + int size = sizeclosure(nelems); | |
| 22 | + Closure *c = (Closure *)luaM_malloc(L, size); | |
| 23 | + c->next = L->rootcl; | |
| 24 | + L->rootcl = c; | |
| 25 | + c->mark = c; | |
| 26 | + c->nupvalues = nelems; | |
| 27 | + L->nblocks += size; | |
| 25 | 28 | return c; |
| 26 | 29 | } |
| 27 | 30 | |
| 28 | 31 | |
| 29 | −TProtoFunc *luaF_newproto (void) | |
| 30 | −{ | |
| 31 | − TProtoFunc *f = luaM_new(TProtoFunc); | |
| 32 | +Proto *luaF_newproto (lua_State *L) { | |
| 33 | + Proto *f = luaM_new(L, Proto); | |
| 34 | + f->knum = NULL; | |
| 35 | + f->nknum = 0; | |
| 36 | + f->kstr = NULL; | |
| 37 | + f->nkstr = 0; | |
| 38 | + f->kproto = NULL; | |
| 39 | + f->nkproto = 0; | |
| 32 | 40 | f->code = NULL; |
| 41 | + f->ncode = 0; | |
| 42 | + f->numparams = 0; | |
| 43 | + f->is_vararg = 0; | |
| 44 | + f->maxstacksize = 0; | |
| 45 | + f->marked = 0; | |
| 46 | + f->lineinfo = NULL; | |
| 47 | + f->nlineinfo = 0; | |
| 48 | + f->nlocvars = 0; | |
| 49 | + f->locvars = NULL; | |
| 33 | 50 | f->lineDefined = 0; |
| 34 | 51 | f->source = NULL; |
| 35 | − f->consts = NULL; | |
| 36 | − f->nconsts = 0; | |
| 37 | − f->locvars = NULL; | |
| 38 | − luaO_insertlist(&(L->rootproto), (GCnode *)f); | |
| 39 | − L->nblocks += gcsizeproto(f); | |
| 52 | + f->next = L->rootproto; /* chain in list of protos */ | |
| 53 | + L->rootproto = f; | |
| 40 | 54 | return f; |
| 41 | 55 | } |
| 42 | 56 | |
| 43 | 57 | |
| 58 | +static size_t protosize (Proto *f) { | |
| 59 | + return sizeof(Proto) | |
| 60 | + + f->nknum*sizeof(Number) | |
| 61 | + + f->nkstr*sizeof(TString *) | |
| 62 | + + f->nkproto*sizeof(Proto *) | |
| 63 | + + f->ncode*sizeof(Instruction) | |
| 64 | + + f->nlocvars*sizeof(struct LocVar) | |
| 65 | + + f->nlineinfo*sizeof(int); | |
| 66 | +} | |
| 44 | 67 | |
| 45 | −static void freefunc (TProtoFunc *f) | |
| 46 | −{ | |
| 47 | − luaM_free(f->code); | |
| 48 | − luaM_free(f->locvars); | |
| 49 | − luaM_free(f->consts); | |
| 50 | − luaM_free(f); | |
| 68 | + | |
| 69 | +void luaF_protook (lua_State *L, Proto *f, int pc) { | |
| 70 | + f->ncode = pc; /* signal that proto was properly created */ | |
| 71 | + L->nblocks += protosize(f); | |
| 51 | 72 | } |
| 52 | 73 | |
| 53 | 74 | |
| 54 | −void luaF_freeproto (TProtoFunc *l) | |
| 55 | −{ | |
| 56 | − while (l) { | |
| 57 | − TProtoFunc *next = (TProtoFunc *)l->head.next; | |
| 58 | − L->nblocks -= gcsizeproto(l); | |
| 59 | − freefunc(l); | |
| 60 | − l = next; | |
| 61 | − } | |
| 75 | +void luaF_freeproto (lua_State *L, Proto *f) { | |
| 76 | + if (f->ncode > 0) /* function was properly created? */ | |
| 77 | + L->nblocks -= protosize(f); | |
| 78 | + luaM_free(L, f->code); | |
| 79 | + luaM_free(L, f->locvars); | |
| 80 | + luaM_free(L, f->kstr); | |
| 81 | + luaM_free(L, f->knum); | |
| 82 | + luaM_free(L, f->kproto); | |
| 83 | + luaM_free(L, f->lineinfo); | |
| 84 | + luaM_free(L, f); | |
| 62 | 85 | } |
| 63 | 86 | |
| 64 | 87 | |
| 65 | −void luaF_freeclosure (Closure *l) | |
| 66 | −{ | |
| 67 | − while (l) { | |
| 68 | − Closure *next = (Closure *)l->head.next; | |
| 69 | − L->nblocks -= gcsizeclosure(l); | |
| 70 | − luaM_free(l); | |
| 71 | − l = next; | |
| 72 | − } | |
| 88 | +void luaF_freeclosure (lua_State *L, Closure *c) { | |
| 89 | + L->nblocks -= sizeclosure(c->nupvalues); | |
| 90 | + luaM_free(L, c); | |
| 73 | 91 | } |
| 74 | 92 | |
| 75 | 93 | |
| 76 | 94 | /* |
| 77 | −** Look for n-th local variable at line "line" in function "func". | |
| 95 | +** Look for n-th local variable at line `line' in function `func'. | |
| 78 | 96 | ** Returns NULL if not found. |
| 79 | 97 | */ |
| 80 | −char *luaF_getlocalname (TProtoFunc *func, int local_number, int line) | |
| 81 | −{ | |
| 82 | − int count = 0; | |
| 83 | − char *varname = NULL; | |
| 84 | − LocVar *lv = func->locvars; | |
| 85 | − if (lv == NULL) | |
| 86 | − return NULL; | |
| 87 | − for (; lv->line != -1 && lv->line < line; lv++) { | |
| 88 | − if (lv->varname) { /* register */ | |
| 89 | − if (++count == local_number) | |
| 90 | − varname = lv->varname->str; | |
| 98 | +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { | |
| 99 | + int i; | |
| 100 | + for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) { | |
| 101 | + if (pc < f->locvars[i].endpc) { /* is variable active? */ | |
| 102 | + local_number--; | |
| 103 | + if (local_number == 0) | |
| 104 | + return f->locvars[i].varname->str; | |
| 91 | 105 | } |
| 92 | − else /* unregister */ | |
| 93 | − if (--count < local_number) | |
| 94 | − varname = NULL; | |
| 95 | 106 | } |
| 96 | − return varname; | |
| 107 | + return NULL; /* not found */ | |
| 97 | 108 | } |
| 98 | 109 | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lfunc.h,v 1.5 1997/12/15 16:17:20 roberto Exp $ | |
| 3 | −** Lua Function structures | |
| 2 | +** $Id: lfunc.h,v 1.13 2000/09/29 12:42:13 roberto Exp $ | |
| 3 | +** Auxiliary functions to manipulate prototypes and closures | |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| @@ -12,12 +12,13 @@ · 5 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | |
| 14 | 14 | |
| 15 | −TProtoFunc *luaF_newproto (void); | |
| 16 | −Closure *luaF_newclosure (int nelems); | |
| 17 | −void luaF_freeproto (TProtoFunc *l); | |
| 18 | −void luaF_freeclosure (Closure *l); | |
| 15 | +Proto *luaF_newproto (lua_State *L); | |
| 16 | +void luaF_protook (lua_State *L, Proto *f, int pc); | |
| 17 | +Closure *luaF_newclosure (lua_State *L, int nelems); | |
| 18 | +void luaF_freeproto (lua_State *L, Proto *f); | |
| 19 | +void luaF_freeclosure (lua_State *L, Closure *c); | |
| 19 | 20 | |
| 20 | −char *luaF_getlocalname (TProtoFunc *func, int local_number, int line); | |
| 21 | +const char *luaF_getlocalname (const Proto *func, int local_number, int pc); | |
| 21 | 22 | |
| 22 | 23 | |
| 23 | 24 | #endif |
| @@ -1,9 +1,10 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lgc.c,v 1.23 1999/03/04 21:17:26 roberto Exp $ | |
| 2 | +** $Id: lgc.c,v 1.72 2000/10/26 12:47:05 roberto Exp $ | |
| 3 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include "lua.h" | |
| 7 | 8 | |
| 8 | 9 | #include "ldo.h" |
| 9 | 10 | #include "lfunc.h" |
| @@ -14,262 +15,339 @@ · 4 unmodified lines | ||
| 14 | 15 | #include "lstring.h" |
| 15 | 16 | #include "ltable.h" |
| 16 | 17 | #include "ltm.h" |
| 17 | −#include "lua.h" | |
| 18 | 18 | |
| 19 | 19 | |
| 20 | +typedef struct GCState { | |
| 21 | + Hash *tmark; /* list of marked tables to be visited */ | |
| 22 | + Closure *cmark; /* list of marked closures to be visited */ | |
| 23 | +} GCState; | |
| 20 | 24 | |
| 21 | −static int markobject (TObject *o); | |
| 22 | 25 | |
| 23 | 26 | |
| 27 | +static void markobject (GCState *st, TObject *o); | |
| 24 | 28 | |
| 25 | −/* | |
| 26 | −** ======================================================= | |
| 27 | −** REF mechanism | |
| 28 | −** ======================================================= | |
| 29 | −*/ | |
| 30 | 29 | |
| 30 | +/* mark a string; marks larger than 1 cannot be changed */ | |
| 31 | +#define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;} | |
| 31 | 32 | |
| 32 | −int luaC_ref (TObject *o, int lock) { | |
| 33 | − int ref; | |
| 34 | − if (ttype(o) == LUA_T_NIL) | |
| 35 | − ref = -1; /* special ref for nil */ | |
| 36 | − else { | |
| 37 | − for (ref=0; ref<L->refSize; ref++) | |
| 38 | − if (L->refArray[ref].status == FREE) | |
| 39 | − break; | |
| 40 | − if (ref == L->refSize) { /* no more empty spaces? */ | |
| 41 | − luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT); | |
| 42 | − L->refSize++; | |
| 43 | − } | |
| 44 | − L->refArray[ref].o = *o; | |
| 45 | − L->refArray[ref].status = lock ? LOCK : HOLD; | |
| 33 | + | |
| 34 | + | |
| 35 | +static void protomark (Proto *f) { | |
| 36 | + if (!f->marked) { | |
| 37 | + int i; | |
| 38 | + f->marked = 1; | |
| 39 | + strmark(f->source); | |
| 40 | + for (i=0; i<f->nkstr; i++) | |
| 41 | + strmark(f->kstr[i]); | |
| 42 | + for (i=0; i<f->nkproto; i++) | |
| 43 | + protomark(f->kproto[i]); | |
| 44 | + for (i=0; i<f->nlocvars; i++) /* mark local-variable names */ | |
| 45 | + strmark(f->locvars[i].varname); | |
| 46 | 46 | } |
| 47 | − return ref; | |
| 48 | 47 | } |
| 49 | 48 | |
| 50 | 49 | |
| 51 | −void lua_unref (int ref) | |
| 52 | −{ | |
| 53 | − if (ref >= 0 && ref < L->refSize) | |
| 54 | − L->refArray[ref].status = FREE; | |
| 50 | +static void markstack (lua_State *L, GCState *st) { | |
| 51 | + StkId o; | |
| 52 | + for (o=L->stack; o<L->top; o++) | |
| 53 | + markobject(st, o); | |
| 55 | 54 | } |
| 56 | 55 | |
| 57 | 56 | |
| 58 | −TObject* luaC_getref (int ref) | |
| 59 | −{ | |
| 60 | − if (ref == -1) | |
| 61 | − return &luaO_nilobject; | |
| 62 | − if (ref >= 0 && ref < L->refSize && | |
| 63 | − (L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD)) | |
| 64 | − return &L->refArray[ref].o; | |
| 65 | − else | |
| 66 | − return NULL; | |
| 57 | +static void marklock (lua_State *L, GCState *st) { | |
| 58 | + int i; | |
| 59 | + for (i=0; i<L->refSize; i++) { | |
| 60 | + if (L->refArray[i].st == LOCK) | |
| 61 | + markobject(st, &L->refArray[i].o); | |
| 62 | + } | |
| 67 | 63 | } |
| 68 | 64 | |
| 69 | 65 | |
| 70 | −static void travlock (void) | |
| 71 | −{ | |
| 72 | − int i; | |
| 73 | − for (i=0; i<L->refSize; i++) | |
| 74 | − if (L->refArray[i].status == LOCK) | |
| 75 | − markobject(&L->refArray[i].o); | |
| 66 | +static void markclosure (GCState *st, Closure *cl) { | |
| 67 | + if (!ismarked(cl)) { | |
| 68 | + if (!cl->isC) | |
| 69 | + protomark(cl->f.l); | |
| 70 | + cl->mark = st->cmark; /* chain it for later traversal */ | |
| 71 | + st->cmark = cl; | |
| 72 | + } | |
| 73 | +} | |
| 74 | + | |
| 75 | + | |
| 76 | +static void marktagmethods (lua_State *L, GCState *st) { | |
| 77 | + int e; | |
| 78 | + for (e=0; e<TM_N; e++) { | |
| 79 | + int t; | |
| 80 | + for (t=0; t<=L->last_tag; t++) { | |
| 81 | + Closure *cl = luaT_gettm(L, t, e); | |
| 82 | + if (cl) markclosure(st, cl); | |
| 83 | + } | |
| 84 | + } | |
| 85 | +} | |
| 86 | + | |
| 87 | + | |
| 88 | +static void markobject (GCState *st, TObject *o) { | |
| 89 | + switch (ttype(o)) { | |
| 90 | + case LUA_TUSERDATA: case LUA_TSTRING: | |
| 91 | + strmark(tsvalue(o)); | |
| 92 | + break; | |
| 93 | + case LUA_TMARK: | |
| 94 | + markclosure(st, infovalue(o)->func); | |
| 95 | + break; | |
| 96 | + case LUA_TFUNCTION: | |
| 97 | + markclosure(st, clvalue(o)); | |
| 98 | + break; | |
| 99 | + case LUA_TTABLE: { | |
| 100 | + if (!ismarked(hvalue(o))) { | |
| 101 | + hvalue(o)->mark = st->tmark; /* chain it in list of marked */ | |
| 102 | + st->tmark = hvalue(o); | |
| 103 | + } | |
| 104 | + break; | |
| 105 | + } | |
| 106 | + default: break; /* numbers, etc */ | |
| 107 | + } | |
| 108 | +} | |
| 109 | + | |
| 110 | + | |
| 111 | +static void markall (lua_State *L) { | |
| 112 | + GCState st; | |
| 113 | + st.cmark = NULL; | |
| 114 | + st.tmark = L->gt; /* put table of globals in mark list */ | |
| 115 | + L->gt->mark = NULL; | |
| 116 | + marktagmethods(L, &st); /* mark tag methods */ | |
| 117 | + markstack(L, &st); /* mark stack objects */ | |
| 118 | + marklock(L, &st); /* mark locked objects */ | |
| 119 | + for (;;) { /* mark tables and closures */ | |
| 120 | + if (st.cmark) { | |
| 121 | + int i; | |
| 122 | + Closure *f = st.cmark; /* get first closure from list */ | |
| 123 | + st.cmark = f->mark; /* remove it from list */ | |
| 124 | + for (i=0; i<f->nupvalues; i++) /* mark its upvalues */ | |
| 125 | + markobject(&st, &f->upvalue[i]); | |
| 126 | + } | |
| 127 | + else if (st.tmark) { | |
| 128 | + int i; | |
| 129 | + Hash *h = st.tmark; /* get first table from list */ | |
| 130 | + st.tmark = h->mark; /* remove it from list */ | |
| 131 | + for (i=0; i<h->size; i++) { | |
| 132 | + Node *n = node(h, i); | |
| 133 | + if (ttype(key(n)) != LUA_TNIL) { | |
| 134 | + if (ttype(val(n)) == LUA_TNIL) | |
| 135 | + luaH_remove(h, key(n)); /* dead element; try to remove it */ | |
| 136 | + markobject(&st, &n->key); | |
| 137 | + markobject(&st, &n->val); | |
| 138 | + } | |
| 139 | + } | |
| 140 | + } | |
| 141 | + else break; /* nothing else to mark */ | |
| 142 | + } | |
| 76 | 143 | } |
| 77 | 144 | |
| 78 | 145 | |
| 79 | −static int ismarked (TObject *o) | |
| 80 | −{ | |
| 146 | +static int hasmark (const TObject *o) { | |
| 81 | 147 | /* valid only for locked objects */ |
| 82 | 148 | switch (o->ttype) { |
| 83 | − case LUA_T_STRING: case LUA_T_USERDATA: | |
| 84 | − return o->value.ts->head.marked; | |
| 85 | − case LUA_T_ARRAY: | |
| 86 | − return o->value.a->head.marked; | |
| 87 | − case LUA_T_CLOSURE: | |
| 88 | − return o->value.cl->head.marked; | |
| 89 | − case LUA_T_PROTO: | |
| 90 | − return o->value.tf->head.marked; | |
| 91 | −#ifdef DEBUG | |
| 92 | − case LUA_T_LINE: case LUA_T_CLMARK: | |
| 93 | − case LUA_T_CMARK: case LUA_T_PMARK: | |
| 94 | − LUA_INTERNALERROR("invalid type"); | |
| 95 | −#endif | |
| 96 | − default: /* nil, number or cproto */ | |
| 149 | + case LUA_TSTRING: case LUA_TUSERDATA: | |
| 150 | + return tsvalue(o)->marked; | |
| 151 | + case LUA_TTABLE: | |
| 152 | + return ismarked(hvalue(o)); | |
| 153 | + case LUA_TFUNCTION: | |
| 154 | + return ismarked(clvalue(o)); | |
| 155 | + default: /* number */ | |
| 97 | 156 | return 1; |
| 98 | 157 | } |
| 99 | 158 | } |
| 100 | 159 | |
| 101 | 160 | |
| 102 | −static void invalidaterefs (void) | |
| 103 | −{ | |
| 161 | +/* macro for internal debugging; check if a link of free refs is valid */ | |
| 162 | +#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n)) | |
| 163 | + | |
| 164 | +static void invalidaterefs (lua_State *L) { | |
| 165 | + int n = L->refSize; | |
| 104 | 166 | int i; |
| 105 | − for (i=0; i<L->refSize; i++) | |
| 106 | − if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o)) | |
| 107 | − L->refArray[i].status = COLLECTED; | |
| 167 | + for (i=0; i<n; i++) { | |
| 168 | + struct Ref *r = &L->refArray[i]; | |
| 169 | + if (r->st == HOLD && !hasmark(&r->o)) | |
| 170 | + r->st = COLLECTED; | |
| 171 | + LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) || | |
| 172 | + (r->st == HOLD && hasmark(&r->o)) || | |
| 173 | + r->st == COLLECTED || | |
| 174 | + r->st == NONEXT || | |
| 175 | + (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)), | |
| 176 | + "inconsistent ref table"); | |
| 177 | + } | |
| 178 | + LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table"); | |
| 108 | 179 | } |
| 109 | 180 | |
| 110 | 181 | |
| 111 | 182 | |
| 112 | −void luaC_hashcallIM (Hash *l) | |
| 113 | −{ | |
| 114 | − TObject t; | |
| 115 | − ttype(&t) = LUA_T_ARRAY; | |
| 116 | − for (; l; l=(Hash *)l->head.next) { | |
| 117 | − avalue(&t) = l; | |
| 118 | − luaD_gcIM(&t); | |
| 183 | +static void collectproto (lua_State *L) { | |
| 184 | + Proto **p = &L->rootproto; | |
| 185 | + Proto *next; | |
| 186 | + while ((next = *p) != NULL) { | |
| 187 | + if (next->marked) { | |
| 188 | + next->marked = 0; | |
| 189 | + p = &next->next; | |
| 190 | + } | |
| 191 | + else { | |
| 192 | + *p = next->next; | |
| 193 | + luaF_freeproto(L, next); | |
| 194 | + } | |
| 119 | 195 | } |
| 120 | 196 | } |
| 121 | 197 | |
| 122 | 198 | |
| 123 | −void luaC_strcallIM (TaggedString *l) | |
| 124 | −{ | |
| 125 | − TObject o; | |
| 126 | − ttype(&o) = LUA_T_USERDATA; | |
| 127 | − for (; l; l=(TaggedString *)l->head.next) | |
| 128 | − if (l->constindex == -1) { /* is userdata? */ | |
| 129 | − tsvalue(&o) = l; | |
| 130 | − luaD_gcIM(&o); | |
| 199 | +static void collectclosure (lua_State *L) { | |
| 200 | + Closure **p = &L->rootcl; | |
| 201 | + Closure *next; | |
| 202 | + while ((next = *p) != NULL) { | |
| 203 | + if (ismarked(next)) { | |
| 204 | + next->mark = next; /* unmark */ | |
| 205 | + p = &next->next; | |
| 206 | + } | |
| 207 | + else { | |
| 208 | + *p = next->next; | |
| 209 | + luaF_freeclosure(L, next); | |
| 131 | 210 | } |
| 211 | + } | |
| 132 | 212 | } |
| 133 | 213 | |
| 134 | 214 | |
| 135 | − | |
| 136 | −static GCnode *listcollect (GCnode *l) | |
| 137 | −{ | |
| 138 | − GCnode *frees = NULL; | |
| 139 | − while (l) { | |
| 140 | − GCnode *next = l->next; | |
| 141 | − l->marked = 0; | |
| 142 | − while (next && !next->marked) { | |
| 143 | − l->next = next->next; | |
| 144 | − next->next = frees; | |
| 145 | − frees = next; | |
| 146 | − next = l->next; | |
| 215 | +static void collecttable (lua_State *L) { | |
| 216 | + Hash **p = &L->roottable; | |
| 217 | + Hash *next; | |
| 218 | + while ((next = *p) != NULL) { | |
| 219 | + if (ismarked(next)) { | |
| 220 | + next->mark = next; /* unmark */ | |
| 221 | + p = &next->next; | |
| 222 | + } | |
| 223 | + else { | |
| 224 | + *p = next->next; | |
| 225 | + luaH_free(L, next); | |
| 147 | 226 | } |
| 148 | − l = next; | |
| 149 | 227 | } |
| 150 | − return frees; | |
| 151 | 228 | } |
| 152 | 229 | |
| 153 | 230 | |
| 154 | −static void strmark (TaggedString *s) | |
| 155 | −{ | |
| 156 | − if (!s->head.marked) | |
| 157 | − s->head.marked = 1; | |
| 231 | +static void checktab (lua_State *L, stringtable *tb) { | |
| 232 | + if (tb->nuse < (lint32)(tb->size/4) && tb->size > 10) | |
| 233 | + luaS_resize(L, tb, tb->size/2); /* table is too big */ | |
| 158 | 234 | } |
| 159 | 235 | |
| 160 | 236 | |
| 161 | −static void protomark (TProtoFunc *f) { | |
| 162 | − if (!f->head.marked) { | |
| 163 | − int i; | |
| 164 | − f->head.marked = 1; | |
| 165 | − strmark(f->source); | |
| 166 | − for (i=0; i<f->nconsts; i++) | |
| 167 | − markobject(&f->consts[i]); | |
| 237 | +static void collectstrings (lua_State *L, int all) { | |
| 238 | + int i; | |
| 239 | + for (i=0; i<L->strt.size; i++) { /* for each list */ | |
| 240 | + TString **p = &L->strt.hash[i]; | |
| 241 | + TString *next; | |
| 242 | + while ((next = *p) != NULL) { | |
| 243 | + if (next->marked && !all) { /* preserve? */ | |
| 244 | + if (next->marked < FIXMARK) /* does not change FIXMARKs */ | |
| 245 | + next->marked = 0; | |
| 246 | + p = &next->nexthash; | |
| 247 | + } | |
| 248 | + else { /* collect */ | |
| 249 | + *p = next->nexthash; | |
| 250 | + L->strt.nuse--; | |
| 251 | + L->nblocks -= sizestring(next->len); | |
| 252 | + luaM_free(L, next); | |
| 253 | + } | |
| 254 | + } | |
| 168 | 255 | } |
| 256 | + checktab(L, &L->strt); | |
| 169 | 257 | } |
| 170 | 258 | |
| 171 | 259 | |
| 172 | −static void closuremark (Closure *f) | |
| 173 | −{ | |
| 174 | − if (!f->head.marked) { | |
| 175 | − int i; | |
| 176 | − f->head.marked = 1; | |
| 177 | − for (i=f->nelems; i>=0; i--) | |
| 178 | − markobject(&f->consts[i]); | |
| 260 | +static void collectudata (lua_State *L, int all) { | |
| 261 | + int i; | |
| 262 | + for (i=0; i<L->udt.size; i++) { /* for each list */ | |
| 263 | + TString **p = &L->udt.hash[i]; | |
| 264 | + TString *next; | |
| 265 | + while ((next = *p) != NULL) { | |
| 266 | + LUA_ASSERT(next->marked <= 1, "udata cannot be fixed"); | |
| 267 | + if (next->marked && !all) { /* preserve? */ | |
| 268 | + next->marked = 0; | |
| 269 | + p = &next->nexthash; | |
| 270 | + } | |
| 271 | + else { /* collect */ | |
| 272 | + int tag = next->u.d.tag; | |
| 273 | + *p = next->nexthash; | |
| 274 | + next->nexthash = L->TMtable[tag].collected; /* chain udata */ | |
| 275 | + L->TMtable[tag].collected = next; | |
| 276 | + L->nblocks -= sizestring(next->len); | |
| 277 | + L->udt.nuse--; | |
| 278 | + } | |
| 279 | + } | |
| 179 | 280 | } |
| 281 | + checktab(L, &L->udt); | |
| 180 | 282 | } |
| 181 | 283 | |
| 182 | 284 | |
| 183 | −static void hashmark (Hash *h) | |
| 184 | −{ | |
| 185 | − if (!h->head.marked) { | |
| 186 | − int i; | |
| 187 | − h->head.marked = 1; | |
| 188 | − for (i=0; i<nhash(h); i++) { | |
| 189 | − Node *n = node(h,i); | |
| 190 | − if (ttype(ref(n)) != LUA_T_NIL) { | |
| 191 | − markobject(&n->ref); | |
| 192 | − markobject(&n->val); | |
| 193 | − } | |
| 194 | − } | |
| 285 | +#define MINBUFFER 256 | |
| 286 | +static void checkMbuffer (lua_State *L) { | |
| 287 | + if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */ | |
| 288 | + size_t newsize = L->Mbuffsize/2; /* still larger than MINBUFFER */ | |
| 289 | + L->nblocks += (newsize - L->Mbuffsize)*sizeof(char); | |
| 290 | + L->Mbuffsize = newsize; | |
| 291 | + luaM_reallocvector(L, L->Mbuffer, newsize, char); | |
| 195 | 292 | } |
| 196 | 293 | } |
| 197 | 294 | |
| 198 | 295 | |
| 199 | −static void globalmark (void) | |
| 200 | −{ | |
| 201 | − TaggedString *g; | |
| 202 | − for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next){ | |
| 203 | − LUA_ASSERT(g->constindex >= 0, "userdata in global list"); | |
| 204 | − if (g->u.s.globalval.ttype != LUA_T_NIL) { | |
| 205 | − markobject(&g->u.s.globalval); | |
| 206 | − strmark(g); /* cannot collect non nil global variables */ | |
| 207 | − } | |
| 296 | +static void callgcTM (lua_State *L, const TObject *o) { | |
| 297 | + Closure *tm = luaT_gettmbyObj(L, o, TM_GC); | |
| 298 | + if (tm != NULL) { | |
| 299 | + int oldah = L->allowhooks; | |
| 300 | + L->allowhooks = 0; /* stop debug hooks during GC tag methods */ | |
| 301 | + luaD_checkstack(L, 2); | |
| 302 | + clvalue(L->top) = tm; | |
| 303 | + ttype(L->top) = LUA_TFUNCTION; | |
| 304 | + *(L->top+1) = *o; | |
| 305 | + L->top += 2; | |
| 306 | + luaD_call(L, L->top-2, 0); | |
| 307 | + L->allowhooks = oldah; /* restore hooks */ | |
| 208 | 308 | } |
| 209 | 309 | } |
| 210 | 310 | |
| 211 | 311 | |
| 212 | −static int markobject (TObject *o) | |
| 213 | −{ | |
| 214 | − switch (ttype(o)) { | |
| 215 | − case LUA_T_USERDATA: case LUA_T_STRING: | |
| 216 | − strmark(tsvalue(o)); | |
| 217 | − break; | |
| 218 | − case LUA_T_ARRAY: | |
| 219 | − hashmark(avalue(o)); | |
| 220 | − break; | |
| 221 | − case LUA_T_CLOSURE: case LUA_T_CLMARK: | |
| 222 | − closuremark(o->value.cl); | |
| 223 | − break; | |
| 224 | − case LUA_T_PROTO: case LUA_T_PMARK: | |
| 225 | − protomark(o->value.tf); | |
| 226 | − break; | |
| 227 | − default: break; /* numbers, cprotos, etc */ | |
| 312 | +static void callgcTMudata (lua_State *L) { | |
| 313 | + int tag; | |
| 314 | + TObject o; | |
| 315 | + ttype(&o) = LUA_TUSERDATA; | |
| 316 | + L->GCthreshold = 2*L->nblocks; /* avoid GC during tag methods */ | |
| 317 | + for (tag=L->last_tag; tag>=0; tag--) { /* for each tag (in reverse order) */ | |
| 318 | + TString *udata; | |
| 319 | + while ((udata = L->TMtable[tag].collected) != NULL) { | |
| 320 | + L->TMtable[tag].collected = udata->nexthash; /* remove it from list */ | |
| 321 | + tsvalue(&o) = udata; | |
| 322 | + callgcTM(L, &o); | |
| 323 | + luaM_free(L, udata); | |
| 324 | + } | |
| 228 | 325 | } |
| 229 | − return 0; | |
| 230 | 326 | } |
| 231 | 327 | |
| 232 | 328 | |
| 233 | − | |
| 234 | −static void markall (void) | |
| 235 | −{ | |
| 236 | − luaD_travstack(markobject); /* mark stack objects */ | |
| 237 | − globalmark(); /* mark global variable values and names */ | |
| 238 | − travlock(); /* mark locked objects */ | |
| 239 | − luaT_travtagmethods(markobject); /* mark fallbacks */ | |
| 329 | +void luaC_collect (lua_State *L, int all) { | |
| 330 | + collectudata(L, all); | |
| 331 | + callgcTMudata(L); | |
| 332 | + collectstrings(L, all); | |
| 333 | + collecttable(L); | |
| 334 | + collectproto(L); | |
| 335 | + collectclosure(L); | |
| 240 | 336 | } |
| 241 | 337 | |
| 242 | 338 | |
| 243 | −long lua_collectgarbage (long limit) | |
| 244 | −{ | |
| 245 | − unsigned long recovered = L->nblocks; /* to subtract nblocks after gc */ | |
| 246 | − Hash *freetable; | |
| 247 | − TaggedString *freestr; | |
| 248 | − TProtoFunc *freefunc; | |
| 249 | − Closure *freeclos; | |
| 250 | − markall(); | |
| 251 | − invalidaterefs(); | |
| 252 | − freestr = luaS_collector(); | |
| 253 | − freetable = (Hash *)listcollect(&(L->roottable)); | |
| 254 | − freefunc = (TProtoFunc *)listcollect(&(L->rootproto)); | |
| 255 | − freeclos = (Closure *)listcollect(&(L->rootcl)); | |
| 256 | − L->GCthreshold *= 4; /* to avoid GC during GC */ | |
| 257 | − luaC_hashcallIM(freetable); /* GC tag methods for tables */ | |
| 258 | − luaC_strcallIM(freestr); /* GC tag methods for userdata */ | |
| 259 | − luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */ | |
| 260 | − luaH_free(freetable); | |
| 261 | − luaS_free(freestr); | |
| 262 | − luaF_freeproto(freefunc); | |
| 263 | − luaF_freeclosure(freeclos); | |
| 264 | − recovered = recovered-L->nblocks; | |
| 265 | − L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; | |
| 266 | − return recovered; | |
| 339 | +static void luaC_collectgarbage (lua_State *L) { | |
| 340 | + markall(L); | |
| 341 | + invalidaterefs(L); /* check unlocked references */ | |
| 342 | + luaC_collect(L, 0); | |
| 343 | + checkMbuffer(L); | |
| 344 | + L->GCthreshold = 2*L->nblocks; /* set new threshold */ | |
| 345 | + callgcTM(L, &luaO_nilobject); | |
| 267 | 346 | } |
| 268 | 347 | |
| 269 | 348 | |
| 270 | −void luaC_checkGC (void) | |
| 271 | −{ | |
| 349 | +void luaC_checkGC (lua_State *L) { | |
| 272 | 350 | if (L->nblocks >= L->GCthreshold) |
| 273 | − lua_collectgarbage(0); | |
| 351 | + luaC_collectgarbage(L); | |
| 274 | 352 | } |
| 275 | 353 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lgc.h,v 1.4 1997/12/01 20:31:25 roberto Exp $ | |
| 2 | +** $Id: lgc.h,v 1.8 2000/10/02 14:47:43 roberto Exp $ | |
| 3 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -11,11 +11,8 @@ · 5 unmodified lines | ||
| 11 | 11 | #include "lobject.h" |
| 12 | 12 | |
| 13 | 13 | |
| 14 | −void luaC_checkGC (void); | |
| 15 | −TObject* luaC_getref (int ref); | |
| 16 | −int luaC_ref (TObject *o, int lock); | |
| 17 | −void luaC_hashcallIM (Hash *l); | |
| 18 | −void luaC_strcallIM (TaggedString *l); | |
| 14 | +void luaC_collect (lua_State *L, int all); | |
| 15 | +void luaC_checkGC (lua_State *L); | |
| 19 | 16 | |
| 20 | 17 | |
| 21 | 18 | #endif |
| @@ -1,4 +1,4 @@ | ||
| 1 | −# makefile for lua standard library | |
| 1 | +# makefile for Lua standard library | |
| 2 | 2 | |
| 3 | 3 | LUA= ../.. |
| 4 | 4 | |
| @@ -7,8 +7,8 @@ include $(LUA)/config · 2 unmodified lines | ||
| 7 | 7 | # actually only used in liolib.c |
| 8 | 8 | EXTRA_DEFS= $(POPEN) |
| 9 | 9 | |
| 10 | −OBJS= linit.o ldblib.o liolib.o lmathlib.o lstrlib.o | |
| 11 | −SRCS= linit.c ldblib.c liolib.c lmathlib.c lstrlib.c | |
| 10 | +OBJS= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o lstrlib.o | |
| 11 | +SRCS= lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c lstrlib.c | |
| 12 | 12 | |
| 13 | 13 | T= $(LIB)/liblualib.a |
| 14 | 14 | |
| @@ -1,4 +1,6 @@ | ||
| 1 | 1 | This is the standard Lua library. |
| 2 | 2 | It is implemented entirely on top of the official Lua API as declared in lua.h, |
| 3 | −using src/lauxlib.c, which contains several useful functions. | |
| 4 | −The code can be read as an example of how to export C functions to Lua. | |
| 3 | +using lauxlib.c, which contains several useful functions for writing libraries. | |
| 4 | +We encourage developers to use lauxlib.c in their own libraries. | |
| 5 | +The code of the standard library can be read as an example of how to export | |
| 6 | +C functions to Lua. | |
| @@ -0,0 +1,216 @@ | ||
| 1 | +/* | |
| 2 | +** $Id: lauxlib.c,v 1.43 2000/10/30 13:07:48 roberto Exp $ | |
| 3 | +** Auxiliary functions for building Lua libraries | |
| 4 | +** See Copyright Notice in lua.h | |
| 5 | +*/ | |
| 6 | + | |
| 7 | + | |
| 8 | +#include <stdarg.h> | |
| 9 | +#include <stdio.h> | |
| 10 | +#include <string.h> | |
| 11 | + | |
| 12 | +/* This file uses only the official API of Lua. | |
| 13 | +** Any function declared here could be written as an application function. | |
| 14 | +** With care, these functions can be used by other libraries. | |
| 15 | +*/ | |
| 16 | + | |
| 17 | +#include "lua.h" | |
| 18 | + | |
| 19 | +#include "lauxlib.h" | |
| 20 | +#include "luadebug.h" | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | +LUALIB_API int luaL_findstring (const char *name, const char *const list[]) { | |
| 25 | + int i; | |
| 26 | + for (i=0; list[i]; i++) | |
| 27 | + if (strcmp(list[i], name) == 0) | |
| 28 | + return i; | |
| 29 | + return -1; /* name not found */ | |
| 30 | +} | |
| 31 | + | |
| 32 | +LUALIB_API void luaL_argerror (lua_State *L, int narg, const char *extramsg) { | |
| 33 | + lua_Debug ar; | |
| 34 | + lua_getstack(L, 0, &ar); | |
| 35 | + lua_getinfo(L, "n", &ar); | |
| 36 | + if (ar.name == NULL) | |
| 37 | + ar.name = "?"; | |
| 38 | + luaL_verror(L, "bad argument #%d to `%.50s' (%.100s)", | |
| 39 | + narg, ar.name, extramsg); | |
| 40 | +} | |
| 41 | + | |
| 42 | + | |
| 43 | +static void type_error (lua_State *L, int narg, int t) { | |
| 44 | + char buff[50]; | |
| 45 | + sprintf(buff, "%.8s expected, got %.8s", lua_typename(L, t), | |
| 46 | + lua_typename(L, lua_type(L, narg))); | |
| 47 | + luaL_argerror(L, narg, buff); | |
| 48 | +} | |
| 49 | + | |
| 50 | + | |
| 51 | +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { | |
| 52 | + if (space > lua_stackspace(L)) | |
| 53 | + luaL_verror(L, "stack overflow (%.30s)", mes); | |
| 54 | +} | |
| 55 | + | |
| 56 | + | |
| 57 | +LUALIB_API void luaL_checktype(lua_State *L, int narg, int t) { | |
| 58 | + if (lua_type(L, narg) != t) | |
| 59 | + type_error(L, narg, t); | |
| 60 | +} | |
| 61 | + | |
| 62 | + | |
| 63 | +LUALIB_API void luaL_checkany (lua_State *L, int narg) { | |
| 64 | + if (lua_type(L, narg) == LUA_TNONE) | |
| 65 | + luaL_argerror(L, narg, "value expected"); | |
| 66 | +} | |
| 67 | + | |
| 68 | + | |
| 69 | +LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) { | |
| 70 | + const char *s = lua_tostring(L, narg); | |
| 71 | + if (!s) type_error(L, narg, LUA_TSTRING); | |
| 72 | + if (len) *len = lua_strlen(L, narg); | |
| 73 | + return s; | |
| 74 | +} | |
| 75 | + | |
| 76 | + | |
| 77 | +LUALIB_API const char *luaL_opt_lstr (lua_State *L, int narg, const char *def, size_t *len) { | |
| 78 | + if (lua_isnull(L, narg)) { | |
| 79 | + if (len) | |
| 80 | + *len = (def ? strlen(def) : 0); | |
| 81 | + return def; | |
| 82 | + } | |
| 83 | + else return luaL_check_lstr(L, narg, len); | |
| 84 | +} | |
| 85 | + | |
| 86 | + | |
| 87 | +LUALIB_API double luaL_check_number (lua_State *L, int narg) { | |
| 88 | + double d = lua_tonumber(L, narg); | |
| 89 | + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ | |
| 90 | + type_error(L, narg, LUA_TNUMBER); | |
| 91 | + return d; | |
| 92 | +} | |
| 93 | + | |
| 94 | + | |
| 95 | +LUALIB_API double luaL_opt_number (lua_State *L, int narg, double def) { | |
| 96 | + if (lua_isnull(L, narg)) return def; | |
| 97 | + else return luaL_check_number(L, narg); | |
| 98 | +} | |
| 99 | + | |
| 100 | + | |
| 101 | +LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n) { | |
| 102 | + int i; | |
| 103 | + for (i=0; i<n; i++) | |
| 104 | + lua_register(L, l[i].name, l[i].func); | |
| 105 | +} | |
| 106 | + | |
| 107 | + | |
| 108 | +LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...) { | |
| 109 | + char buff[500]; | |
| 110 | + va_list argp; | |
| 111 | + va_start(argp, fmt); | |
| 112 | + vsprintf(buff, fmt, argp); | |
| 113 | + va_end(argp); | |
| 114 | + lua_error(L, buff); | |
| 115 | +} | |
| 116 | + | |
| 117 | + | |
| 118 | +/* | |
| 119 | +** {====================================================== | |
| 120 | +** Generic Buffer manipulation | |
| 121 | +** ======================================================= | |
| 122 | +*/ | |
| 123 | + | |
| 124 | + | |
| 125 | +#define buffempty(B) ((B)->p == (B)->buffer) | |
| 126 | +#define bufflen(B) ((B)->p - (B)->buffer) | |
| 127 | +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) | |
| 128 | + | |
| 129 | +#define LIMIT (LUA_MINSTACK/2) | |
| 130 | + | |
| 131 | + | |
| 132 | +static int emptybuffer (luaL_Buffer *B) { | |
| 133 | + size_t l = bufflen(B); | |
| 134 | + if (l == 0) return 0; /* put nothing on stack */ | |
| 135 | + else { | |
| 136 | + lua_pushlstring(B->L, B->buffer, l); | |
| 137 | + B->p = B->buffer; | |
| 138 | + B->level++; | |
| 139 | + return 1; | |
| 140 | + } | |
| 141 | +} | |
| 142 | + | |
| 143 | + | |
| 144 | +static void adjuststack (luaL_Buffer *B) { | |
| 145 | + if (B->level > 1) { | |
| 146 | + lua_State *L = B->L; | |
| 147 | + int toget = 1; /* number of levels to concat */ | |
| 148 | + size_t toplen = lua_strlen(L, -1); | |
| 149 | + do { | |
| 150 | + size_t l = lua_strlen(L, -(toget+1)); | |
| 151 | + if (B->level - toget + 1 >= LIMIT || toplen > l) { | |
| 152 | + toplen += l; | |
| 153 | + toget++; | |
| 154 | + } | |
| 155 | + else break; | |
| 156 | + } while (toget < B->level); | |
| 157 | + if (toget >= 2) { | |
| 158 | + lua_concat(L, toget); | |
| 159 | + B->level = B->level - toget + 1; | |
| 160 | + } | |
| 161 | + } | |
| 162 | +} | |
| 163 | + | |
| 164 | + | |
| 165 | +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { | |
| 166 | + if (emptybuffer(B)) | |
| 167 | + adjuststack(B); | |
| 168 | + return B->buffer; | |
| 169 | +} | |
| 170 | + | |
| 171 | + | |
| 172 | +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { | |
| 173 | + while (l--) | |
| 174 | + luaL_putchar(B, *s++); | |
| 175 | +} | |
| 176 | + | |
| 177 | + | |
| 178 | +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { | |
| 179 | + luaL_addlstring(B, s, strlen(s)); | |
| 180 | +} | |
| 181 | + | |
| 182 | + | |
| 183 | +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { | |
| 184 | + emptybuffer(B); | |
| 185 | + if (B->level == 0) | |
| 186 | + lua_pushlstring(B->L, NULL, 0); | |
| 187 | + else if (B->level > 1) | |
| 188 | + lua_concat(B->L, B->level); | |
| 189 | + B->level = 1; | |
| 190 | +} | |
| 191 | + | |
| 192 | + | |
| 193 | +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { | |
| 194 | + lua_State *L = B->L; | |
| 195 | + size_t vl = lua_strlen(L, -1); | |
| 196 | + if (vl <= bufffree(B)) { /* fit into buffer? */ | |
| 197 | + memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */ | |
| 198 | + B->p += vl; | |
| 199 | + lua_pop(L, 1); /* remove from stack */ | |
| 200 | + } | |
| 201 | + else { | |
| 202 | + if (emptybuffer(B)) | |
| 203 | + lua_insert(L, -2); /* put buffer before new value */ | |
| 204 | + B->level++; /* add new value into B stack */ | |
| 205 | + adjuststack(B); | |
| 206 | + } | |
| 207 | +} | |
| 208 | + | |
| 209 | + | |
| 210 | +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { | |
| 211 | + B->L = L; | |
| 212 | + B->p = B->buffer; | |
| 213 | + B->level = 0; | |
| 214 | +} | |
| 215 | + | |
| 216 | +/* }====================================================== */ | |
| @@ -0,0 +1,651 @@ | ||
| 1 | +/* | |
| 2 | +** $Id: lbaselib.c,v 1.17 2000/11/06 13:45:18 roberto Exp $ | |
| 3 | +** Basic library | |
| 4 | +** See Copyright Notice in lua.h | |
| 5 | +*/ | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | +#include <ctype.h> | |
| 10 | +#include <stdio.h> | |
| 11 | +#include <stdlib.h> | |
| 12 | +#include <string.h> | |
| 13 | + | |
| 14 | +#include "lua.h" | |
| 15 | + | |
| 16 | +#include "lauxlib.h" | |
| 17 | +#include "luadebug.h" | |
| 18 | +#include "lualib.h" | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | +/* | |
| 23 | +** If your system does not support `stderr', redefine this function, or | |
| 24 | +** redefine _ERRORMESSAGE so that it won't need _ALERT. | |
| 25 | +*/ | |
| 26 | +static int luaB__ALERT (lua_State *L) { | |
| 27 | + fputs(luaL_check_string(L, 1), stderr); | |
| 28 | + return 0; | |
| 29 | +} | |
| 30 | + | |
| 31 | + | |
| 32 | +/* | |
| 33 | +** Basic implementation of _ERRORMESSAGE. | |
| 34 | +** The library `liolib' redefines _ERRORMESSAGE for better error information. | |
| 35 | +*/ | |
| 36 | +static int luaB__ERRORMESSAGE (lua_State *L) { | |
| 37 | + luaL_checktype(L, 1, LUA_TSTRING); | |
| 38 | + lua_getglobal(L, LUA_ALERT); | |
| 39 | + if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */ | |
| 40 | + lua_Debug ar; | |
| 41 | + lua_pushstring(L, "error: "); | |
| 42 | + lua_pushvalue(L, 1); | |
| 43 | + if (lua_getstack(L, 1, &ar)) { | |
| 44 | + lua_getinfo(L, "Sl", &ar); | |
| 45 | + if (ar.source && ar.currentline > 0) { | |
| 46 | + char buff[100]; | |
| 47 | + sprintf(buff, "\n <%.70s: line %d>", ar.short_src, ar.currentline); | |
| 48 | + lua_pushstring(L, buff); | |
| 49 | + lua_concat(L, 2); | |
| 50 | + } | |
| 51 | + } | |
| 52 | + lua_pushstring(L, "\n"); | |
| 53 | + lua_concat(L, 3); | |
| 54 | + lua_rawcall(L, 1, 0); | |
| 55 | + } | |
| 56 | + return 0; | |
| 57 | +} | |
| 58 | + | |
| 59 | + | |
| 60 | +/* | |
| 61 | +** If your system does not support `stdout', you can just remove this function. | |
| 62 | +** If you need, you can define your own `print' function, following this | |
| 63 | +** model but changing `fputs' to put the strings at a proper place | |
| 64 | +** (a console window or a log file, for instance). | |
| 65 | +*/ | |
| 66 | +static int luaB_print (lua_State *L) { | |
| 67 | + int n = lua_gettop(L); /* number of arguments */ | |
| 68 | + int i; | |
| 69 | + lua_getglobal(L, "tostring"); | |
| 70 | + for (i=1; i<=n; i++) { | |
| 71 | + const char *s; | |
| 72 | + lua_pushvalue(L, -1); /* function to be called */ | |
| 73 | + lua_pushvalue(L, i); /* value to print */ | |
| 74 | + lua_rawcall(L, 1, 1); | |
| 75 | + s = lua_tostring(L, -1); /* get result */ | |
| 76 | + if (s == NULL) | |
| 77 | + lua_error(L, "`tostring' must return a string to `print'"); | |
| 78 | + if (i>1) fputs("\t", stdout); | |
| 79 | + fputs(s, stdout); | |
| 80 | + lua_pop(L, 1); /* pop result */ | |
| 81 | + } | |
| 82 | + fputs("\n", stdout); | |
| 83 | + return 0; | |
| 84 | +} | |
| 85 | + | |
| 86 | + | |
| 87 | +static int luaB_tonumber (lua_State *L) { | |
| 88 | + int base = luaL_opt_int(L, 2, 10); | |
| 89 | + if (base == 10) { /* standard conversion */ | |
| 90 | + luaL_checkany(L, 1); | |
| 91 | + if (lua_isnumber(L, 1)) { | |
| 92 | + lua_pushnumber(L, lua_tonumber(L, 1)); | |
| 93 | + return 1; | |
| 94 | + } | |
| 95 | + } | |
| 96 | + else { | |
| 97 | + const char *s1 = luaL_check_string(L, 1); | |
| 98 | + char *s2; | |
| 99 | + unsigned long n; | |
| 100 | + luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range"); | |
| 101 | + n = strtoul(s1, &s2, base); | |
| 102 | + if (s1 != s2) { /* at least one valid digit? */ | |
| 103 | + while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */ | |
| 104 | + if (*s2 == '\0') { /* no invalid trailing characters? */ | |
| 105 | + lua_pushnumber(L, n); | |
| 106 | + return 1; | |
| 107 | + } | |
| 108 | + } | |
| 109 | + } | |
| 110 | + lua_pushnil(L); /* else not a number */ | |
| 111 | + return 1; | |
| 112 | +} | |
| 113 | + | |
| 114 | + | |
| 115 | +static int luaB_error (lua_State *L) { | |
| 116 | + lua_error(L, luaL_opt_string(L, 1, NULL)); | |
| 117 | + return 0; /* to avoid warnings */ | |
| 118 | +} | |
| 119 | + | |
| 120 | +static int luaB_setglobal (lua_State *L) { | |
| 121 | + luaL_checkany(L, 2); | |
| 122 | + lua_setglobal(L, luaL_check_string(L, 1)); | |
| 123 | + return 0; | |
| 124 | +} | |
| 125 | + | |
| 126 | +static int luaB_getglobal (lua_State *L) { | |
| 127 | + lua_getglobal(L, luaL_check_string(L, 1)); | |
| 128 | + return 1; | |
| 129 | +} | |
| 130 | + | |
| 131 | +static int luaB_tag (lua_State *L) { | |
| 132 | + luaL_checkany(L, 1); | |
| 133 | + lua_pushnumber(L, lua_tag(L, 1)); | |
| 134 | + return 1; | |
| 135 | +} | |
| 136 | + | |
| 137 | +static int luaB_settag (lua_State *L) { | |
| 138 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 139 | + lua_pushvalue(L, 1); /* push table */ | |
| 140 | + lua_settag(L, luaL_check_int(L, 2)); | |
| 141 | + return 1; /* return table */ | |
| 142 | +} | |
| 143 | + | |
| 144 | +static int luaB_newtag (lua_State *L) { | |
| 145 | + lua_pushnumber(L, lua_newtag(L)); | |
| 146 | + return 1; | |
| 147 | +} | |
| 148 | + | |
| 149 | +static int luaB_copytagmethods (lua_State *L) { | |
| 150 | + lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1), | |
| 151 | + luaL_check_int(L, 2))); | |
| 152 | + return 1; | |
| 153 | +} | |
| 154 | + | |
| 155 | +static int luaB_globals (lua_State *L) { | |
| 156 | + lua_getglobals(L); /* value to be returned */ | |
| 157 | + if (!lua_isnull(L, 1)) { | |
| 158 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 159 | + lua_pushvalue(L, 1); /* new table of globals */ | |
| 160 | + lua_setglobals(L); | |
| 161 | + } | |
| 162 | + return 1; | |
| 163 | +} | |
| 164 | + | |
| 165 | +static int luaB_rawget (lua_State *L) { | |
| 166 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 167 | + luaL_checkany(L, 2); | |
| 168 | + lua_rawget(L, -2); | |
| 169 | + return 1; | |
| 170 | +} | |
| 171 | + | |
| 172 | +static int luaB_rawset (lua_State *L) { | |
| 173 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 174 | + luaL_checkany(L, 2); | |
| 175 | + luaL_checkany(L, 3); | |
| 176 | + lua_rawset(L, -3); | |
| 177 | + return 1; | |
| 178 | +} | |
| 179 | + | |
| 180 | +static int luaB_settagmethod (lua_State *L) { | |
| 181 | + int tag = luaL_check_int(L, 1); | |
| 182 | + const char *event = luaL_check_string(L, 2); | |
| 183 | + luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3, | |
| 184 | + "function or nil expected"); | |
| 185 | + if (strcmp(event, "gc") == 0) | |
| 186 | + lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua"); | |
| 187 | + lua_gettagmethod(L, tag, event); | |
| 188 | + lua_pushvalue(L, 3); | |
| 189 | + lua_settagmethod(L, tag, event); | |
| 190 | + return 1; | |
| 191 | +} | |
| 192 | + | |
| 193 | + | |
| 194 | +static int luaB_gettagmethod (lua_State *L) { | |
| 195 | + int tag = luaL_check_int(L, 1); | |
| 196 | + const char *event = luaL_check_string(L, 2); | |
| 197 | + if (strcmp(event, "gc") == 0) | |
| 198 | + lua_error(L, "deprecated use: cannot get the `gc' tag method from Lua"); | |
| 199 | + lua_gettagmethod(L, tag, event); | |
| 200 | + return 1; | |
| 201 | +} | |
| 202 | + | |
| 203 | + | |
| 204 | +static int luaB_gcinfo (lua_State *L) { | |
| 205 | + lua_pushnumber(L, lua_getgccount(L)); | |
| 206 | + lua_pushnumber(L, lua_getgcthreshold(L)); | |
| 207 | + return 2; | |
| 208 | +} | |
| 209 | + | |
| 210 | + | |
| 211 | +static int luaB_collectgarbage (lua_State *L) { | |
| 212 | + lua_setgcthreshold(L, luaL_opt_int(L, 1, 0)); | |
| 213 | + return 0; | |
| 214 | +} | |
| 215 | + | |
| 216 | + | |
| 217 | +static int luaB_type (lua_State *L) { | |
| 218 | + luaL_checkany(L, 1); | |
| 219 | + lua_pushstring(L, lua_typename(L, lua_type(L, 1))); | |
| 220 | + return 1; | |
| 221 | +} | |
| 222 | + | |
| 223 | + | |
| 224 | +static int luaB_next (lua_State *L) { | |
| 225 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 226 | + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ | |
| 227 | + if (lua_next(L, 1)) | |
| 228 | + return 2; | |
| 229 | + else { | |
| 230 | + lua_pushnil(L); | |
| 231 | + return 1; | |
| 232 | + } | |
| 233 | +} | |
| 234 | + | |
| 235 | + | |
| 236 | +static int passresults (lua_State *L, int status, int oldtop) { | |
| 237 | + static const char *const errornames[] = | |
| 238 | + {"ok", "run-time error", "file error", "syntax error", | |
| 239 | + "memory error", "error in error handling"}; | |
| 240 | + if (status == 0) { | |
| 241 | + int nresults = lua_gettop(L) - oldtop; | |
| 242 | + if (nresults > 0) | |
| 243 | + return nresults; /* results are already on the stack */ | |
| 244 | + else { | |
| 245 | + lua_pushuserdata(L, NULL); /* at least one result to signal no errors */ | |
| 246 | + return 1; | |
| 247 | + } | |
| 248 | + } | |
| 249 | + else { /* error */ | |
| 250 | + lua_pushnil(L); | |
| 251 | + lua_pushstring(L, errornames[status]); /* error code */ | |
| 252 | + return 2; | |
| 253 | + } | |
| 254 | +} | |
| 255 | + | |
| 256 | +static int luaB_dostring (lua_State *L) { | |
| 257 | + int oldtop = lua_gettop(L); | |
| 258 | + size_t l; | |
| 259 | + const char *s = luaL_check_lstr(L, 1, &l); | |
| 260 | + if (*s == '\27') /* binary files start with ESC... */ | |
| 261 | + lua_error(L, "`dostring' cannot run pre-compiled code"); | |
| 262 | + return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop); | |
| 263 | +} | |
| 264 | + | |
| 265 | + | |
| 266 | +static int luaB_dofile (lua_State *L) { | |
| 267 | + int oldtop = lua_gettop(L); | |
| 268 | + const char *fname = luaL_opt_string(L, 1, NULL); | |
| 269 | + return passresults(L, lua_dofile(L, fname), oldtop); | |
| 270 | +} | |
| 271 | + | |
| 272 | + | |
| 273 | +static int luaB_call (lua_State *L) { | |
| 274 | + int oldtop; | |
| 275 | + const char *options = luaL_opt_string(L, 3, ""); | |
| 276 | + int err = 0; /* index of old error method */ | |
| 277 | + int i, status; | |
| 278 | + int n; | |
| 279 | + luaL_checktype(L, 2, LUA_TTABLE); | |
| 280 | + n = lua_getn(L, 2); | |
| 281 | + if (!lua_isnull(L, 4)) { /* set new error method */ | |
| 282 | + lua_getglobal(L, LUA_ERRORMESSAGE); | |
| 283 | + err = lua_gettop(L); /* get index */ | |
| 284 | + lua_pushvalue(L, 4); | |
| 285 | + lua_setglobal(L, LUA_ERRORMESSAGE); | |
| 286 | + } | |
| 287 | + oldtop = lua_gettop(L); /* top before function-call preparation */ | |
| 288 | + /* push function */ | |
| 289 | + lua_pushvalue(L, 1); | |
| 290 | + luaL_checkstack(L, n, "too many arguments"); | |
| 291 | + for (i=0; i<n; i++) /* push arg[1...n] */ | |
| 292 | + lua_rawgeti(L, 2, i+1); | |
| 293 | + status = lua_call(L, n, LUA_MULTRET); | |
| 294 | + if (err != 0) { /* restore old error method */ | |
| 295 | + lua_pushvalue(L, err); | |
| 296 | + lua_setglobal(L, LUA_ERRORMESSAGE); | |
| 297 | + } | |
| 298 | + if (status != 0) { /* error in call? */ | |
| 299 | + if (strchr(options, 'x')) | |
| 300 | + lua_pushnil(L); /* return nil to signal the error */ | |
| 301 | + else | |
| 302 | + lua_error(L, NULL); /* propagate error without additional messages */ | |
| 303 | + return 1; | |
| 304 | + } | |
| 305 | + if (strchr(options, 'p')) /* pack results? */ | |
| 306 | + lua_error(L, "deprecated option `p' in `call'"); | |
| 307 | + return lua_gettop(L) - oldtop; /* results are already on the stack */ | |
| 308 | +} | |
| 309 | + | |
| 310 | + | |
| 311 | +static int luaB_tostring (lua_State *L) { | |
| 312 | + char buff[64]; | |
| 313 | + switch (lua_type(L, 1)) { | |
| 314 | + case LUA_TNUMBER: | |
| 315 | + lua_pushstring(L, lua_tostring(L, 1)); | |
| 316 | + return 1; | |
| 317 | + case LUA_TSTRING: | |
| 318 | + lua_pushvalue(L, 1); | |
| 319 | + return 1; | |
| 320 | + case LUA_TTABLE: | |
| 321 | + sprintf(buff, "table: %p", lua_topointer(L, 1)); | |
| 322 | + break; | |
| 323 | + case LUA_TFUNCTION: | |
| 324 | + sprintf(buff, "function: %p", lua_topointer(L, 1)); | |
| 325 | + break; | |
| 326 | + case LUA_TUSERDATA: | |
| 327 | + sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1)); | |
| 328 | + break; | |
| 329 | + case LUA_TNIL: | |
| 330 | + lua_pushstring(L, "nil"); | |
| 331 | + return 1; | |
| 332 | + default: | |
| 333 | + luaL_argerror(L, 1, "value expected"); | |
| 334 | + } | |
| 335 | + lua_pushstring(L, buff); | |
| 336 | + return 1; | |
| 337 | +} | |
| 338 | + | |
| 339 | + | |
| 340 | +static int luaB_foreachi (lua_State *L) { | |
| 341 | + int n, i; | |
| 342 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 343 | + luaL_checktype(L, 2, LUA_TFUNCTION); | |
| 344 | + n = lua_getn(L, 1); | |
| 345 | + for (i=1; i<=n; i++) { | |
| 346 | + lua_pushvalue(L, 2); /* function */ | |
| 347 | + lua_pushnumber(L, i); /* 1st argument */ | |
| 348 | + lua_rawgeti(L, 1, i); /* 2nd argument */ | |
| 349 | + lua_rawcall(L, 2, 1); | |
| 350 | + if (!lua_isnil(L, -1)) | |
| 351 | + return 1; | |
| 352 | + lua_pop(L, 1); /* remove nil result */ | |
| 353 | + } | |
| 354 | + return 0; | |
| 355 | +} | |
| 356 | + | |
| 357 | + | |
| 358 | +static int luaB_foreach (lua_State *L) { | |
| 359 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 360 | + luaL_checktype(L, 2, LUA_TFUNCTION); | |
| 361 | + lua_pushnil(L); /* first index */ | |
| 362 | + for (;;) { | |
| 363 | + if (lua_next(L, 1) == 0) | |
| 364 | + return 0; | |
| 365 | + lua_pushvalue(L, 2); /* function */ | |
| 366 | + lua_pushvalue(L, -3); /* key */ | |
| 367 | + lua_pushvalue(L, -3); /* value */ | |
| 368 | + lua_rawcall(L, 2, 1); | |
| 369 | + if (!lua_isnil(L, -1)) | |
| 370 | + return 1; | |
| 371 | + lua_pop(L, 2); /* remove value and result */ | |
| 372 | + } | |
| 373 | +} | |
| 374 | + | |
| 375 | + | |
| 376 | +static int luaB_assert (lua_State *L) { | |
| 377 | + luaL_checkany(L, 1); | |
| 378 | + if (lua_isnil(L, 1)) | |
| 379 | + luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, "")); | |
| 380 | + return 0; | |
| 381 | +} | |
| 382 | + | |
| 383 | + | |
| 384 | +static int luaB_getn (lua_State *L) { | |
| 385 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 386 | + lua_pushnumber(L, lua_getn(L, 1)); | |
| 387 | + return 1; | |
| 388 | +} | |
| 389 | + | |
| 390 | + | |
| 391 | +static int luaB_tinsert (lua_State *L) { | |
| 392 | + int v = lua_gettop(L); /* last argument: to be inserted */ | |
| 393 | + int n, pos; | |
| 394 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 395 | + n = lua_getn(L, 1); | |
| 396 | + if (v == 2) /* called with only 2 arguments */ | |
| 397 | + pos = n+1; | |
| 398 | + else | |
| 399 | + pos = luaL_check_int(L, 2); /* 2nd argument is the position */ | |
| 400 | + lua_pushstring(L, "n"); | |
| 401 | + lua_pushnumber(L, n+1); | |
| 402 | + lua_rawset(L, 1); /* t.n = n+1 */ | |
| 403 | + for (; n>=pos; n--) { | |
| 404 | + lua_rawgeti(L, 1, n); | |
| 405 | + lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ | |
| 406 | + } | |
| 407 | + lua_pushvalue(L, v); | |
| 408 | + lua_rawseti(L, 1, pos); /* t[pos] = v */ | |
| 409 | + return 0; | |
| 410 | +} | |
| 411 | + | |
| 412 | + | |
| 413 | +static int luaB_tremove (lua_State *L) { | |
| 414 | + int pos, n; | |
| 415 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 416 | + n = lua_getn(L, 1); | |
| 417 | + pos = luaL_opt_int(L, 2, n); | |
| 418 | + if (n <= 0) return 0; /* table is "empty" */ | |
| 419 | + lua_rawgeti(L, 1, pos); /* result = t[pos] */ | |
| 420 | + for ( ;pos<n; pos++) { | |
| 421 | + lua_rawgeti(L, 1, pos+1); | |
| 422 | + lua_rawseti(L, 1, pos); /* a[pos] = a[pos+1] */ | |
| 423 | + } | |
| 424 | + lua_pushstring(L, "n"); | |
| 425 | + lua_pushnumber(L, n-1); | |
| 426 | + lua_rawset(L, 1); /* t.n = n-1 */ | |
| 427 | + lua_pushnil(L); | |
| 428 | + lua_rawseti(L, 1, n); /* t[n] = nil */ | |
| 429 | + return 1; | |
| 430 | +} | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | +/* | |
| 436 | +** {====================================================== | |
| 437 | +** Quicksort | |
| 438 | +** (based on `Algorithms in MODULA-3', Robert Sedgewick; | |
| 439 | +** Addison-Wesley, 1993.) | |
| 440 | +*/ | |
| 441 | + | |
| 442 | + | |
| 443 | +static void set2 (lua_State *L, int i, int j) { | |
| 444 | + lua_rawseti(L, 1, i); | |
| 445 | + lua_rawseti(L, 1, j); | |
| 446 | +} | |
| 447 | + | |
| 448 | +static int sort_comp (lua_State *L, int a, int b) { | |
| 449 | + /* WARNING: the caller (auxsort) must ensure stack space */ | |
| 450 | + if (!lua_isnil(L, 2)) { /* function? */ | |
| 451 | + int res; | |
| 452 | + lua_pushvalue(L, 2); | |
| 453 | + lua_pushvalue(L, a-1); /* -1 to compensate function */ | |
| 454 | + lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ | |
| 455 | + lua_rawcall(L, 2, 1); | |
| 456 | + res = !lua_isnil(L, -1); | |
| 457 | + lua_pop(L, 1); | |
| 458 | + return res; | |
| 459 | + } | |
| 460 | + else /* a < b? */ | |
| 461 | + return lua_lessthan(L, a, b); | |
| 462 | +} | |
| 463 | + | |
| 464 | +static void auxsort (lua_State *L, int l, int u) { | |
| 465 | + while (l < u) { /* for tail recursion */ | |
| 466 | + int i, j; | |
| 467 | + /* sort elements a[l], a[(l+u)/2] and a[u] */ | |
| 468 | + lua_rawgeti(L, 1, l); | |
| 469 | + lua_rawgeti(L, 1, u); | |
| 470 | + if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ | |
| 471 | + set2(L, l, u); /* swap a[l] - a[u] */ | |
| 472 | + else | |
| 473 | + lua_pop(L, 2); | |
| 474 | + if (u-l == 1) break; /* only 2 elements */ | |
| 475 | + i = (l+u)/2; | |
| 476 | + lua_rawgeti(L, 1, i); | |
| 477 | + lua_rawgeti(L, 1, l); | |
| 478 | + if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */ | |
| 479 | + set2(L, i, l); | |
| 480 | + else { | |
| 481 | + lua_pop(L, 1); /* remove a[l] */ | |
| 482 | + lua_rawgeti(L, 1, u); | |
| 483 | + if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */ | |
| 484 | + set2(L, i, u); | |
| 485 | + else | |
| 486 | + lua_pop(L, 2); | |
| 487 | + } | |
| 488 | + if (u-l == 2) break; /* only 3 elements */ | |
| 489 | + lua_rawgeti(L, 1, i); /* Pivot */ | |
| 490 | + lua_pushvalue(L, -1); | |
| 491 | + lua_rawgeti(L, 1, u-1); | |
| 492 | + set2(L, i, u-1); | |
| 493 | + /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */ | |
| 494 | + i = l; j = u-1; | |
| 495 | + for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ | |
| 496 | + /* repeat ++i until a[i] >= P */ | |
| 497 | + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { | |
| 498 | + if (i>u) lua_error(L, "invalid order function for sorting"); | |
| 499 | + lua_pop(L, 1); /* remove a[i] */ | |
| 500 | + } | |
| 501 | + /* repeat --j until a[j] <= P */ | |
| 502 | + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { | |
| 503 | + if (j<l) lua_error(L, "invalid order function for sorting"); | |
| 504 | + lua_pop(L, 1); /* remove a[j] */ | |
| 505 | + } | |
| 506 | + if (j<i) { | |
| 507 | + lua_pop(L, 3); /* pop pivot, a[i], a[j] */ | |
| 508 | + break; | |
| 509 | + } | |
| 510 | + set2(L, i, j); | |
| 511 | + } | |
| 512 | + lua_rawgeti(L, 1, u-1); | |
| 513 | + lua_rawgeti(L, 1, i); | |
| 514 | + set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */ | |
| 515 | + /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ | |
| 516 | + /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */ | |
| 517 | + if (i-l < u-i) { | |
| 518 | + j=l; i=i-1; l=i+2; | |
| 519 | + } | |
| 520 | + else { | |
| 521 | + j=i+1; i=u; u=j-2; | |
| 522 | + } | |
| 523 | + auxsort(L, j, i); /* call recursively the smaller one */ | |
| 524 | + } /* repeat the routine for the larger one */ | |
| 525 | +} | |
| 526 | + | |
| 527 | +static int luaB_sort (lua_State *L) { | |
| 528 | + int n; | |
| 529 | + luaL_checktype(L, 1, LUA_TTABLE); | |
| 530 | + n = lua_getn(L, 1); | |
| 531 | + if (!lua_isnull(L, 2)) /* is there a 2nd argument? */ | |
| 532 | + luaL_checktype(L, 2, LUA_TFUNCTION); | |
| 533 | + lua_settop(L, 2); /* make sure there is two arguments */ | |
| 534 | + auxsort(L, 1, n); | |
| 535 | + return 0; | |
| 536 | +} | |
| 537 | + | |
| 538 | +/* }====================================================== */ | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | +/* | |
| 543 | +** {====================================================== | |
| 544 | +** Deprecated functions to manipulate global environment. | |
| 545 | +** ======================================================= | |
| 546 | +*/ | |
| 547 | + | |
| 548 | + | |
| 549 | +#define num_deprecated 4 | |
| 550 | + | |
| 551 | +static const struct luaL_reg deprecated_names [num_deprecated] = { | |
| 552 | + {"foreachvar", luaB_foreach}, | |
| 553 | + {"nextvar", luaB_next}, | |
| 554 | + {"rawgetglobal", luaB_rawget}, | |
| 555 | + {"rawsetglobal", luaB_rawset} | |
| 556 | +}; | |
| 557 | + | |
| 558 | + | |
| 559 | +#ifdef LUA_DEPRECATEDFUNCS | |
| 560 | + | |
| 561 | +/* | |
| 562 | +** call corresponding function inserting `globals' as first argument | |
| 563 | +*/ | |
| 564 | +static int deprecated_func (lua_State *L) { | |
| 565 | + lua_insert(L, 1); /* upvalue is the function to be called */ | |
| 566 | + lua_getglobals(L); | |
| 567 | + lua_insert(L, 2); /* table of globals is 1o argument */ | |
| 568 | + lua_rawcall(L, lua_gettop(L)-1, LUA_MULTRET); | |
| 569 | + return lua_gettop(L); /* return all results */ | |
| 570 | +} | |
| 571 | + | |
| 572 | + | |
| 573 | +static void deprecated_funcs (lua_State *L) { | |
| 574 | + int i; | |
| 575 | + for (i=0; i<num_deprecated; i++) { | |
| 576 | + lua_pushcfunction(L, deprecated_names[i].func); | |
| 577 | + lua_pushcclosure(L, deprecated_func, 1); | |
| 578 | + lua_setglobal(L, deprecated_names[i].name); | |
| 579 | + } | |
| 580 | +} | |
| 581 | + | |
| 582 | + | |
| 583 | +#else | |
| 584 | + | |
| 585 | +/* | |
| 586 | +** gives an explicit error in any attempt to call a deprecated function | |
| 587 | +*/ | |
| 588 | +static int deprecated_func (lua_State *L) { | |
| 589 | + luaL_verror(L, "function `%.20s' is deprecated", lua_tostring(L, -1)); | |
| 590 | + return 0; /* to avoid warnings */ | |
| 591 | +} | |
| 592 | + | |
| 593 | + | |
| 594 | +static void deprecated_funcs (lua_State *L) { | |
| 595 | + int i; | |
| 596 | + for (i=0; i<num_deprecated; i++) { | |
| 597 | + lua_pushstring(L, deprecated_names[i].name); | |
| 598 | + lua_pushcclosure(L, deprecated_func, 1); | |
| 599 | + lua_setglobal(L, deprecated_names[i].name); | |
| 600 | + } | |
| 601 | +} | |
| 602 | + | |
| 603 | +#endif | |
| 604 | + | |
| 605 | +/* }====================================================== */ | |
| 606 | + | |
| 607 | +static const struct luaL_reg base_funcs[] = { | |
| 608 | + {LUA_ALERT, luaB__ALERT}, | |
| 609 | + {LUA_ERRORMESSAGE, luaB__ERRORMESSAGE}, | |
| 610 | + {"call", luaB_call}, | |
| 611 | + {"collectgarbage", luaB_collectgarbage}, | |
| 612 | + {"copytagmethods", luaB_copytagmethods}, | |
| 613 | + {"dofile", luaB_dofile}, | |
| 614 | + {"dostring", luaB_dostring}, | |
| 615 | + {"error", luaB_error}, | |
| 616 | + {"foreach", luaB_foreach}, | |
| 617 | + {"foreachi", luaB_foreachi}, | |
| 618 | + {"gcinfo", luaB_gcinfo}, | |
| 619 | + {"getglobal", luaB_getglobal}, | |
| 620 | + {"gettagmethod", luaB_gettagmethod}, | |
| 621 | + {"globals", luaB_globals}, | |
| 622 | + {"newtag", luaB_newtag}, | |
| 623 | + {"next", luaB_next}, | |
| 624 | + {"print", luaB_print}, | |
| 625 | + {"rawget", luaB_rawget}, | |
| 626 | + {"rawset", luaB_rawset}, | |
| 627 | + {"rawgettable", luaB_rawget}, /* for compatibility */ | |
| 628 | + {"rawsettable", luaB_rawset}, /* for compatibility */ | |
| 629 | + {"setglobal", luaB_setglobal}, | |
| 630 | + {"settag", luaB_settag}, | |
| 631 | + {"settagmethod", luaB_settagmethod}, | |
| 632 | + {"tag", luaB_tag}, | |
| 633 | + {"tonumber", luaB_tonumber}, | |
| 634 | + {"tostring", luaB_tostring}, | |
| 635 | + {"type", luaB_type}, | |
| 636 | + {"assert", luaB_assert}, | |
| 637 | + {"getn", luaB_getn}, | |
| 638 | + {"sort", luaB_sort}, | |
| 639 | + {"tinsert", luaB_tinsert}, | |
| 640 | + {"tremove", luaB_tremove} | |
| 641 | +}; | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | +LUALIB_API void lua_baselibopen (lua_State *L) { | |
| 646 | + luaL_openl(L, base_funcs); | |
| 647 | + lua_pushstring(L, LUA_VERSION); | |
| 648 | + lua_setglobal(L, "_VERSION"); | |
| 649 | + deprecated_funcs(L); | |
| 650 | +} | |
| 651 | + | |
| @@ -1,217 +1,188 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ldblib.c,v 1.5 1999/03/04 21:17:26 roberto Exp $ | |
| 2 | +** $Id: ldblib.c,v 1.29 2000/11/06 17:58:38 roberto Exp $ | |
| 3 | 3 | ** Interface from Lua to its debug API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | +#include <stdio.h> | |
| 8 | 9 | #include <stdlib.h> |
| 9 | 10 | #include <string.h> |
| 10 | 11 | |
| 11 | −#include "lauxlib.h" | |
| 12 | 12 | #include "lua.h" |
| 13 | + | |
| 14 | +#include "lauxlib.h" | |
| 13 | 15 | #include "luadebug.h" |
| 14 | 16 | #include "lualib.h" |
| 15 | 17 | |
| 16 | 18 | |
| 17 | 19 | |
| 18 | −static void settabss (lua_Object t, char *i, char *v) { | |
| 19 | − lua_pushobject(t); | |
| 20 | − lua_pushstring(i); | |
| 21 | − lua_pushstring(v); | |
| 22 | − lua_settable(); | |
| 20 | +static void settabss (lua_State *L, const char *i, const char *v) { | |
| 21 | + lua_pushstring(L, i); | |
| 22 | + lua_pushstring(L, v); | |
| 23 | + lua_settable(L, -3); | |
| 23 | 24 | } |
| 24 | 25 | |
| 25 | 26 | |
| 26 | −static void settabsi (lua_Object t, char *i, int v) { | |
| 27 | − lua_pushobject(t); | |
| 28 | − lua_pushstring(i); | |
| 29 | − lua_pushnumber(v); | |
| 30 | − lua_settable(); | |
| 27 | +static void settabsi (lua_State *L, const char *i, int v) { | |
| 28 | + lua_pushstring(L, i); | |
| 29 | + lua_pushnumber(L, v); | |
| 30 | + lua_settable(L, -3); | |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | |
| 34 | −static lua_Object getfuncinfo (lua_Object func) { | |
| 35 | − lua_Object result = lua_createtable(); | |
| 36 | − char *str; | |
| 37 | − int line; | |
| 38 | − lua_funcinfo(func, &str, &line); | |
| 39 | − if (line == -1) /* C function? */ | |
| 40 | − settabss(result, "kind", "C"); | |
| 41 | − else if (line == 0) { /* "main"? */ | |
| 42 | − settabss(result, "kind", "chunk"); | |
| 43 | − settabss(result, "source", str); | |
| 34 | +static int getinfo (lua_State *L) { | |
| 35 | + lua_Debug ar; | |
| 36 | + const char *options = luaL_opt_string(L, 2, "flnSu"); | |
| 37 | + char buff[20]; | |
| 38 | + if (lua_isnumber(L, 1)) { | |
| 39 | + if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) { | |
| 40 | + lua_pushnil(L); /* level out of range */ | |
| 41 | + return 1; | |
| 44 | 42 | } |
| 45 | − else { /* Lua function */ | |
| 46 | − settabss(result, "kind", "Lua"); | |
| 47 | − settabsi(result, "def_line", line); | |
| 48 | − settabss(result, "source", str); | |
| 49 | 43 | } |
| 50 | − if (line != 0) { /* is it not a "main"? */ | |
| 51 | − char *kind = lua_getobjname(func, &str); | |
| 52 | − if (*kind) { | |
| 53 | − settabss(result, "name", str); | |
| 54 | − settabss(result, "where", kind); | |
| 44 | + else if (lua_isfunction(L, 1)) { | |
| 45 | + lua_pushvalue(L, 1); | |
| 46 | + sprintf(buff, ">%.10s", options); | |
| 47 | + options = buff; | |
| 48 | + } | |
| 49 | + else | |
| 50 | + luaL_argerror(L, 1, "function or level expected"); | |
| 51 | + if (!lua_getinfo(L, options, &ar)) | |
| 52 | + luaL_argerror(L, 2, "invalid option"); | |
| 53 | + lua_newtable(L); | |
| 54 | + for (; *options; options++) { | |
| 55 | + switch (*options) { | |
| 56 | + case 'S': | |
| 57 | + settabss(L, "source", ar.source); | |
| 58 | + if (ar.source) | |
| 59 | + settabss(L, "short_src", ar.short_src); | |
| 60 | + settabsi(L, "linedefined", ar.linedefined); | |
| 61 | + settabss(L, "what", ar.what); | |
| 62 | + break; | |
| 63 | + case 'l': | |
| 64 | + settabsi(L, "currentline", ar.currentline); | |
| 65 | + break; | |
| 66 | + case 'u': | |
| 67 | + settabsi(L, "nups", ar.nups); | |
| 68 | + break; | |
| 69 | + case 'n': | |
| 70 | + settabss(L, "name", ar.name); | |
| 71 | + settabss(L, "namewhat", ar.namewhat); | |
| 72 | + break; | |
| 73 | + case 'f': | |
| 74 | + lua_pushstring(L, "func"); | |
| 75 | + lua_pushvalue(L, -3); | |
| 76 | + lua_settable(L, -3); | |
| 77 | + break; | |
| 55 | 78 | } |
| 56 | 79 | } |
| 57 | − return result; | |
| 80 | + return 1; /* return table */ | |
| 58 | 81 | } |
| 59 | − | |
| 60 | − | |
| 61 | −static void getstack (void) { | |
| 62 | − lua_Object func = lua_stackedfunction(luaL_check_int(1)); | |
| 63 | − if (func == LUA_NOOBJECT) /* level out of range? */ | |
| 64 | − return; | |
| 65 | − else { | |
| 66 | − lua_Object result = getfuncinfo(func); | |
| 67 | − int currline = lua_currentline(func); | |
| 68 | − if (currline > 0) | |
| 69 | − settabsi(result, "current", currline); | |
| 70 | − lua_pushobject(result); | |
| 71 | − lua_pushstring("func"); | |
| 72 | − lua_pushobject(func); | |
| 73 | − lua_settable(); /* result.func = func */ | |
| 74 | − lua_pushobject(result); | |
| 82 | + | |
| 83 | + | |
| 84 | +static int getlocal (lua_State *L) { | |
| 85 | + lua_Debug ar; | |
| 86 | + const char *name; | |
| 87 | + if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ | |
| 88 | + luaL_argerror(L, 1, "level out of range"); | |
| 89 | + name = lua_getlocal(L, &ar, luaL_check_int(L, 2)); | |
| 90 | + if (name) { | |
| 91 | + lua_pushstring(L, name); | |
| 92 | + lua_pushvalue(L, -2); | |
| 93 | + return 2; | |
| 75 | 94 | } |
| 76 | −} | |
| 77 | − | |
| 78 | − | |
| 79 | −static void funcinfo (void) { | |
| 80 | − lua_pushobject(getfuncinfo(luaL_functionarg(1))); | |
| 81 | −} | |
| 82 | − | |
| 83 | − | |
| 84 | −static int findlocal (lua_Object func, int arg) { | |
| 85 | − lua_Object v = lua_getparam(arg); | |
| 86 | − if (lua_isnumber(v)) | |
| 87 | − return (int)lua_getnumber(v); | |
| 88 | 95 | else { |
| 89 | − char *name = luaL_check_string(arg); | |
| 90 | − int i = 0; | |
| 91 | − int result = -1; | |
| 92 | − char *vname; | |
| 93 | − while (lua_getlocal(func, ++i, &vname) != LUA_NOOBJECT) { | |
| 94 | − if (strcmp(name, vname) == 0) | |
| 95 | − result = i; /* keep looping to get the last var with this name */ | |
| 96 | − } | |
| 97 | − if (result == -1) | |
| 98 | − luaL_verror("no local variable `%.50s' at given level", name); | |
| 99 | − return result; | |
| 96 | + lua_pushnil(L); | |
| 97 | + return 1; | |
| 100 | 98 | } |
| 101 | 99 | } |
| 102 | 100 | |
| 103 | 101 | |
| 104 | −static void getlocal (void) { | |
| 105 | − lua_Object func = lua_stackedfunction(luaL_check_int(1)); | |
| 106 | − lua_Object val; | |
| 107 | − char *name; | |
| 108 | − if (func == LUA_NOOBJECT) /* level out of range? */ | |
| 109 | − return; /* return nil */ | |
| 110 | − else if (lua_getparam(2) != LUA_NOOBJECT) { /* 2nd argument? */ | |
| 111 | − if ((val = lua_getlocal(func, findlocal(func, 2), &name)) != LUA_NOOBJECT) { | |
| 112 | − lua_pushobject(val); | |
| 113 | − lua_pushstring(name); | |
| 114 | − } | |
| 115 | − /* else return nil */ | |
| 116 | − } | |
| 117 | − else { /* collect all locals in a table */ | |
| 118 | − lua_Object result = lua_createtable(); | |
| 119 | − int i; | |
| 120 | − for (i=1; ;i++) { | |
| 121 | − if ((val = lua_getlocal(func, i, &name)) == LUA_NOOBJECT) | |
| 122 | − break; | |
| 123 | − lua_pushobject(result); | |
| 124 | − lua_pushstring(name); | |
| 125 | − lua_pushobject(val); | |
| 126 | − lua_settable(); /* result[name] = value */ | |
| 127 | − } | |
| 128 | − lua_pushobject(result); | |
| 129 | − } | |
| 102 | +static int setlocal (lua_State *L) { | |
| 103 | + lua_Debug ar; | |
| 104 | + if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ | |
| 105 | + luaL_argerror(L, 1, "level out of range"); | |
| 106 | + luaL_checkany(L, 3); | |
| 107 | + lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2))); | |
| 108 | + return 1; | |
| 130 | 109 | } |
| 131 | 110 | |
| 132 | 111 | |
| 133 | −static void setlocal (void) { | |
| 134 | − lua_Object func = lua_stackedfunction(luaL_check_int(1)); | |
| 135 | − int numvar; | |
| 136 | − luaL_arg_check(func != LUA_NOOBJECT, 1, "level out of range"); | |
| 137 | − numvar = findlocal(func, 2); | |
| 138 | − lua_pushobject(luaL_nonnullarg(3)); | |
| 139 | − if (!lua_setlocal(func, numvar)) | |
| 140 | − lua_error("no such local variable"); | |
| 141 | −} | |
| 142 | 112 | |
| 113 | +/* dummy variables (to define unique addresses) */ | |
| 114 | +static char key1, key2; | |
| 115 | +#define KEY_CALLHOOK (&key1) | |
| 116 | +#define KEY_LINEHOOK (&key2) | |
| 143 | 117 | |
| 144 | 118 | |
| 145 | −static int linehook = -1; /* Lua reference to line hook function */ | |
| 146 | −static int callhook = -1; /* Lua reference to call hook function */ | |
| 119 | +static void hookf (lua_State *L, void *key) { | |
| 120 | + lua_getregistry(L); | |
| 121 | + lua_pushuserdata(L, key); | |
| 122 | + lua_gettable(L, -2); | |
| 123 | + if (lua_isfunction(L, -1)) { | |
| 124 | + lua_pushvalue(L, 1); | |
| 125 | + lua_rawcall(L, 1, 0); | |
| 126 | + } | |
| 127 | + else | |
| 128 | + lua_pop(L, 1); /* pop result from gettable */ | |
| 129 | + lua_pop(L, 1); /* pop table */ | |
| 130 | +} | |
| 147 | 131 | |
| 148 | 132 | |
| 149 | −static void dohook (int ref) { | |
| 150 | − lua_LHFunction oldlinehook = lua_setlinehook(NULL); | |
| 151 | − lua_CHFunction oldcallhook = lua_setcallhook(NULL); | |
| 152 | − lua_callfunction(lua_getref(ref)); | |
| 153 | − lua_setlinehook(oldlinehook); | |
| 154 | − lua_setcallhook(oldcallhook); | |
| 133 | +static void callf (lua_State *L, lua_Debug *ar) { | |
| 134 | + lua_pushstring(L, ar->event); | |
| 135 | + hookf(L, KEY_CALLHOOK); | |
| 155 | 136 | } |
| 156 | 137 | |
| 157 | 138 | |
| 158 | −static void linef (int line) { | |
| 159 | − lua_pushnumber(line); | |
| 160 | − dohook(linehook); | |
| 139 | +static void linef (lua_State *L, lua_Debug *ar) { | |
| 140 | + lua_pushnumber(L, ar->currentline); | |
| 141 | + hookf(L, KEY_LINEHOOK); | |
| 161 | 142 | } |
| 162 | 143 | |
| 163 | 144 | |
| 164 | −static void callf (lua_Function func, char *file, int line) { | |
| 165 | − if (func != LUA_NOOBJECT) { | |
| 166 | − lua_pushobject(func); | |
| 167 | − lua_pushstring(file); | |
| 168 | − lua_pushnumber(line); | |
| 169 | − } | |
| 170 | − dohook(callhook); | |
| 145 | +static void sethook (lua_State *L, void *key, lua_Hook hook, | |
| 146 | + lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) { | |
| 147 | + lua_settop(L, 1); | |
| 148 | + if (lua_isnil(L, 1)) | |
| 149 | + (*sethookf)(L, NULL); | |
| 150 | + else if (lua_isfunction(L, 1)) | |
| 151 | + (*sethookf)(L, hook); | |
| 152 | + else | |
| 153 | + luaL_argerror(L, 1, "function expected"); | |
| 154 | + lua_getregistry(L); | |
| 155 | + lua_pushuserdata(L, key); | |
| 156 | + lua_pushvalue(L, -1); /* dup key */ | |
| 157 | + lua_gettable(L, -3); /* get old value */ | |
| 158 | + lua_pushvalue(L, -2); /* key (again) */ | |
| 159 | + lua_pushvalue(L, 1); | |
| 160 | + lua_settable(L, -5); /* set new value */ | |
| 171 | 161 | } |
| 172 | 162 | |
| 173 | 163 | |
| 174 | −static void setcallhook (void) { | |
| 175 | − lua_Object f = lua_getparam(1); | |
| 176 | − lua_unref(callhook); | |
| 177 | − if (f == LUA_NOOBJECT) { | |
| 178 | − callhook = -1; | |
| 179 | − lua_setcallhook(NULL); | |
| 180 | − } | |
| 181 | − else { | |
| 182 | − lua_pushobject(f); | |
| 183 | − callhook = lua_ref(1); | |
| 184 | − lua_setcallhook(callf); | |
| 185 | − } | |
| 164 | +static int setcallhook (lua_State *L) { | |
| 165 | + sethook(L, KEY_CALLHOOK, callf, lua_setcallhook); | |
| 166 | + return 1; | |
| 186 | 167 | } |
| 187 | 168 | |
| 188 | 169 | |
| 189 | −static void setlinehook (void) { | |
| 190 | − lua_Object f = lua_getparam(1); | |
| 191 | − lua_unref(linehook); | |
| 192 | − if (f == LUA_NOOBJECT) { | |
| 193 | − linehook = -1; | |
| 194 | − lua_setlinehook(NULL); | |
| 195 | − } | |
| 196 | − else { | |
| 197 | − lua_pushobject(f); | |
| 198 | − linehook = lua_ref(1); | |
| 199 | − lua_setlinehook(linef); | |
| 200 | − } | |
| 170 | +static int setlinehook (lua_State *L) { | |
| 171 | + sethook(L, KEY_LINEHOOK, linef, lua_setlinehook); | |
| 172 | + return 1; | |
| 201 | 173 | } |
| 202 | 174 | |
| 203 | 175 | |
| 204 | −static struct luaL_reg dblib[] = { | |
| 205 | − {"funcinfo", funcinfo}, | |
| 176 | +static const struct luaL_reg dblib[] = { | |
| 206 | 177 | {"getlocal", getlocal}, |
| 207 | − {"getstack", getstack}, | |
| 178 | + {"getinfo", getinfo}, | |
| 208 | 179 | {"setcallhook", setcallhook}, |
| 209 | 180 | {"setlinehook", setlinehook}, |
| 210 | 181 | {"setlocal", setlocal} |
| 211 | 182 | }; |
| 212 | 183 | |
| 213 | 184 | |
| 214 | −void lua_dblibopen (void) { | |
| 215 | − luaL_openlib(dblib, (sizeof(dblib)/sizeof(dblib[0]))); | |
| 185 | +LUALIB_API void lua_dblibopen (lua_State *L) { | |
| 186 | + luaL_openl(L, dblib); | |
| 216 | 187 | } |
| 217 | 188 | |
| @@ -1,17 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** $Id: linit.c,v 1.1 1999/01/08 16:49:32 roberto Exp $ | |
| 3 | −** Initialization of libraries for lua.c | |
| 4 | −** See Copyright Notice in lua.h | |
| 5 | −*/ | |
| 6 | − | |
| 7 | −#include "lua.h" | |
| 8 | −#include "lualib.h" | |
| 9 | − | |
| 10 | − | |
| 11 | −void lua_userinit (void) { | |
| 12 | − lua_iolibopen(); | |
| 13 | − lua_strlibopen(); | |
| 14 | − lua_mathlibopen(); | |
| 15 | − lua_dblibopen(); | |
| 16 | −} | |
| 17 | − | |
| @@ -1,67 +1,78 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: liolib.c,v 1.41 1999/06/23 13:48:39 roberto Exp $ | |
| 2 | +** $Id: liolib.c,v 1.91 2000/10/31 13:10:24 roberto Exp $ | |
| 3 | 3 | ** Standard I/O (and system) library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | −#include <errno.h> | |
| 8 | +#include <ctype.h> | |
| 9 | 9 | #include <stdio.h> |
| 10 | 10 | #include <stdlib.h> |
| 11 | 11 | #include <string.h> |
| 12 | 12 | #include <time.h> |
| 13 | 13 | |
| 14 | −#include "lauxlib.h" | |
| 15 | 14 | #include "lua.h" |
| 15 | + | |
| 16 | +#include "lauxlib.h" | |
| 16 | 17 | #include "luadebug.h" |
| 17 | 18 | #include "lualib.h" |
| 18 | 19 | |
| 19 | 20 | |
| 20 | 21 | #ifndef OLD_ANSI |
| 22 | +#include <errno.h> | |
| 21 | 23 | #include <locale.h> |
| 24 | +#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s)) | |
| 25 | +#define free(b) if (b) (free)(b) | |
| 22 | 26 | #else |
| 23 | 27 | /* no support for locale and for strerror: fake them */ |
| 24 | −#define setlocale(a,b) 0 | |
| 28 | +#define setlocale(a,b) ((void)a, strcmp((b),"C")==0?"C":NULL) | |
| 25 | 29 | #define LC_ALL 0 |
| 26 | 30 | #define LC_COLLATE 0 |
| 27 | 31 | #define LC_CTYPE 0 |
| 28 | 32 | #define LC_MONETARY 0 |
| 29 | 33 | #define LC_NUMERIC 0 |
| 30 | 34 | #define LC_TIME 0 |
| 31 | −#define strerror(e) "(no error message provided by operating system)" | |
| 35 | +#define strerror(e) "generic I/O error" | |
| 36 | +#define errno (-1) | |
| 32 | 37 | #endif |
| 33 | 38 | |
| 34 | 39 | |
| 35 | −#define IOTAG 1 | |
| 36 | − | |
| 37 | −#define FIRSTARG 2 /* 1st is upvalue */ | |
| 38 | − | |
| 39 | −#define CLOSEDTAG(tag) ((tag)-1) /* assume that CLOSEDTAG = iotag-1 */ | |
| 40 | − | |
| 41 | − | |
| 42 | −#define FINPUT "_INPUT" | |
| 43 | −#define FOUTPUT "_OUTPUT" | |
| 44 | − | |
| 45 | 40 | |
| 46 | 41 | #ifdef POPEN |
| 47 | −FILE *popen(); | |
| 48 | −int pclose(); | |
| 49 | −#define CLOSEFILE(f) {if (pclose(f) == -1) fclose(f);} | |
| 42 | +/* FILE *popen(); | |
| 43 | +int pclose(); */ | |
| 44 | +#define CLOSEFILE(L, f) ((pclose(f) == -1) ? fclose(f) : 0) | |
| 50 | 45 | #else |
| 51 | 46 | /* no support for popen */ |
| 52 | 47 | #define popen(x,y) NULL /* that is, popen always fails */ |
| 53 | −#define CLOSEFILE(f) {fclose(f);} | |
| 48 | +#define CLOSEFILE(L, f) (fclose(f)) | |
| 54 | 49 | #endif |
| 55 | 50 | |
| 56 | 51 | |
| 52 | +#define INFILE 0 | |
| 53 | +#define OUTFILE 1 | |
| 54 | + | |
| 55 | +typedef struct IOCtrl { | |
| 56 | + int ref[2]; /* ref for strings _INPUT/_OUTPUT */ | |
| 57 | + int iotag; /* tag for file handles */ | |
| 58 | + int closedtag; /* tag for closed handles */ | |
| 59 | +} IOCtrl; | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | +static const char *const filenames[] = {"_INPUT", "_OUTPUT"}; | |
| 57 | 64 | |
| 58 | −static void pushresult (int i) { | |
| 59 | − if (i) | |
| 60 | − lua_pushuserdata(NULL); | |
| 65 | + | |
| 66 | +static int pushresult (lua_State *L, int i) { | |
| 67 | + if (i) { | |
| 68 | + lua_pushuserdata(L, NULL); | |
| 69 | + return 1; | |
| 70 | + } | |
| 61 | 71 | else { |
| 62 | − lua_pushnil(); | |
| 63 | − lua_pushstring(strerror(errno)); | |
| 64 | − lua_pushnumber(errno); | |
| 72 | + lua_pushnil(L); | |
| 73 | + lua_pushstring(L, strerror(errno)); | |
| 74 | + lua_pushnumber(L, errno); | |
| 75 | + return 3;; | |
| 65 | 76 | } |
| 66 | 77 | } |
| 67 | 78 | |
| @@ -72,138 +83,138 @@ static void pushresult (int i) { · 4 unmodified lines | ||
| 72 | 83 | ** ======================================================= |
| 73 | 84 | */ |
| 74 | 85 | |
| 75 | −static int gettag (void) { | |
| 76 | − return (int)lua_getnumber(lua_getparam(IOTAG)); | |
| 77 | −} | |
| 78 | 86 | |
| 79 | − | |
| 80 | −static int ishandle (lua_Object f) { | |
| 81 | − if (lua_isuserdata(f)) { | |
| 82 | − int tag = gettag(); | |
| 83 | − if (lua_tag(f) == CLOSEDTAG(tag)) | |
| 84 | − lua_error("cannot access a closed file"); | |
| 85 | − return lua_tag(f) == tag; | |
| 87 | +static FILE *gethandle (lua_State *L, IOCtrl *ctrl, int f) { | |
| 88 | + void *p = lua_touserdata(L, f); | |
| 89 | + if (p != NULL) { /* is `f' a userdata ? */ | |
| 90 | + int ftag = lua_tag(L, f); | |
| 91 | + if (ftag == ctrl->iotag) /* does it have the correct tag? */ | |
| 92 | + return (FILE *)p; | |
| 93 | + else if (ftag == ctrl->closedtag) | |
| 94 | + lua_error(L, "cannot access a closed file"); | |
| 95 | + /* else go through */ | |
| 86 | 96 | } |
| 87 | − else return 0; | |
| 97 | + return NULL; | |
| 88 | 98 | } |
| 89 | 99 | |
| 90 | 100 | |
| 91 | −static FILE *getfilebyname (char *name) { | |
| 92 | − lua_Object f = lua_getglobal(name); | |
| 93 | − if (!ishandle(f)) | |
| 94 | − luaL_verror("global variable `%.50s' is not a file handle", name); | |
| 95 | − return lua_getuserdata(f); | |
| 96 | −} | |
| 97 | − | |
| 98 | − | |
| 99 | −static FILE *getfile (int arg) { | |
| 100 | − lua_Object f = lua_getparam(arg); | |
| 101 | − return (ishandle(f)) ? lua_getuserdata(f) : NULL; | |
| 101 | +static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) { | |
| 102 | + FILE *f = gethandle(L, ctrl, arg); | |
| 103 | + luaL_arg_check(L, f, arg, "invalid file handle"); | |
| 104 | + return f; | |
| 102 | 105 | } |
| 103 | 106 | |
| 104 | 107 | |
| 105 | −static FILE *getnonullfile (int arg) { | |
| 106 | − FILE *f = getfile(arg); | |
| 107 | − luaL_arg_check(f, arg, "invalid file handle"); | |
| 108 | +static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) { | |
| 109 | + FILE *f; | |
| 110 | + lua_getglobals(L); | |
| 111 | + lua_getref(L, ctrl->ref[inout]); | |
| 112 | + lua_rawget(L, -2); | |
| 113 | + f = gethandle(L, ctrl, -1); | |
| 114 | + if (f == NULL) | |
| 115 | + luaL_verror(L, "global variable `%.10s' is not a file handle", | |
| 116 | + filenames[inout]); | |
| 108 | 117 | return f; |
| 109 | 118 | } |
| 110 | 119 | |
| 111 | 120 | |
| 112 | −static FILE *getfileparam (char *name, int *arg) { | |
| 113 | − FILE *f = getfile(*arg); | |
| 114 | − if (f) { | |
| 115 | − (*arg)++; | |
| 116 | − return f; | |
| 117 | − } | |
| 118 | − else | |
| 119 | − return getfilebyname(name); | |
| 121 | +static void setfilebyname (lua_State *L, IOCtrl *ctrl, FILE *f, | |
| 122 | + const char *name) { | |
| 123 | + lua_pushusertag(L, f, ctrl->iotag); | |
| 124 | + lua_setglobal(L, name); | |
| 120 | 125 | } |
| 121 | 126 | |
| 122 | 127 | |
| 123 | −static void closefile (FILE *f) { | |
| 124 | − if (f != stdin && f != stdout) { | |
| 125 | − int tag = gettag(); | |
| 126 | − CLOSEFILE(f); | |
| 127 | − lua_pushusertag(f, tag); | |
| 128 | − lua_settag(CLOSEDTAG(tag)); | |
| 129 | − } | |
| 130 | −} | |
| 128 | +#define setfile(L,ctrl,f,inout) (setfilebyname(L,ctrl,f,filenames[inout])) | |
| 131 | 129 | |
| 132 | 130 | |
| 133 | −static void io_close (void) { | |
| 134 | − closefile(getnonullfile(FIRSTARG)); | |
| 131 | +static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) { | |
| 132 | + if (f == NULL) | |
| 133 | + return pushresult(L, 0); | |
| 134 | + else { | |
| 135 | + setfile(L, ctrl, f, inout); | |
| 136 | + lua_pushusertag(L, f, ctrl->iotag); | |
| 137 | + return 1; | |
| 138 | + } | |
| 135 | 139 | } |
| 136 | 140 | |
| 137 | 141 | |
| 138 | −static void gc_close (void) { | |
| 139 | − FILE *f = getnonullfile(FIRSTARG); | |
| 140 | − if (f != stdin && f != stdout && f != stderr) { | |
| 141 | − CLOSEFILE(f); | |
| 142 | +static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) { | |
| 143 | + if (f == stdin || f == stdout || f == stderr) | |
| 144 | + return 1; | |
| 145 | + else { | |
| 146 | + lua_pushusertag(L, f, ctrl->iotag); | |
| 147 | + lua_settag(L, ctrl->closedtag); | |
| 148 | + return (CLOSEFILE(L, f) == 0); | |
| 142 | 149 | } |
| 143 | 150 | } |
| 144 | 151 | |
| 145 | 152 | |
| 146 | −static void io_open (void) { | |
| 147 | − FILE *f = fopen(luaL_check_string(FIRSTARG), luaL_check_string(FIRSTARG+1)); | |
| 148 | − if (f) lua_pushusertag(f, gettag()); | |
| 149 | − else pushresult(0); | |
| 153 | +static int io_close (lua_State *L) { | |
| 154 | + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); | |
| 155 | + lua_pop(L, 1); /* remove upvalue */ | |
| 156 | + return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 1))); | |
| 150 | 157 | } |
| 151 | 158 | |
| 152 | 159 | |
| 153 | −static void setfile (FILE *f, char *name, int tag) { | |
| 154 | − lua_pushusertag(f, tag); | |
| 155 | − lua_setglobal(name); | |
| 160 | +static int file_collect (lua_State *L) { | |
| 161 | + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); | |
| 162 | + FILE *f = getnonullfile(L, ctrl, 1); | |
| 163 | + if (f != stdin && f != stdout && f != stderr) | |
| 164 | + CLOSEFILE(L, f); | |
| 165 | + return 0; | |
| 156 | 166 | } |
| 157 | 167 | |
| 158 | 168 | |
| 159 | −static void setreturn (FILE *f, char *name) { | |
| 160 | − if (f == NULL) | |
| 161 | − pushresult(0); | |
| 162 | − else { | |
| 163 | − int tag = gettag(); | |
| 164 | − setfile(f, name, tag); | |
| 165 | − lua_pushusertag(f, tag); | |
| 169 | +static int io_open (lua_State *L) { | |
| 170 | + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); | |
| 171 | + FILE *f; | |
| 172 | + lua_pop(L, 1); /* remove upvalue */ | |
| 173 | + f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2)); | |
| 174 | + if (f) { | |
| 175 | + lua_pushusertag(L, f, ctrl->iotag); | |
| 176 | + return 1; | |
| 166 | 177 | } |
| 178 | + else | |
| 179 | + return pushresult(L, 0); | |
| 167 | 180 | } |
| 168 | 181 | |
| 169 | 182 | |
| 170 | −static void io_readfrom (void) { | |
| 183 | + | |
| 184 | +static int io_fromto (lua_State *L, int inout, const char *mode) { | |
| 185 | + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); | |
| 171 | 186 | FILE *current; |
| 172 | − lua_Object f = lua_getparam(FIRSTARG); | |
| 173 | − if (f == LUA_NOOBJECT) { | |
| 174 | − closefile(getfilebyname(FINPUT)); | |
| 175 | − current = stdin; | |
| 187 | + lua_pop(L, 1); /* remove upvalue */ | |
| 188 | + if (lua_isnull(L, 1)) { | |
| 189 | + closefile(L, ctrl, getfilebyref(L, ctrl, inout)); | |
| 190 | + current = (inout == 0) ? stdin : stdout; | |
| 176 | 191 | } |
| 177 | − else if (lua_tag(f) == gettag()) /* deprecated option */ | |
| 178 | − current = lua_getuserdata(f); | |
| 192 | + else if (lua_tag(L, 1) == ctrl->iotag) /* deprecated option */ | |
| 193 | + current = (FILE *)lua_touserdata(L, 1); | |
| 179 | 194 | else { |
| 180 | − char *s = luaL_check_string(FIRSTARG); | |
| 181 | − current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); | |
| 195 | + const char *s = luaL_check_string(L, 1); | |
| 196 | + current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode); | |
| 182 | 197 | } |
| 183 | − setreturn(current, FINPUT); | |
| 198 | + return setreturn(L, ctrl, current, inout); | |
| 184 | 199 | } |
| 185 | 200 | |
| 186 | 201 | |
| 187 | −static void io_writeto (void) { | |
| 188 | − FILE *current; | |
| 189 | − lua_Object f = lua_getparam(FIRSTARG); | |
| 190 | − if (f == LUA_NOOBJECT) { | |
| 191 | − closefile(getfilebyname(FOUTPUT)); | |
| 192 | − current = stdout; | |
| 193 | − } | |
| 194 | − else if (lua_tag(f) == gettag()) /* deprecated option */ | |
| 195 | − current = lua_getuserdata(f); | |
| 196 | − else { | |
| 197 | − char *s = luaL_check_string(FIRSTARG); | |
| 198 | − current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w"); | |
| 199 | − } | |
| 200 | − setreturn(current, FOUTPUT); | |
| 202 | +static int io_readfrom (lua_State *L) { | |
| 203 | + return io_fromto(L, INFILE, "r"); | |
| 201 | 204 | } |
| 202 | 205 | |
| 203 | 206 | |
| 204 | −static void io_appendto (void) { | |
| 205 | − FILE *current = fopen(luaL_check_string(FIRSTARG), "a"); | |
| 206 | − setreturn(current, FOUTPUT); | |
| 207 | +static int io_writeto (lua_State *L) { | |
| 208 | + return io_fromto(L, OUTFILE, "w"); | |
| 209 | +} | |
| 210 | + | |
| 211 | + | |
| 212 | +static int io_appendto (lua_State *L) { | |
| 213 | + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); | |
| 214 | + FILE *current; | |
| 215 | + lua_pop(L, 1); /* remove upvalue */ | |
| 216 | + current = fopen(luaL_check_string(L, 1), "a"); | |
| 217 | + return setreturn(L, ctrl, current, OUTFILE); | |
| 207 | 218 | } |
| 208 | 219 | |
| 209 | 220 | |
| @@ -215,6 +226,9 @@ static void io_appendto (void) { · 5 unmodified lines | ||
| 215 | 226 | */ |
| 216 | 227 | |
| 217 | 228 | |
| 229 | + | |
| 230 | +#ifdef LUA_COMPAT_READPATTERN | |
| 231 | + | |
| 218 | 232 | /* |
| 219 | 233 | ** We cannot lookahead without need, because this can lock stdin. |
| 220 | 234 | ** This flag signals when we need to read a next char. |
| @@ -222,9 +236,11 @@ static void io_appendto (void) { · 1 unmodified line | ||
| 222 | 236 | #define NEED_OTHER (EOF-1) /* just some flag different from EOF */ |
| 223 | 237 | |
| 224 | 238 | |
| 225 | −static int read_pattern (FILE *f, char *p) { | |
| 239 | +static int read_pattern (lua_State *L, FILE *f, const char *p) { | |
| 226 | 240 | int inskip = 0; /* {skip} level */ |
| 227 | 241 | int c = NEED_OTHER; |
| 242 | + luaL_Buffer b; | |
| 243 | + luaL_buffinit(L, &b); | |
| 228 | 244 | while (*p != '\0') { |
| 229 | 245 | switch (*p) { |
| 230 | 246 | case '{': |
| @@ -232,17 +248,17 @@ static int read_pattern (FILE *f, char *p) { · 1 unmodified line | ||
| 232 | 248 | p++; |
| 233 | 249 | continue; |
| 234 | 250 | case '}': |
| 235 | − if (!inskip) lua_error("unbalanced braces in read pattern"); | |
| 251 | + if (!inskip) lua_error(L, "unbalanced braces in read pattern"); | |
| 236 | 252 | inskip--; |
| 237 | 253 | p++; |
| 238 | 254 | continue; |
| 239 | 255 | default: { |
| 240 | − char *ep = luaI_classend(p); /* get what is next */ | |
| 256 | + const char *ep = luaI_classend(L, p); /* get what is next */ | |
| 241 | 257 | int m; /* match result */ |
| 242 | 258 | if (c == NEED_OTHER) c = getc(f); |
| 243 | 259 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); |
| 244 | 260 | if (m) { |
| 245 | − if (!inskip) luaL_addchar(c); | |
| 261 | + if (!inskip) luaL_putchar(&b, c); | |
| 246 | 262 | c = NEED_OTHER; |
| 247 | 263 | } |
| 248 | 264 | switch (*ep) { |
| @@ -253,7 +269,7 @@ static int read_pattern (FILE *f, char *p) { · 4 unmodified lines | ||
| 253 | 269 | while (m) { /* reads the same item until it fails */ |
| 254 | 270 | c = getc(f); |
| 255 | 271 | m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); |
| 256 | − if (m && !inskip) luaL_addchar(c); | |
| 272 | + if (m && !inskip) luaL_putchar(&b, c); | |
| 257 | 273 | } |
| 258 | 274 | /* go through to continue reading the pattern */ |
| 259 | 275 | case '?': /* optional */ |
| @@ -267,116 +283,210 @@ static int read_pattern (FILE *f, char *p) { · 7 unmodified lines | ||
| 267 | 283 | } |
| 268 | 284 | } break_while: |
| 269 | 285 | if (c != NEED_OTHER) ungetc(c, f); |
| 286 | + luaL_pushresult(&b); /* close buffer */ | |
| 270 | 287 | return (*p == '\0'); |
| 271 | 288 | } |
| 272 | 289 | |
| 290 | +#else | |
| 291 | + | |
| 292 | +#define read_pattern(L, f, p) (lua_error(L, "read patterns are deprecated"), 0) | |
| 273 | 293 | |
| 274 | −static int read_number (FILE *f) { | |
| 294 | +#endif | |
| 295 | + | |
| 296 | + | |
| 297 | +static int read_number (lua_State *L, FILE *f) { | |
| 275 | 298 | double d; |
| 276 | 299 | if (fscanf(f, "%lf", &d) == 1) { |
| 277 | − lua_pushnumber(d); | |
| 300 | + lua_pushnumber(L, d); | |
| 278 | 301 | return 1; |
| 279 | 302 | } |
| 280 | 303 | else return 0; /* read fails */ |
| 281 | 304 | } |
| 282 | 305 | |
| 283 | 306 | |
| 284 | −#define HUNK_LINE 1024 | |
| 285 | −#define HUNK_FILE BUFSIZ | |
| 307 | +static int read_word (lua_State *L, FILE *f) { | |
| 308 | + int c; | |
| 309 | + luaL_Buffer b; | |
| 310 | + luaL_buffinit(L, &b); | |
| 311 | + do { c = fgetc(f); } while (isspace(c)); /* skip spaces */ | |
| 312 | + while (c != EOF && !isspace(c)) { | |
| 313 | + luaL_putchar(&b, c); | |
| 314 | + c = fgetc(f); | |
| 315 | + } | |
| 316 | + ungetc(c, f); | |
| 317 | + luaL_pushresult(&b); /* close buffer */ | |
| 318 | + return (lua_strlen(L, -1) > 0); | |
| 319 | +} | |
| 286 | 320 | |
| 287 | −static int read_line (FILE *f) { | |
| 288 | − /* equivalent to: return read_pattern(f, "[^\n]*{\n}"); */ | |
| 289 | − int n; | |
| 290 | − char *b; | |
| 291 | − do { | |
| 292 | − b = luaL_openspace(HUNK_LINE); | |
| 293 | − if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */ | |
| 294 | − n = strlen(b); | |
| 295 | − luaL_addsize(n); | |
| 296 | − } while (b[n-1] != '\n'); | |
| 297 | − luaL_addsize(-1); /* remove '\n' */ | |
| 298 | − return 1; | |
| 321 | + | |
| 322 | +static int read_line (lua_State *L, FILE *f) { | |
| 323 | + int n = 0; | |
| 324 | + luaL_Buffer b; | |
| 325 | + luaL_buffinit(L, &b); | |
| 326 | + for (;;) { | |
| 327 | + char *p = luaL_prepbuffer(&b); | |
| 328 | + if (!fgets(p, LUAL_BUFFERSIZE, f)) /* read fails? */ | |
| 329 | + break; | |
| 330 | + n = strlen(p); | |
| 331 | + if (p[n-1] != '\n') | |
| 332 | + luaL_addsize(&b, n); | |
| 333 | + else { | |
| 334 | + luaL_addsize(&b, n-1); /* do not add the `\n' */ | |
| 335 | + break; | |
| 336 | + } | |
| 337 | + } | |
| 338 | + luaL_pushresult(&b); /* close buffer */ | |
| 339 | + return (n > 0); /* read something? */ | |
| 299 | 340 | } |
| 300 | 341 | |
| 301 | 342 | |
| 302 | −static void read_file (FILE *f) { | |
| 303 | − /* equivalent to: return read_pattern(f, ".*"); */ | |
| 304 | − int n; | |
| 305 | − do { | |
| 306 | − char *b = luaL_openspace(HUNK_FILE); | |
| 307 | − n = fread(b, sizeof(char), HUNK_FILE, f); | |
| 308 | − luaL_addsize(n); | |
| 309 | − } while (n==HUNK_FILE); | |
| 343 | +static void read_file (lua_State *L, FILE *f) { | |
| 344 | + size_t len = 0; | |
| 345 | + size_t size = BUFSIZ; | |
| 346 | + char *buffer = NULL; | |
| 347 | + for (;;) { | |
| 348 | + char *newbuffer = (char *)realloc(buffer, size); | |
| 349 | + if (newbuffer == NULL) { | |
| 350 | + free(buffer); | |
| 351 | + lua_error(L, "not enough memory to read a file"); | |
| 352 | + } | |
| 353 | + buffer = newbuffer; | |
| 354 | + len += fread(buffer+len, sizeof(char), size-len, f); | |
| 355 | + if (len < size) break; /* did not read all it could */ | |
| 356 | + size *= 2; | |
| 357 | + } | |
| 358 | + lua_pushlstring(L, buffer, len); | |
| 359 | + free(buffer); | |
| 310 | 360 | } |
| 311 | 361 | |
| 312 | 362 | |
| 313 | −static void io_read (void) { | |
| 314 | − static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL}; | |
| 315 | − int arg = FIRSTARG; | |
| 316 | − FILE *f = getfileparam(FINPUT, &arg); | |
| 317 | − char *p = luaL_opt_string(arg++, "*l"); | |
| 318 | − do { /* repeat for each part */ | |
| 319 | − long l; | |
| 363 | +static int read_chars (lua_State *L, FILE *f, size_t n) { | |
| 364 | + char *buffer; | |
| 365 | + size_t n1; | |
| 366 | + char statbuff[BUFSIZ]; | |
| 367 | + if (n <= BUFSIZ) | |
| 368 | + buffer = statbuff; | |
| 369 | + else { | |
| 370 | + buffer = (char *)malloc(n); | |
| 371 | + if (buffer == NULL) | |
| 372 | + lua_error(L, "not enough memory to read a file"); | |
| 373 | + } | |
| 374 | + n1 = fread(buffer, sizeof(char), n, f); | |
| 375 | + lua_pushlstring(L, buffer, n1); | |
| 376 | + if (buffer != statbuff) free(buffer); | |
| 377 | + return (n1 > 0 || n == 0); | |
| 378 | +} | |
| 379 | + | |
| 380 | + | |
| 381 | +static int io_read (lua_State *L) { | |
| 382 | + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); | |
| 383 | + int lastarg = lua_gettop(L) - 1; | |
| 384 | + int firstarg = 1; | |
| 385 | + FILE *f = gethandle(L, ctrl, firstarg); | |
| 386 | + int n; | |
| 387 | + if (f) firstarg++; | |
| 388 | + else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */ | |
| 389 | + lua_pop(L, 1); | |
| 390 | + if (firstarg > lastarg) { /* no arguments? */ | |
| 391 | + lua_settop(L, 0); /* erase upvalue and other eventual garbage */ | |
| 392 | + firstarg = lastarg = 1; /* correct indices */ | |
| 393 | + lua_pushstring(L, "*l"); /* push default argument */ | |
| 394 | + } | |
| 395 | + else /* ensure stack space for all results and for auxlib's buffer */ | |
| 396 | + luaL_checkstack(L, lastarg-firstarg+1+LUA_MINSTACK, "too many arguments"); | |
| 397 | + for (n = firstarg; n<=lastarg; n++) { | |
| 320 | 398 | int success; |
| 321 | − luaL_resetbuffer(); | |
| 322 | − switch (luaL_findstring(p, options)) { | |
| 323 | − case 0: /* number */ | |
| 324 | − if (!read_number(f)) return; /* read fails */ | |
| 325 | − continue; /* number is already pushed; avoid the "pushstring" */ | |
| 326 | − case 1: /* line */ | |
| 327 | − success = read_line(f); | |
| 328 | − break; | |
| 329 | − case 2: case 3: /* file */ | |
| 330 | − read_file(f); | |
| 331 | − success = 1; /* always success */ | |
| 332 | − break; | |
| 333 | − case 4: /* word */ | |
| 334 | − success = read_pattern(f, "{%s*}%S+"); | |
| 335 | − break; | |
| 336 | − default: | |
| 337 | − success = read_pattern(f, p); | |
| 399 | + if (lua_isnumber(L, n)) | |
| 400 | + success = read_chars(L, f, (size_t)lua_tonumber(L, n)); | |
| 401 | + else { | |
| 402 | + const char *p = luaL_check_string(L, n); | |
| 403 | + if (p[0] != '*') | |
| 404 | + success = read_pattern(L, f, p); /* deprecated! */ | |
| 405 | + else { | |
| 406 | + switch (p[1]) { | |
| 407 | + case 'n': /* number */ | |
| 408 | + if (!read_number(L, f)) goto endloop; /* read fails */ | |
| 409 | + continue; /* number is already pushed; avoid the "pushstring" */ | |
| 410 | + case 'l': /* line */ | |
| 411 | + success = read_line(L, f); | |
| 412 | + break; | |
| 413 | + case 'a': /* file */ | |
| 414 | + read_file(L, f); | |
| 415 | + success = 1; /* always success */ | |
| 416 | + break; | |
| 417 | + case 'w': /* word */ | |
| 418 | + success = read_word(L, f); | |
| 419 | + break; | |
| 420 | + default: | |
| 421 | + luaL_argerror(L, n, "invalid format"); | |
| 422 | + success = 0; /* to avoid warnings */ | |
| 423 | + } | |
| 424 | + } | |
| 338 | 425 | } |
| 339 | − l = luaL_getsize(); | |
| 340 | − if (!success && l==0) return; /* read fails */ | |
| 341 | − lua_pushlstring(luaL_buffer(), l); | |
| 342 | − } while ((p = luaL_opt_string(arg++, NULL)) != NULL); | |
| 426 | + if (!success) { | |
| 427 | + lua_pop(L, 1); /* remove last result */ | |
| 428 | + break; /* read fails */ | |
| 429 | + } | |
| 430 | + } endloop: | |
| 431 | + return n - firstarg; | |
| 343 | 432 | } |
| 344 | 433 | |
| 345 | 434 | /* }====================================================== */ |
| 346 | 435 | |
| 347 | 436 | |
| 348 | −static void io_write (void) { | |
| 349 | − int arg = FIRSTARG; | |
| 350 | − FILE *f = getfileparam(FOUTPUT, &arg); | |
| 437 | +static int io_write (lua_State *L) { | |
| 438 | + int lastarg = lua_gettop(L) - 1; | |
| 439 | + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); | |
| 440 | + int arg = 1; | |
| 351 | 441 | int status = 1; |
| 352 | − char *s; | |
| 353 | − long l; | |
| 354 | − while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL) | |
| 355 | − status = status && ((long)fwrite(s, 1, l, f) == l); | |
| 356 | − pushresult(status); | |
| 442 | + FILE *f = gethandle(L, ctrl, arg); | |
| 443 | + if (f) arg++; | |
| 444 | + else f = getfilebyref(L, ctrl, OUTFILE); /* get _OUTPUT */ | |
| 445 | + for (; arg <= lastarg; arg++) { | |
| 446 | + if (lua_type(L, arg) == LUA_TNUMBER) { /* LUA_NUMBER */ | |
| 447 | + /* optimization: could be done exactly as for strings */ | |
| 448 | + status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0; | |
| 449 | + } | |
| 450 | + else { | |
| 451 | + size_t l; | |
| 452 | + const char *s = luaL_check_lstr(L, arg, &l); | |
| 453 | + status = status && (fwrite(s, sizeof(char), l, f) == l); | |
| 454 | + } | |
| 455 | + } | |
| 456 | + pushresult(L, status); | |
| 457 | + return 1; | |
| 357 | 458 | } |
| 358 | 459 | |
| 359 | 460 | |
| 360 | −static void io_seek (void) { | |
| 361 | − static int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; | |
| 362 | − static char *modenames[] = {"set", "cur", "end", NULL}; | |
| 363 | − FILE *f = getnonullfile(FIRSTARG); | |
| 364 | − int op = luaL_findstring(luaL_opt_string(FIRSTARG+1, "cur"), modenames); | |
| 365 | − long offset = luaL_opt_long(FIRSTARG+2, 0); | |
| 366 | − luaL_arg_check(op != -1, FIRSTARG+1, "invalid mode"); | |
| 461 | +static int io_seek (lua_State *L) { | |
| 462 | + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; | |
| 463 | + static const char *const modenames[] = {"set", "cur", "end", NULL}; | |
| 464 | + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); | |
| 465 | + FILE *f; | |
| 466 | + int op; | |
| 467 | + long offset; | |
| 468 | + lua_pop(L, 1); /* remove upvalue */ | |
| 469 | + f = getnonullfile(L, ctrl, 1); | |
| 470 | + op = luaL_findstring(luaL_opt_string(L, 2, "cur"), modenames); | |
| 471 | + offset = luaL_opt_long(L, 3, 0); | |
| 472 | + luaL_arg_check(L, op != -1, 2, "invalid mode"); | |
| 367 | 473 | op = fseek(f, offset, mode[op]); |
| 368 | 474 | if (op) |
| 369 | − pushresult(0); /* error */ | |
| 370 | − else | |
| 371 | − lua_pushnumber(ftell(f)); | |
| 475 | + return pushresult(L, 0); /* error */ | |
| 476 | + else { | |
| 477 | + lua_pushnumber(L, ftell(f)); | |
| 478 | + return 1; | |
| 479 | + } | |
| 372 | 480 | } |
| 373 | 481 | |
| 374 | 482 | |
| 375 | −static void io_flush (void) { | |
| 376 | − FILE *f = getfile(FIRSTARG); | |
| 377 | − luaL_arg_check(f || lua_getparam(FIRSTARG) == LUA_NOOBJECT, FIRSTARG, | |
| 378 | − "invalid file handle"); | |
| 379 | − pushresult(fflush(f) == 0); | |
| 483 | +static int io_flush (lua_State *L) { | |
| 484 | + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); | |
| 485 | + FILE *f; | |
| 486 | + lua_pop(L, 1); /* remove upvalue */ | |
| 487 | + f = gethandle(L, ctrl, 1); | |
| 488 | + luaL_arg_check(L, f || lua_isnull(L, 1), 1, "invalid file handle"); | |
| 489 | + return pushresult(L, fflush(f) == 0); | |
| 380 | 490 | } |
| 381 | 491 | |
| 382 | 492 | /* }====================================================== */ |
| @@ -388,145 +498,165 @@ static void io_flush (void) { · 5 unmodified lines | ||
| 388 | 498 | ** ======================================================= |
| 389 | 499 | */ |
| 390 | 500 | |
| 391 | −static void io_execute (void) { | |
| 392 | − lua_pushnumber(system(luaL_check_string(1))); | |
| 501 | +static int io_execute (lua_State *L) { | |
| 502 | + lua_pushnumber(L, system(luaL_check_string(L, 1))); | |
| 503 | + return 1; | |
| 393 | 504 | } |
| 394 | 505 | |
| 395 | 506 | |
| 396 | −static void io_remove (void) { | |
| 397 | − pushresult(remove(luaL_check_string(1)) == 0); | |
| 507 | +static int io_remove (lua_State *L) { | |
| 508 | + return pushresult(L, remove(luaL_check_string(L, 1)) == 0); | |
| 398 | 509 | } |
| 399 | 510 | |
| 400 | 511 | |
| 401 | −static void io_rename (void) { | |
| 402 | − pushresult(rename(luaL_check_string(1), | |
| 403 | − luaL_check_string(2)) == 0); | |
| 512 | +static int io_rename (lua_State *L) { | |
| 513 | + return pushresult(L, rename(luaL_check_string(L, 1), | |
| 514 | + luaL_check_string(L, 2)) == 0); | |
| 404 | 515 | } |
| 405 | 516 | |
| 406 | 517 | |
| 407 | −static void io_tmpname (void) { | |
| 408 | − lua_pushstring(tmpnam(NULL)); | |
| 518 | +static int io_tmpname (lua_State *L) { | |
| 519 | + lua_pushstring(L, tmpnam(NULL)); | |
| 520 | + return 1; | |
| 409 | 521 | } |
| 410 | 522 | |
| 411 | 523 | |
| 412 | 524 | |
| 413 | −static void io_getenv (void) { | |
| 414 | − lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */ | |
| 525 | +static int io_getenv (lua_State *L) { | |
| 526 | + lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */ | |
| 527 | + return 1; | |
| 415 | 528 | } |
| 416 | 529 | |
| 417 | 530 | |
| 418 | −static void io_clock (void) { | |
| 419 | − lua_pushnumber(((double)clock())/CLOCKS_PER_SEC); | |
| 531 | +static int io_clock (lua_State *L) { | |
| 532 | + lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC); | |
| 533 | + return 1; | |
| 420 | 534 | } |
| 421 | 535 | |
| 422 | 536 | |
| 423 | −static void io_date (void) { | |
| 537 | +static int io_date (lua_State *L) { | |
| 424 | 538 | char b[256]; |
| 425 | − char *s = luaL_opt_string(1, "%c"); | |
| 426 | − struct tm *tm; | |
| 539 | + const char *s = luaL_opt_string(L, 1, "%c"); | |
| 540 | + struct tm *stm; | |
| 427 | 541 | time_t t; |
| 428 | − time(&t); tm = localtime(&t); | |
| 429 | − if (strftime(b,sizeof(b),s,tm)) | |
| 430 | − lua_pushstring(b); | |
| 542 | + time(&t); stm = localtime(&t); | |
| 543 | + if (strftime(b, sizeof(b), s, stm)) | |
| 544 | + lua_pushstring(L, b); | |
| 431 | 545 | else |
| 432 | − lua_error("invalid `date' format"); | |
| 546 | + lua_error(L, "invalid `date' format"); | |
| 547 | + return 1; | |
| 433 | 548 | } |
| 434 | 549 | |
| 435 | 550 | |
| 436 | −static void setloc (void) { | |
| 437 | − static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, | |
| 438 | − LC_TIME}; | |
| 439 | − static char *catnames[] = {"all", "collate", "ctype", "monetary", | |
| 551 | +static int setloc (lua_State *L) { | |
| 552 | + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, | |
| 553 | + LC_NUMERIC, LC_TIME}; | |
| 554 | + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", | |
| 440 | 555 | "numeric", "time", NULL}; |
| 441 | − int op = luaL_findstring(luaL_opt_string(2, "all"), catnames); | |
| 442 | − luaL_arg_check(op != -1, 2, "invalid option"); | |
| 443 | − lua_pushstring(setlocale(cat[op], luaL_check_string(1))); | |
| 556 | + int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames); | |
| 557 | + luaL_arg_check(L, op != -1, 2, "invalid option"); | |
| 558 | + lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1))); | |
| 559 | + return 1; | |
| 444 | 560 | } |
| 445 | 561 | |
| 446 | 562 | |
| 447 | −static void io_exit (void) { | |
| 448 | − lua_Object o = lua_getparam(1); | |
| 449 | − exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1); | |
| 563 | +static int io_exit (lua_State *L) { | |
| 564 | + exit(luaL_opt_int(L, 1, EXIT_SUCCESS)); | |
| 565 | + return 0; /* to avoid warnings */ | |
| 450 | 566 | } |
| 451 | 567 | |
| 452 | 568 | /* }====================================================== */ |
| 453 | 569 | |
| 454 | 570 | |
| 455 | 571 | |
| 456 | −static void io_debug (void) { | |
| 572 | +static int io_debug (lua_State *L) { | |
| 457 | 573 | for (;;) { |
| 458 | 574 | char buffer[250]; |
| 459 | 575 | fprintf(stderr, "lua_debug> "); |
| 460 | 576 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || |
| 461 | 577 | strcmp(buffer, "cont\n") == 0) |
| 462 | − return; | |
| 463 | − lua_dostring(buffer); | |
| 578 | + return 0; | |
| 579 | + lua_dostring(L, buffer); | |
| 580 | + lua_settop(L, 0); /* remove eventual returns */ | |
| 464 | 581 | } |
| 465 | 582 | } |
| 466 | 583 | |
| 467 | 584 | |
| 585 | +#define LEVELS1 12 /* size of the first part of the stack */ | |
| 586 | +#define LEVELS2 10 /* size of the second part of the stack */ | |
| 468 | 587 | |
| 469 | −#define MESSAGESIZE 150 | |
| 470 | −#define MAXMESSAGE (MESSAGESIZE*10) | |
| 471 | − | |
| 472 | − | |
| 473 | −#define MAXSRC 60 | |
| 474 | − | |
| 475 | − | |
| 476 | −static void errorfb (void) { | |
| 477 | − char buff[MAXMESSAGE]; | |
| 588 | +static int errorfb (lua_State *L) { | |
| 478 | 589 | int level = 1; /* skip level 0 (it's this function) */ |
| 479 | − lua_Object func; | |
| 480 | − sprintf(buff, "lua error: %.200s\n", lua_getstring(lua_getparam(1))); | |
| 481 | − while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) { | |
| 482 | − char *name; | |
| 483 | − int currentline; | |
| 484 | − char *chunkname; | |
| 485 | − char buffchunk[MAXSRC]; | |
| 486 | − int linedefined; | |
| 487 | − lua_funcinfo(func, &chunkname, &linedefined); | |
| 488 | − luaL_chunkid(buffchunk, chunkname, sizeof(buffchunk)); | |
| 489 | − if (level == 2) strcat(buff, "Active Stack:\n"); | |
| 490 | − strcat(buff, " "); | |
| 491 | − if (strlen(buff) > MAXMESSAGE-MESSAGESIZE) { | |
| 492 | − strcat(buff, "...\n"); | |
| 493 | − break; /* buffer is full */ | |
| 590 | + int firstpart = 1; /* still before eventual `...' */ | |
| 591 | + lua_Debug ar; | |
| 592 | + luaL_Buffer b; | |
| 593 | + luaL_buffinit(L, &b); | |
| 594 | + luaL_addstring(&b, "error: "); | |
| 595 | + luaL_addstring(&b, luaL_check_string(L, 1)); | |
| 596 | + luaL_addstring(&b, "\n"); | |
| 597 | + while (lua_getstack(L, level++, &ar)) { | |
| 598 | + char buff[120]; /* enough to fit following `sprintf's */ | |
| 599 | + if (level == 2) | |
| 600 | + luaL_addstring(&b, "stack traceback:\n"); | |
| 601 | + else if (level > LEVELS1 && firstpart) { | |
| 602 | + /* no more than `LEVELS2' more levels? */ | |
| 603 | + if (!lua_getstack(L, level+LEVELS2, &ar)) | |
| 604 | + level--; /* keep going */ | |
| 605 | + else { | |
| 606 | + luaL_addstring(&b, " ...\n"); /* too many levels */ | |
| 607 | + while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ | |
| 608 | + level++; | |
| 609 | + } | |
| 610 | + firstpart = 0; | |
| 611 | + continue; | |
| 494 | 612 | } |
| 495 | − switch (*lua_getobjname(func, &name)) { | |
| 496 | − case 'g': | |
| 497 | − sprintf(buff+strlen(buff), "function `%.50s'", name); | |
| 613 | + sprintf(buff, "%4d: ", level-1); | |
| 614 | + luaL_addstring(&b, buff); | |
| 615 | + lua_getinfo(L, "Snl", &ar); | |
| 616 | + switch (*ar.namewhat) { | |
| 617 | + case 'g': case 'l': /* global, local */ | |
| 618 | + sprintf(buff, "function `%.50s'", ar.name); | |
| 498 | 619 | break; |
| 499 | − case 't': | |
| 500 | − sprintf(buff+strlen(buff), "`%.50s' tag method", name); | |
| 620 | + case 'f': /* field */ | |
| 621 | + sprintf(buff, "method `%.50s'", ar.name); | |
| 622 | + break; | |
| 623 | + case 't': /* tag method */ | |
| 624 | + sprintf(buff, "`%.50s' tag method", ar.name); | |
| 501 | 625 | break; |
| 502 | 626 | default: { |
| 503 | − if (linedefined == 0) | |
| 504 | − sprintf(buff+strlen(buff), "main of %.70s", buffchunk); | |
| 505 | − else if (linedefined < 0) | |
| 506 | − sprintf(buff+strlen(buff), "%.70s", buffchunk); | |
| 627 | + if (*ar.what == 'm') /* main? */ | |
| 628 | + sprintf(buff, "main of %.70s", ar.short_src); | |
| 629 | + else if (*ar.what == 'C') /* C function? */ | |
| 630 | + sprintf(buff, "%.70s", ar.short_src); | |
| 507 | 631 | else |
| 508 | − sprintf(buff+strlen(buff), "function <%d:%.70s>", | |
| 509 | − linedefined, buffchunk); | |
| 510 | − chunkname = NULL; | |
| 632 | + sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src); | |
| 633 | + ar.source = NULL; /* do not print source again */ | |
| 511 | 634 | } |
| 512 | 635 | } |
| 513 | − if ((currentline = lua_currentline(func)) > 0) | |
| 514 | − sprintf(buff+strlen(buff), " at line %d", currentline); | |
| 515 | − if (chunkname) | |
| 516 | − sprintf(buff+strlen(buff), " [%.70s]", buffchunk); | |
| 517 | − strcat(buff, "\n"); | |
| 636 | + luaL_addstring(&b, buff); | |
| 637 | + if (ar.currentline > 0) { | |
| 638 | + sprintf(buff, " at line %d", ar.currentline); | |
| 639 | + luaL_addstring(&b, buff); | |
| 640 | + } | |
| 641 | + if (ar.source) { | |
| 642 | + sprintf(buff, " [%.70s]", ar.short_src); | |
| 643 | + luaL_addstring(&b, buff); | |
| 644 | + } | |
| 645 | + luaL_addstring(&b, "\n"); | |
| 518 | 646 | } |
| 519 | − func = lua_rawgetglobal("_ALERT"); | |
| 520 | − if (lua_isfunction(func)) { /* avoid error loop if _ALERT is not defined */ | |
| 521 | − lua_pushstring(buff); | |
| 522 | − lua_callfunction(func); | |
| 647 | + luaL_pushresult(&b); | |
| 648 | + lua_getglobal(L, LUA_ALERT); | |
| 649 | + if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ | |
| 650 | + lua_pushvalue(L, -2); /* error message */ | |
| 651 | + lua_rawcall(L, 1, 0); | |
| 523 | 652 | } |
| 653 | + return 0; | |
| 524 | 654 | } |
| 525 | 655 | |
| 526 | 656 | |
| 527 | 657 | |
| 528 | −static struct luaL_reg iolib[] = { | |
| 529 | − {"_ERRORMESSAGE", errorfb}, | |
| 658 | +static const struct luaL_reg iolib[] = { | |
| 659 | + {LUA_ERRORMESSAGE, errorfb}, | |
| 530 | 660 | {"clock", io_clock}, |
| 531 | 661 | {"date", io_date}, |
| 532 | 662 | {"debug", io_debug}, |
| @@ -540,7 +670,7 @@ static struct luaL_reg iolib[] = { · 7 unmodified lines | ||
| 540 | 670 | }; |
| 541 | 671 | |
| 542 | 672 | |
| 543 | −static struct luaL_reg iolibtag[] = { | |
| 673 | +static const struct luaL_reg iolibtag[] = { | |
| 544 | 674 | {"appendto", io_appendto}, |
| 545 | 675 | {"closefile", io_close}, |
| 546 | 676 | {"flush", io_flush}, |
| @@ -553,31 +683,36 @@ static struct luaL_reg iolibtag[] = { · 6 unmodified lines | ||
| 553 | 683 | }; |
| 554 | 684 | |
| 555 | 685 | |
| 556 | −static void openwithtags (void) { | |
| 557 | − int i; | |
| 558 | − int iotag = lua_newtag(); | |
| 559 | − lua_newtag(); /* alloc CLOSEDTAG: assume that CLOSEDTAG = iotag-1 */ | |
| 686 | +static void openwithcontrol (lua_State *L) { | |
| 687 | + IOCtrl *ctrl = (IOCtrl *)lua_newuserdata(L, sizeof(IOCtrl)); | |
| 688 | + unsigned int i; | |
| 689 | + ctrl->iotag = lua_newtag(L); | |
| 690 | + ctrl->closedtag = lua_newtag(L); | |
| 560 | 691 | for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) { |
| 561 | − /* put iotag as upvalue for these functions */ | |
| 562 | − lua_pushnumber(iotag); | |
| 563 | − lua_pushcclosure(iolibtag[i].func, 1); | |
| 564 | − lua_setglobal(iolibtag[i].name); | |
| 692 | + /* put `ctrl' as upvalue for these functions */ | |
| 693 | + lua_pushvalue(L, -1); | |
| 694 | + lua_pushcclosure(L, iolibtag[i].func, 1); | |
| 695 | + lua_setglobal(L, iolibtag[i].name); | |
| 565 | 696 | } |
| 697 | + /* create references to variable names */ | |
| 698 | + lua_pushstring(L, filenames[INFILE]); | |
| 699 | + ctrl->ref[INFILE] = lua_ref(L, 1); | |
| 700 | + lua_pushstring(L, filenames[OUTFILE]); | |
| 701 | + ctrl->ref[OUTFILE] = lua_ref(L, 1); | |
| 566 | 702 | /* predefined file handles */ |
| 567 | − setfile(stdin, FINPUT, iotag); | |
| 568 | − setfile(stdout, FOUTPUT, iotag); | |
| 569 | − setfile(stdin, "_STDIN", iotag); | |
| 570 | − setfile(stdout, "_STDOUT", iotag); | |
| 571 | − setfile(stderr, "_STDERR", iotag); | |
| 572 | − /* close file when collected */ | |
| 573 | − lua_pushnumber(iotag); | |
| 574 | − lua_pushcclosure(gc_close, 1); | |
| 575 | − lua_settagmethod(iotag, "gc"); | |
| 576 | −} | |
| 577 | − | |
| 578 | −void lua_iolibopen (void) { | |
| 579 | − /* register lib functions */ | |
| 580 | − luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); | |
| 581 | − openwithtags(); | |
| 703 | + setfile(L, ctrl, stdin, INFILE); | |
| 704 | + setfile(L, ctrl, stdout, OUTFILE); | |
| 705 | + setfilebyname(L, ctrl, stdin, "_STDIN"); | |
| 706 | + setfilebyname(L, ctrl, stdout, "_STDOUT"); | |
| 707 | + setfilebyname(L, ctrl, stderr, "_STDERR"); | |
| 708 | + /* close files when collected */ | |
| 709 | + lua_pushcclosure(L, file_collect, 1); /* pops `ctrl' from stack */ | |
| 710 | + lua_settagmethod(L, ctrl->iotag, "gc"); | |
| 711 | +} | |
| 712 | + | |
| 713 | + | |
| 714 | +LUALIB_API void lua_iolibopen (lua_State *L) { | |
| 715 | + luaL_openl(L, iolib); | |
| 716 | + openwithcontrol(L); | |
| 582 | 717 | } |
| 583 | 718 | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lmathlib.c,v 1.17 1999/07/07 17:54:08 roberto Exp $ | |
| 3 | −** Lua standard mathematical library | |
| 2 | +** $Id: lmathlib.c,v 1.32 2000/10/31 13:10:24 roberto Exp $ | |
| 3 | +** Standard mathematical library | |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| @@ -8,14 +8,15 @@ · 1 unmodified line | ||
| 8 | 8 | #include <stdlib.h> |
| 9 | 9 | #include <math.h> |
| 10 | 10 | |
| 11 | −#include "lauxlib.h" | |
| 12 | 11 | #include "lua.h" |
| 12 | + | |
| 13 | +#include "lauxlib.h" | |
| 13 | 14 | #include "lualib.h" |
| 14 | 15 | |
| 15 | 16 | |
| 16 | 17 | #undef PI |
| 17 | −#define PI (3.14159265358979323846) | |
| 18 | −#define RADIANS_PER_DEGREE (PI/180.0) | |
| 18 | +#define PI (3.14159265358979323846) | |
| 19 | +#define RADIANS_PER_DEGREE (PI/180.0) | |
| 19 | 20 | |
| 20 | 21 | |
| 21 | 22 | |
| @@ -32,139 +33,173 @@ · 10 unmodified lines | ||
| 32 | 33 | #endif |
| 33 | 34 | |
| 34 | 35 | |
| 35 | −static void math_abs (void) { | |
| 36 | − lua_pushnumber(fabs(luaL_check_number(1))); | |
| 36 | +static int math_abs (lua_State *L) { | |
| 37 | + lua_pushnumber(L, fabs(luaL_check_number(L, 1))); | |
| 38 | + return 1; | |
| 37 | 39 | } |
| 38 | 40 | |
| 39 | −static void math_sin (void) { | |
| 40 | − lua_pushnumber(sin(TORAD(luaL_check_number(1)))); | |
| 41 | +static int math_sin (lua_State *L) { | |
| 42 | + lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1)))); | |
| 43 | + return 1; | |
| 41 | 44 | } |
| 42 | 45 | |
| 43 | −static void math_cos (void) { | |
| 44 | − lua_pushnumber(cos(TORAD(luaL_check_number(1)))); | |
| 46 | +static int math_cos (lua_State *L) { | |
| 47 | + lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1)))); | |
| 48 | + return 1; | |
| 45 | 49 | } |
| 46 | 50 | |
| 47 | −static void math_tan (void) { | |
| 48 | − lua_pushnumber(tan(TORAD(luaL_check_number(1)))); | |
| 51 | +static int math_tan (lua_State *L) { | |
| 52 | + lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1)))); | |
| 53 | + return 1; | |
| 49 | 54 | } |
| 50 | 55 | |
| 51 | −static void math_asin (void) { | |
| 52 | − lua_pushnumber(FROMRAD(asin(luaL_check_number(1)))); | |
| 56 | +static int math_asin (lua_State *L) { | |
| 57 | + lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1)))); | |
| 58 | + return 1; | |
| 53 | 59 | } |
| 54 | 60 | |
| 55 | −static void math_acos (void) { | |
| 56 | − lua_pushnumber(FROMRAD(acos(luaL_check_number(1)))); | |
| 61 | +static int math_acos (lua_State *L) { | |
| 62 | + lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1)))); | |
| 63 | + return 1; | |
| 57 | 64 | } |
| 58 | 65 | |
| 59 | −static void math_atan (void) { | |
| 60 | − lua_pushnumber(FROMRAD(atan(luaL_check_number(1)))); | |
| 66 | +static int math_atan (lua_State *L) { | |
| 67 | + lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1)))); | |
| 68 | + return 1; | |
| 61 | 69 | } |
| 62 | 70 | |
| 63 | −static void math_atan2 (void) { | |
| 64 | − lua_pushnumber(FROMRAD(atan2(luaL_check_number(1), luaL_check_number(2)))); | |
| 71 | +static int math_atan2 (lua_State *L) { | |
| 72 | + lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2)))); | |
| 73 | + return 1; | |
| 65 | 74 | } |
| 66 | 75 | |
| 67 | −static void math_ceil (void) { | |
| 68 | − lua_pushnumber(ceil(luaL_check_number(1))); | |
| 76 | +static int math_ceil (lua_State *L) { | |
| 77 | + lua_pushnumber(L, ceil(luaL_check_number(L, 1))); | |
| 78 | + return 1; | |
| 69 | 79 | } |
| 70 | 80 | |
| 71 | −static void math_floor (void) { | |
| 72 | − lua_pushnumber(floor(luaL_check_number(1))); | |
| 81 | +static int math_floor (lua_State *L) { | |
| 82 | + lua_pushnumber(L, floor(luaL_check_number(L, 1))); | |
| 83 | + return 1; | |
| 73 | 84 | } |
| 74 | 85 | |
| 75 | −static void math_mod (void) { | |
| 76 | − lua_pushnumber(fmod(luaL_check_number(1), luaL_check_number(2))); | |
| 86 | +static int math_mod (lua_State *L) { | |
| 87 | + lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2))); | |
| 88 | + return 1; | |
| 77 | 89 | } |
| 78 | 90 | |
| 79 | −static void math_sqrt (void) { | |
| 80 | − lua_pushnumber(sqrt(luaL_check_number(1))); | |
| 91 | +static int math_sqrt (lua_State *L) { | |
| 92 | + lua_pushnumber(L, sqrt(luaL_check_number(L, 1))); | |
| 93 | + return 1; | |
| 81 | 94 | } |
| 82 | 95 | |
| 83 | −static void math_pow (void) { | |
| 84 | − lua_pushnumber(pow(luaL_check_number(1), luaL_check_number(2))); | |
| 96 | +static int math_pow (lua_State *L) { | |
| 97 | + lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2))); | |
| 98 | + return 1; | |
| 85 | 99 | } |
| 86 | 100 | |
| 87 | −static void math_log (void) { | |
| 88 | − lua_pushnumber(log(luaL_check_number(1))); | |
| 101 | +static int math_log (lua_State *L) { | |
| 102 | + lua_pushnumber(L, log(luaL_check_number(L, 1))); | |
| 103 | + return 1; | |
| 89 | 104 | } |
| 90 | 105 | |
| 91 | −static void math_log10 (void) { | |
| 92 | − lua_pushnumber(log10(luaL_check_number(1))); | |
| 106 | +static int math_log10 (lua_State *L) { | |
| 107 | + lua_pushnumber(L, log10(luaL_check_number(L, 1))); | |
| 108 | + return 1; | |
| 93 | 109 | } |
| 94 | 110 | |
| 95 | −static void math_exp (void) { | |
| 96 | − lua_pushnumber(exp(luaL_check_number(1))); | |
| 111 | +static int math_exp (lua_State *L) { | |
| 112 | + lua_pushnumber(L, exp(luaL_check_number(L, 1))); | |
| 113 | + return 1; | |
| 97 | 114 | } |
| 98 | 115 | |
| 99 | −static void math_deg (void) { | |
| 100 | − lua_pushnumber(luaL_check_number(1)/RADIANS_PER_DEGREE); | |
| 116 | +static int math_deg (lua_State *L) { | |
| 117 | + lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE); | |
| 118 | + return 1; | |
| 101 | 119 | } |
| 102 | 120 | |
| 103 | −static void math_rad (void) { | |
| 104 | − lua_pushnumber(luaL_check_number(1)*RADIANS_PER_DEGREE); | |
| 121 | +static int math_rad (lua_State *L) { | |
| 122 | + lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE); | |
| 123 | + return 1; | |
| 105 | 124 | } |
| 106 | 125 | |
| 107 | −static void math_frexp (void) { | |
| 126 | +static int math_frexp (lua_State *L) { | |
| 108 | 127 | int e; |
| 109 | − lua_pushnumber(frexp(luaL_check_number(1), &e)); | |
| 110 | − lua_pushnumber(e); | |
| 128 | + lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e)); | |
| 129 | + lua_pushnumber(L, e); | |
| 130 | + return 2; | |
| 111 | 131 | } |
| 112 | 132 | |
| 113 | −static void math_ldexp (void) { | |
| 114 | − lua_pushnumber(ldexp(luaL_check_number(1), luaL_check_int(2))); | |
| 133 | +static int math_ldexp (lua_State *L) { | |
| 134 | + lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2))); | |
| 135 | + return 1; | |
| 115 | 136 | } |
| 116 | 137 | |
| 117 | 138 | |
| 118 | 139 | |
| 119 | −static void math_min (void) { | |
| 120 | − int i = 1; | |
| 121 | − double dmin = luaL_check_number(i); | |
| 122 | − while (lua_getparam(++i) != LUA_NOOBJECT) { | |
| 123 | − double d = luaL_check_number(i); | |
| 140 | +static int math_min (lua_State *L) { | |
| 141 | + int n = lua_gettop(L); /* number of arguments */ | |
| 142 | + double dmin = luaL_check_number(L, 1); | |
| 143 | + int i; | |
| 144 | + for (i=2; i<=n; i++) { | |
| 145 | + double d = luaL_check_number(L, i); | |
| 124 | 146 | if (d < dmin) |
| 125 | 147 | dmin = d; |
| 126 | 148 | } |
| 127 | − lua_pushnumber(dmin); | |
| 149 | + lua_pushnumber(L, dmin); | |
| 150 | + return 1; | |
| 128 | 151 | } |
| 129 | 152 | |
| 130 | 153 | |
| 131 | −static void math_max (void) { | |
| 132 | − int i = 1; | |
| 133 | − double dmax = luaL_check_number(i); | |
| 134 | − while (lua_getparam(++i) != LUA_NOOBJECT) { | |
| 135 | − double d = luaL_check_number(i); | |
| 154 | +static int math_max (lua_State *L) { | |
| 155 | + int n = lua_gettop(L); /* number of arguments */ | |
| 156 | + double dmax = luaL_check_number(L, 1); | |
| 157 | + int i; | |
| 158 | + for (i=2; i<=n; i++) { | |
| 159 | + double d = luaL_check_number(L, i); | |
| 136 | 160 | if (d > dmax) |
| 137 | 161 | dmax = d; |
| 138 | 162 | } |
| 139 | − lua_pushnumber(dmax); | |
| 163 | + lua_pushnumber(L, dmax); | |
| 164 | + return 1; | |
| 140 | 165 | } |
| 141 | 166 | |
| 142 | 167 | |
| 143 | −static void math_random (void) { | |
| 168 | +static int math_random (lua_State *L) { | |
| 144 | 169 | /* the '%' avoids the (rare) case of r==1, and is needed also because on |
| 145 | − some systems (SunOS!) "rand()" may return a value bigger than RAND_MAX */ | |
| 170 | + some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */ | |
| 146 | 171 | double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX; |
| 147 | − int l = luaL_opt_int(1, 0); | |
| 148 | − if (l == 0) | |
| 149 | − lua_pushnumber(r); | |
| 150 | − else { | |
| 151 | − int u = luaL_opt_int(2, 0); | |
| 152 | − if (u == 0) { | |
| 153 | − u = l; | |
| 154 | − l = 1; | |
| 172 | + switch (lua_gettop(L)) { /* check number of arguments */ | |
| 173 | + case 0: { /* no arguments */ | |
| 174 | + lua_pushnumber(L, r); /* Number between 0 and 1 */ | |
| 175 | + break; | |
| 176 | + } | |
| 177 | + case 1: { /* only upper limit */ | |
| 178 | + int u = luaL_check_int(L, 1); | |
| 179 | + luaL_arg_check(L, 1<=u, 1, "interval is empty"); | |
| 180 | + lua_pushnumber(L, (int)(r*u)+1); /* integer between 1 and `u' */ | |
| 181 | + break; | |
| 182 | + } | |
| 183 | + case 2: { /* lower and upper limits */ | |
| 184 | + int l = luaL_check_int(L, 1); | |
| 185 | + int u = luaL_check_int(L, 2); | |
| 186 | + luaL_arg_check(L, l<=u, 2, "interval is empty"); | |
| 187 | + lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */ | |
| 188 | + break; | |
| 155 | 189 | } |
| 156 | − luaL_arg_check(l<=u, 1, "interval is empty"); | |
| 157 | − lua_pushnumber((int)(r*(u-l+1))+l); | |
| 190 | + default: lua_error(L, "wrong number of arguments"); | |
| 158 | 191 | } |
| 192 | + return 1; | |
| 159 | 193 | } |
| 160 | 194 | |
| 161 | 195 | |
| 162 | −static void math_randomseed (void) { | |
| 163 | − srand(luaL_check_int(1)); | |
| 196 | +static int math_randomseed (lua_State *L) { | |
| 197 | + srand(luaL_check_int(L, 1)); | |
| 198 | + return 0; | |
| 164 | 199 | } |
| 165 | 200 | |
| 166 | 201 | |
| 167 | −static struct luaL_reg mathlib[] = { | |
| 202 | +static const struct luaL_reg mathlib[] = { | |
| 168 | 203 | {"abs", math_abs}, |
| 169 | 204 | {"sin", math_sin}, |
| 170 | 205 | {"cos", math_cos}, |
| @@ -193,11 +228,11 @@ static struct luaL_reg mathlib[] = { · 22 unmodified lines | ||
| 193 | 228 | /* |
| 194 | 229 | ** Open math library |
| 195 | 230 | */ |
| 196 | −void lua_mathlibopen (void) { | |
| 197 | − luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0]))); | |
| 198 | − lua_pushcfunction(math_pow); | |
| 199 | − lua_pushnumber(0); /* to get its tag */ | |
| 200 | − lua_settagmethod(lua_tag(lua_pop()), "pow"); | |
| 201 | − lua_pushnumber(PI); lua_setglobal("PI"); | |
| 231 | +LUALIB_API void lua_mathlibopen (lua_State *L) { | |
| 232 | + luaL_openl(L, mathlib); | |
| 233 | + lua_pushcfunction(L, math_pow); | |
| 234 | + lua_settagmethod(L, LUA_TNUMBER, "pow"); | |
| 235 | + lua_pushnumber(L, PI); | |
| 236 | + lua_setglobal(L, "PI"); | |
| 202 | 237 | } |
| 203 | 238 | |
| @@ -1,112 +1,111 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lstrlib.c,v 1.32 1999/06/17 17:04:03 roberto Exp $ | |
| 3 | −** Standard library for strings and pattern-matching | |
| 2 | +** $Id: lstrlib.c,v 1.56 2000/10/27 16:15:53 roberto Exp $ | |
| 3 | +** Standard library for string operations and pattern-matching | |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | 8 | #include <ctype.h> |
| 9 | +#include <stddef.h> | |
| 9 | 10 | #include <stdio.h> |
| 10 | 11 | #include <stdlib.h> |
| 11 | 12 | #include <string.h> |
| 12 | 13 | |
| 13 | −#include "lauxlib.h" | |
| 14 | 14 | #include "lua.h" |
| 15 | −#include "lualib.h" | |
| 16 | − | |
| 17 | − | |
| 18 | − | |
| 19 | −static void addnchar (char *s, int n) | |
| 20 | −{ | |
| 21 | − char *b = luaL_openspace(n); | |
| 22 | − memcpy(b, s, n); | |
| 23 | − luaL_addsize(n); | |
| 24 | −} | |
| 25 | 15 | |
| 16 | +#include "lauxlib.h" | |
| 17 | +#include "lualib.h" | |
| 26 | 18 | |
| 27 | −static void str_len (void) | |
| 28 | −{ | |
| 29 | − long l; | |
| 30 | − luaL_check_lstr(1, &l); | |
| 31 | − lua_pushnumber(l); | |
| 32 | −} | |
| 33 | 19 | |
| 34 | 20 | |
| 35 | −static void closeandpush (void) { | |
| 36 | − lua_pushlstring(luaL_buffer(), luaL_getsize()); | |
| 21 | +static int str_len (lua_State *L) { | |
| 22 | + size_t l; | |
| 23 | + luaL_check_lstr(L, 1, &l); | |
| 24 | + lua_pushnumber(L, l); | |
| 25 | + return 1; | |
| 37 | 26 | } |
| 38 | 27 | |
| 39 | 28 | |
| 40 | −static long posrelat (long pos, long len) { | |
| 29 | +static long posrelat (long pos, size_t len) { | |
| 41 | 30 | /* relative string position: negative means back from end */ |
| 42 | − return (pos>=0) ? pos : len+pos+1; | |
| 31 | + return (pos>=0) ? pos : (long)len+pos+1; | |
| 43 | 32 | } |
| 44 | 33 | |
| 45 | 34 | |
| 46 | −static void str_sub (void) { | |
| 47 | − long l; | |
| 48 | − char *s = luaL_check_lstr(1, &l); | |
| 49 | − long start = posrelat(luaL_check_long(2), l); | |
| 50 | − long end = posrelat(luaL_opt_long(3, -1), l); | |
| 35 | +static int str_sub (lua_State *L) { | |
| 36 | + size_t l; | |
| 37 | + const char *s = luaL_check_lstr(L, 1, &l); | |
| 38 | + long start = posrelat(luaL_check_long(L, 2), l); | |
| 39 | + long end = posrelat(luaL_opt_long(L, 3, -1), l); | |
| 51 | 40 | if (start < 1) start = 1; |
| 52 | − if (end > l) end = l; | |
| 41 | + if (end > (long)l) end = l; | |
| 53 | 42 | if (start <= end) |
| 54 | − lua_pushlstring(s+start-1, end-start+1); | |
| 55 | − else lua_pushstring(""); | |
| 43 | + lua_pushlstring(L, s+start-1, end-start+1); | |
| 44 | + else lua_pushstring(L, ""); | |
| 45 | + return 1; | |
| 56 | 46 | } |
| 57 | 47 | |
| 58 | 48 | |
| 59 | −static void str_lower (void) { | |
| 60 | − long l; | |
| 61 | − int i; | |
| 62 | − char *s = luaL_check_lstr(1, &l); | |
| 63 | − luaL_resetbuffer(); | |
| 49 | +static int str_lower (lua_State *L) { | |
| 50 | + size_t l; | |
| 51 | + size_t i; | |
| 52 | + luaL_Buffer b; | |
| 53 | + const char *s = luaL_check_lstr(L, 1, &l); | |
| 54 | + luaL_buffinit(L, &b); | |
| 64 | 55 | for (i=0; i<l; i++) |
| 65 | − luaL_addchar(tolower((unsigned char)(s[i]))); | |
| 66 | − closeandpush(); | |
| 56 | + luaL_putchar(&b, tolower((unsigned char)(s[i]))); | |
| 57 | + luaL_pushresult(&b); | |
| 58 | + return 1; | |
| 67 | 59 | } |
| 68 | 60 | |
| 69 | 61 | |
| 70 | −static void str_upper (void) { | |
| 71 | − long l; | |
| 72 | − int i; | |
| 73 | − char *s = luaL_check_lstr(1, &l); | |
| 74 | − luaL_resetbuffer(); | |
| 62 | +static int str_upper (lua_State *L) { | |
| 63 | + size_t l; | |
| 64 | + size_t i; | |
| 65 | + luaL_Buffer b; | |
| 66 | + const char *s = luaL_check_lstr(L, 1, &l); | |
| 67 | + luaL_buffinit(L, &b); | |
| 75 | 68 | for (i=0; i<l; i++) |
| 76 | − luaL_addchar(toupper((unsigned char)(s[i]))); | |
| 77 | − closeandpush(); | |
| 69 | + luaL_putchar(&b, toupper((unsigned char)(s[i]))); | |
| 70 | + luaL_pushresult(&b); | |
| 71 | + return 1; | |
| 78 | 72 | } |
| 79 | 73 | |
| 80 | −static void str_rep (void) | |
| 81 | −{ | |
| 82 | − long l; | |
| 83 | − char *s = luaL_check_lstr(1, &l); | |
| 84 | − int n = luaL_check_int(2); | |
| 85 | − luaL_resetbuffer(); | |
| 74 | +static int str_rep (lua_State *L) { | |
| 75 | + size_t l; | |
| 76 | + luaL_Buffer b; | |
| 77 | + const char *s = luaL_check_lstr(L, 1, &l); | |
| 78 | + int n = luaL_check_int(L, 2); | |
| 79 | + luaL_buffinit(L, &b); | |
| 86 | 80 | while (n-- > 0) |
| 87 | − addnchar(s, l); | |
| 88 | − closeandpush(); | |
| 81 | + luaL_addlstring(&b, s, l); | |
| 82 | + luaL_pushresult(&b); | |
| 83 | + return 1; | |
| 89 | 84 | } |
| 90 | 85 | |
| 91 | 86 | |
| 92 | −static void str_byte (void) { | |
| 93 | − long l; | |
| 94 | − char *s = luaL_check_lstr(1, &l); | |
| 95 | − long pos = posrelat(luaL_opt_long(2, 1), l); | |
| 96 | − luaL_arg_check(0<pos && pos<=l, 2, "out of range"); | |
| 97 | − lua_pushnumber((unsigned char)s[pos-1]); | |
| 87 | +static int str_byte (lua_State *L) { | |
| 88 | + size_t l; | |
| 89 | + const char *s = luaL_check_lstr(L, 1, &l); | |
| 90 | + long pos = posrelat(luaL_opt_long(L, 2, 1), l); | |
| 91 | + luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range"); | |
| 92 | + lua_pushnumber(L, (unsigned char)s[pos-1]); | |
| 93 | + return 1; | |
| 98 | 94 | } |
| 99 | 95 | |
| 100 | 96 | |
| 101 | −static void str_char (void) { | |
| 102 | − int i = 0; | |
| 103 | − luaL_resetbuffer(); | |
| 104 | − while (lua_getparam(++i) != LUA_NOOBJECT) { | |
| 105 | − double c = luaL_check_number(i); | |
| 106 | − luaL_arg_check((unsigned char)c == c, i, "invalid value"); | |
| 107 | − luaL_addchar((unsigned char)c); | |
| 97 | +static int str_char (lua_State *L) { | |
| 98 | + int n = lua_gettop(L); /* number of arguments */ | |
| 99 | + int i; | |
| 100 | + luaL_Buffer b; | |
| 101 | + luaL_buffinit(L, &b); | |
| 102 | + for (i=1; i<=n; i++) { | |
| 103 | + int c = luaL_check_int(L, i); | |
| 104 | + luaL_arg_check(L, (unsigned char)c == c, i, "invalid value"); | |
| 105 | + luaL_putchar(&b, (unsigned char)c); | |
| 108 | 106 | } |
| 109 | − closeandpush(); | |
| 107 | + luaL_pushresult(&b); | |
| 108 | + return 1; | |
| 110 | 109 | } |
| 111 | 110 | |
| 112 | 111 | |
| @@ -117,63 +116,53 @@ static void str_char (void) { · 4 unmodified lines | ||
| 117 | 116 | ** ======================================================= |
| 118 | 117 | */ |
| 119 | 118 | |
| 120 | −#ifndef MAX_CAPT | |
| 121 | −#define MAX_CAPT 32 /* arbitrary limit */ | |
| 119 | +#ifndef MAX_CAPTURES | |
| 120 | +#define MAX_CAPTURES 32 /* arbitrary limit */ | |
| 122 | 121 | #endif |
| 123 | 122 | |
| 124 | 123 | |
| 125 | 124 | struct Capture { |
| 126 | − char *src_end; /* end ('\0') of source string */ | |
| 125 | + const char *src_end; /* end ('\0') of source string */ | |
| 127 | 126 | int level; /* total number of captures (finished or unfinished) */ |
| 128 | 127 | struct { |
| 129 | − char *init; | |
| 130 | − int len; /* -1 signals unfinished capture */ | |
| 131 | − } capture[MAX_CAPT]; | |
| 128 | + const char *init; | |
| 129 | + long len; /* -1 signals unfinished capture */ | |
| 130 | + } capture[MAX_CAPTURES]; | |
| 132 | 131 | }; |
| 133 | 132 | |
| 134 | 133 | |
| 135 | −#define ESC '%' | |
| 136 | −#define SPECIALS "^$*+?.([%-" | |
| 134 | +#define ESC '%' | |
| 135 | +#define SPECIALS "^$*+?.([%-" | |
| 137 | 136 | |
| 138 | 137 | |
| 139 | −static void push_captures (struct Capture *cap) { | |
| 140 | − int i; | |
| 141 | − for (i=0; i<cap->level; i++) { | |
| 142 | − int l = cap->capture[i].len; | |
| 143 | − if (l == -1) lua_error("unfinished capture"); | |
| 144 | − lua_pushlstring(cap->capture[i].init, l); | |
| 145 | − } | |
| 146 | −} | |
| 147 | − | |
| 148 | − | |
| 149 | −static int check_cap (int l, struct Capture *cap) { | |
| 138 | +static int check_capture (lua_State *L, int l, struct Capture *cap) { | |
| 150 | 139 | l -= '1'; |
| 151 | 140 | if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) |
| 152 | − lua_error("invalid capture index"); | |
| 141 | + lua_error(L, "invalid capture index"); | |
| 153 | 142 | return l; |
| 154 | 143 | } |
| 155 | 144 | |
| 156 | 145 | |
| 157 | −static int capture_to_close (struct Capture *cap) { | |
| 146 | +static int capture_to_close (lua_State *L, struct Capture *cap) { | |
| 158 | 147 | int level = cap->level; |
| 159 | 148 | for (level--; level>=0; level--) |
| 160 | 149 | if (cap->capture[level].len == -1) return level; |
| 161 | − lua_error("invalid pattern capture"); | |
| 150 | + lua_error(L, "invalid pattern capture"); | |
| 162 | 151 | return 0; /* to avoid warnings */ |
| 163 | 152 | } |
| 164 | 153 | |
| 165 | 154 | |
| 166 | −char *luaI_classend (char *p) { | |
| 155 | +const char *luaI_classend (lua_State *L, const char *p) { | |
| 167 | 156 | switch (*p++) { |
| 168 | 157 | case ESC: |
| 169 | − if (*p == '\0') | |
| 170 | − luaL_verror("incorrect pattern (ends with `%c')", ESC); | |
| 158 | + if (*p == '\0') lua_error(L, "malformed pattern (ends with `%')"); | |
| 171 | 159 | return p+1; |
| 172 | 160 | case '[': |
| 173 | 161 | if (*p == '^') p++; |
| 174 | − if (*p == ']') p++; | |
| 175 | − p = strchr(p, ']'); | |
| 176 | − if (!p) lua_error("incorrect pattern (missing `]')"); | |
| 162 | + do { /* look for a ']' */ | |
| 163 | + if (*p == '\0') lua_error(L, "malformed pattern (missing `]')"); | |
| 164 | + if (*(p++) == ESC && *p != '\0') p++; /* skip escapes (e.g. '%]') */ | |
| 165 | + } while (*p != ']'); | |
| 177 | 166 | return p+1; |
| 178 | 167 | default: |
| 179 | 168 | return p; |
| @@ -181,7 +170,7 @@ char *luaI_classend (char *p) { · 1 unmodified line | ||
| 181 | 170 | } |
| 182 | 171 | |
| 183 | 172 | |
| 184 | −static int matchclass (int c, int cl) { | |
| 173 | +static int match_class (int c, int cl) { | |
| 185 | 174 | int res; |
| 186 | 175 | switch (tolower(cl)) { |
| 187 | 176 | case 'a' : res = isalpha(c); break; |
| @@ -201,36 +190,36 @@ static int matchclass (int c, int cl) { · 13 unmodified lines | ||
| 201 | 190 | |
| 202 | 191 | |
| 203 | 192 | |
| 204 | −static int matchbracketclass (int c, char *p, char *end) { | |
| 193 | +static int matchbracketclass (int c, const char *p, const char *endclass) { | |
| 205 | 194 | int sig = 1; |
| 206 | 195 | if (*(p+1) == '^') { |
| 207 | 196 | sig = 0; |
| 208 | 197 | p++; /* skip the '^' */ |
| 209 | 198 | } |
| 210 | − while (++p < end) { | |
| 199 | + while (++p < endclass) { | |
| 211 | 200 | if (*p == ESC) { |
| 212 | 201 | p++; |
| 213 | − if ((p < end) && matchclass(c, (unsigned char)*p)) | |
| 202 | + if (match_class(c, (unsigned char)*p)) | |
| 214 | 203 | return sig; |
| 215 | 204 | } |
| 216 | − else if ((*(p+1) == '-') && (p+2 < end)) { | |
| 205 | + else if ((*(p+1) == '-') && (p+2 < endclass)) { | |
| 217 | 206 | p+=2; |
| 218 | 207 | if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p) |
| 219 | 208 | return sig; |
| 220 | 209 | } |
| 221 | − else if ((unsigned char)*p == c) return sig; | |
| 210 | + else if ((int)(unsigned char)*p == c) return sig; | |
| 222 | 211 | } |
| 223 | 212 | return !sig; |
| 224 | 213 | } |
| 225 | 214 | |
| 226 | 215 | |
| 227 | 216 | |
| 228 | −int luaI_singlematch (int c, char *p, char *ep) { | |
| 217 | +int luaI_singlematch (int c, const char *p, const char *ep) { | |
| 229 | 218 | switch (*p) { |
| 230 | 219 | case '.': /* matches any char */ |
| 231 | 220 | return 1; |
| 232 | 221 | case ESC: |
| 233 | − return matchclass(c, (unsigned char)*(p+1)); | |
| 222 | + return match_class(c, (unsigned char)*(p+1)); | |
| 234 | 223 | case '[': |
| 235 | 224 | return matchbracketclass(c, p, ep-1); |
| 236 | 225 | default: |
| @@ -239,12 +228,14 @@ int luaI_singlematch (int c, char *p, char *ep) { · 2 unmodified lines | ||
| 239 | 228 | } |
| 240 | 229 | |
| 241 | 230 | |
| 242 | −static char *match (char *s, char *p, struct Capture *cap); | |
| 231 | +static const char *match (lua_State *L, const char *s, const char *p, | |
| 232 | + struct Capture *cap); | |
| 243 | 233 | |
| 244 | 234 | |
| 245 | −static char *matchbalance (char *s, char *p, struct Capture *cap) { | |
| 235 | +static const char *matchbalance (lua_State *L, const char *s, const char *p, | |
| 236 | + struct Capture *cap) { | |
| 246 | 237 | if (*p == 0 || *(p+1) == 0) |
| 247 | − lua_error("unbalanced pattern"); | |
| 238 | + lua_error(L, "unbalanced pattern"); | |
| 248 | 239 | if (*s != *p) return NULL; |
| 249 | 240 | else { |
| 250 | 241 | int b = *p; |
| @@ -261,13 +252,14 @@ static char *matchbalance (char *s, char *p, struct Capture *cap) { · 10 unmodified lines | ||
| 261 | 252 | } |
| 262 | 253 | |
| 263 | 254 | |
| 264 | −static char *max_expand (char *s, char *p, char *ep, struct Capture *cap) { | |
| 265 | − int i = 0; /* counts maximum expand for item */ | |
| 255 | +static const char *max_expand (lua_State *L, const char *s, const char *p, | |
| 256 | + const char *ep, struct Capture *cap) { | |
| 257 | + long i = 0; /* counts maximum expand for item */ | |
| 266 | 258 | while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep)) |
| 267 | 259 | i++; |
| 268 | − /* keeps trying to match mith the maximum repetitions */ | |
| 260 | + /* keeps trying to match with the maximum repetitions */ | |
| 269 | 261 | while (i>=0) { |
| 270 | − char *res = match((s+i), ep+1, cap); | |
| 262 | + const char *res = match(L, (s+i), ep+1, cap); | |
| 271 | 263 | if (res) return res; |
| 272 | 264 | i--; /* else didn't match; reduce 1 repetition to try again */ |
| 273 | 265 | } |
| @@ -275,9 +267,10 @@ static char *max_expand (char *s, char *p, char *ep, struct Capture *cap) { · 1 unmodified line | ||
| 275 | 267 | } |
| 276 | 268 | |
| 277 | 269 | |
| 278 | −static char *min_expand (char *s, char *p, char *ep, struct Capture *cap) { | |
| 270 | +static const char *min_expand (lua_State *L, const char *s, const char *p, | |
| 271 | + const char *ep, struct Capture *cap) { | |
| 279 | 272 | for (;;) { |
| 280 | − char *res = match(s, ep+1, cap); | |
| 273 | + const char *res = match(L, s, ep+1, cap); | |
| 281 | 274 | if (res != NULL) |
| 282 | 275 | return res; |
| 283 | 276 | else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep)) |
| @@ -287,56 +280,60 @@ static char *min_expand (char *s, char *p, char *ep, struct Capture *cap) { · 3 unmodified lines | ||
| 287 | 280 | } |
| 288 | 281 | |
| 289 | 282 | |
| 290 | −static char *start_capt (char *s, char *p, struct Capture *cap) { | |
| 291 | − char *res; | |
| 283 | +static const char *start_capture (lua_State *L, const char *s, const char *p, | |
| 284 | + struct Capture *cap) { | |
| 285 | + const char *res; | |
| 292 | 286 | int level = cap->level; |
| 293 | − if (level >= MAX_CAPT) lua_error("too many captures"); | |
| 287 | + if (level >= MAX_CAPTURES) lua_error(L, "too many captures"); | |
| 294 | 288 | cap->capture[level].init = s; |
| 295 | 289 | cap->capture[level].len = -1; |
| 296 | 290 | cap->level = level+1; |
| 297 | − if ((res=match(s, p+1, cap)) == NULL) /* match failed? */ | |
| 291 | + if ((res=match(L, s, p+1, cap)) == NULL) /* match failed? */ | |
| 298 | 292 | cap->level--; /* undo capture */ |
| 299 | 293 | return res; |
| 300 | 294 | } |
| 301 | 295 | |
| 302 | 296 | |
| 303 | −static char *end_capt (char *s, char *p, struct Capture *cap) { | |
| 304 | − int l = capture_to_close(cap); | |
| 305 | − char *res; | |
| 297 | +static const char *end_capture (lua_State *L, const char *s, const char *p, | |
| 298 | + struct Capture *cap) { | |
| 299 | + int l = capture_to_close(L, cap); | |
| 300 | + const char *res; | |
| 306 | 301 | cap->capture[l].len = s - cap->capture[l].init; /* close capture */ |
| 307 | − if ((res = match(s, p+1, cap)) == NULL) /* match failed? */ | |
| 302 | + if ((res = match(L, s, p+1, cap)) == NULL) /* match failed? */ | |
| 308 | 303 | cap->capture[l].len = -1; /* undo capture */ |
| 309 | 304 | return res; |
| 310 | 305 | } |
| 311 | 306 | |
| 312 | 307 | |
| 313 | −static char *match_capture (char *s, int level, struct Capture *cap) { | |
| 314 | − int l = check_cap(level, cap); | |
| 315 | − int len = cap->capture[l].len; | |
| 316 | − if (cap->src_end-s >= len && | |
| 308 | +static const char *match_capture (lua_State *L, const char *s, int level, | |
| 309 | + struct Capture *cap) { | |
| 310 | + int l = check_capture(L, level, cap); | |
| 311 | + size_t len = cap->capture[l].len; | |
| 312 | + if ((size_t)(cap->src_end-s) >= len && | |
| 317 | 313 | memcmp(cap->capture[l].init, s, len) == 0) |
| 318 | 314 | return s+len; |
| 319 | 315 | else return NULL; |
| 320 | 316 | } |
| 321 | 317 | |
| 322 | 318 | |
| 323 | −static char *match (char *s, char *p, struct Capture *cap) { | |
| 319 | +static const char *match (lua_State *L, const char *s, const char *p, | |
| 320 | + struct Capture *cap) { | |
| 324 | 321 | init: /* using goto's to optimize tail recursion */ |
| 325 | 322 | switch (*p) { |
| 326 | 323 | case '(': /* start capture */ |
| 327 | − return start_capt(s, p, cap); | |
| 324 | + return start_capture(L, s, p, cap); | |
| 328 | 325 | case ')': /* end capture */ |
| 329 | − return end_capt(s, p, cap); | |
| 326 | + return end_capture(L, s, p, cap); | |
| 330 | 327 | case ESC: /* may be %[0-9] or %b */ |
| 331 | 328 | if (isdigit((unsigned char)(*(p+1)))) { /* capture? */ |
| 332 | − s = match_capture(s, *(p+1), cap); | |
| 329 | + s = match_capture(L, s, *(p+1), cap); | |
| 333 | 330 | if (s == NULL) return NULL; |
| 334 | − p+=2; goto init; /* else return match(p+2, s, cap) */ | |
| 331 | + p+=2; goto init; /* else return match(L, s, p+2, cap) */ | |
| 335 | 332 | } |
| 336 | 333 | else if (*(p+1) == 'b') { /* balanced string? */ |
| 337 | − s = matchbalance(s, p+2, cap); | |
| 334 | + s = matchbalance(L, s, p+2, cap); | |
| 338 | 335 | if (s == NULL) return NULL; |
| 339 | − p+=4; goto init; /* else return match(p+4, s, cap); */ | |
| 336 | + p+=4; goto init; /* else return match(L, s, p+4, cap); */ | |
| 340 | 337 | } |
| 341 | 338 | else goto dflt; /* case default */ |
| 342 | 339 | case '\0': /* end of pattern */ |
| @@ -346,178 +343,208 @@ static char *match (char *s, char *p, struct Capture *cap) { · 3 unmodified lines | ||
| 346 | 343 | return (s == cap->src_end) ? s : NULL; /* check end of string */ |
| 347 | 344 | else goto dflt; |
| 348 | 345 | default: dflt: { /* it is a pattern item */ |
| 349 | − char *ep = luaI_classend(p); /* points to what is next */ | |
| 346 | + const char *ep = luaI_classend(L, p); /* points to what is next */ | |
| 350 | 347 | int m = s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep); |
| 351 | 348 | switch (*ep) { |
| 352 | 349 | case '?': { /* optional */ |
| 353 | − char *res; | |
| 354 | − if (m && ((res=match(s+1, ep+1, cap)) != NULL)) | |
| 350 | + const char *res; | |
| 351 | + if (m && ((res=match(L, s+1, ep+1, cap)) != NULL)) | |
| 355 | 352 | return res; |
| 356 | − p=ep+1; goto init; /* else return match(s, ep+1, cap); */ | |
| 353 | + p=ep+1; goto init; /* else return match(L, s, ep+1, cap); */ | |
| 357 | 354 | } |
| 358 | 355 | case '*': /* 0 or more repetitions */ |
| 359 | − return max_expand(s, p, ep, cap); | |
| 356 | + return max_expand(L, s, p, ep, cap); | |
| 360 | 357 | case '+': /* 1 or more repetitions */ |
| 361 | − return (m ? max_expand(s+1, p, ep, cap) : NULL); | |
| 358 | + return (m ? max_expand(L, s+1, p, ep, cap) : NULL); | |
| 362 | 359 | case '-': /* 0 or more repetitions (minimum) */ |
| 363 | − return min_expand(s, p, ep, cap); | |
| 360 | + return min_expand(L, s, p, ep, cap); | |
| 364 | 361 | default: |
| 365 | 362 | if (!m) return NULL; |
| 366 | − s++; p=ep; goto init; /* else return match(s+1, ep, cap); */ | |
| 363 | + s++; p=ep; goto init; /* else return match(L, s+1, ep, cap); */ | |
| 364 | + } | |
| 365 | + } | |
| 366 | + } | |
| 367 | +} | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | +static const char *lmemfind (const char *s1, size_t l1, | |
| 372 | + const char *s2, size_t l2) { | |
| 373 | + if (l2 == 0) return s1; /* empty strings are everywhere */ | |
| 374 | + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ | |
| 375 | + else { | |
| 376 | + const char *init; /* to search for a `*s2' inside `s1' */ | |
| 377 | + l2--; /* 1st char will be checked by `memchr' */ | |
| 378 | + l1 = l1-l2; /* `s2' cannot be found after that */ | |
| 379 | + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { | |
| 380 | + init++; /* 1st char is already checked */ | |
| 381 | + if (memcmp(init, s2+1, l2) == 0) | |
| 382 | + return init-1; | |
| 383 | + else { /* correct `l1' and `s1' to try again */ | |
| 384 | + l1 -= init-s1; | |
| 385 | + s1 = init; | |
| 367 | 386 | } |
| 368 | 387 | } |
| 388 | + return NULL; /* not found */ | |
| 369 | 389 | } |
| 370 | 390 | } |
| 371 | 391 | |
| 372 | 392 | |
| 373 | −static void str_find (void) { | |
| 374 | − long l; | |
| 375 | − char *s = luaL_check_lstr(1, &l); | |
| 376 | − char *p = luaL_check_string(2); | |
| 377 | − long init = posrelat(luaL_opt_long(3, 1), l) - 1; | |
| 393 | +static int push_captures (lua_State *L, struct Capture *cap) { | |
| 394 | + int i; | |
| 395 | + luaL_checkstack(L, cap->level, "too many captures"); | |
| 396 | + for (i=0; i<cap->level; i++) { | |
| 397 | + int l = cap->capture[i].len; | |
| 398 | + if (l == -1) lua_error(L, "unfinished capture"); | |
| 399 | + lua_pushlstring(L, cap->capture[i].init, l); | |
| 400 | + } | |
| 401 | + return cap->level; /* number of strings pushed */ | |
| 402 | +} | |
| 403 | + | |
| 404 | + | |
| 405 | +static int str_find (lua_State *L) { | |
| 406 | + size_t l1, l2; | |
| 407 | + const char *s = luaL_check_lstr(L, 1, &l1); | |
| 408 | + const char *p = luaL_check_lstr(L, 2, &l2); | |
| 409 | + long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1; | |
| 378 | 410 | struct Capture cap; |
| 379 | − luaL_arg_check(0 <= init && init <= l, 3, "out of range"); | |
| 380 | − if (lua_getparam(4) != LUA_NOOBJECT || | |
| 381 | − strpbrk(p, SPECIALS) == NULL) { /* no special characters? */ | |
| 382 | − char *s2 = strstr(s+init, p); | |
| 411 | + luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range"); | |
| 412 | + if (lua_gettop(L) > 3 || /* extra argument? */ | |
| 413 | + strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ | |
| 414 | + const char *s2 = lmemfind(s+init, l1-init, p, l2); | |
| 383 | 415 | if (s2) { |
| 384 | − lua_pushnumber(s2-s+1); | |
| 385 | − lua_pushnumber(s2-s+strlen(p)); | |
| 386 | − return; | |
| 416 | + lua_pushnumber(L, s2-s+1); | |
| 417 | + lua_pushnumber(L, s2-s+l2); | |
| 418 | + return 2; | |
| 387 | 419 | } |
| 388 | 420 | } |
| 389 | 421 | else { |
| 390 | 422 | int anchor = (*p == '^') ? (p++, 1) : 0; |
| 391 | − char *s1=s+init; | |
| 392 | − cap.src_end = s+l; | |
| 423 | + const char *s1=s+init; | |
| 424 | + cap.src_end = s+l1; | |
| 393 | 425 | do { |
| 394 | − char *res; | |
| 426 | + const char *res; | |
| 395 | 427 | cap.level = 0; |
| 396 | − if ((res=match(s1, p, &cap)) != NULL) { | |
| 397 | − lua_pushnumber(s1-s+1); /* start */ | |
| 398 | − lua_pushnumber(res-s); /* end */ | |
| 399 | − push_captures(&cap); | |
| 400 | − return; | |
| 428 | + if ((res=match(L, s1, p, &cap)) != NULL) { | |
| 429 | + lua_pushnumber(L, s1-s+1); /* start */ | |
| 430 | + lua_pushnumber(L, res-s); /* end */ | |
| 431 | + return push_captures(L, &cap) + 2; | |
| 401 | 432 | } |
| 402 | 433 | } while (s1++<cap.src_end && !anchor); |
| 403 | 434 | } |
| 404 | − lua_pushnil(); /* if arrives here, it didn't find */ | |
| 435 | + lua_pushnil(L); /* not found */ | |
| 436 | + return 1; | |
| 405 | 437 | } |
| 406 | 438 | |
| 407 | 439 | |
| 408 | −static void add_s (lua_Object newp, struct Capture *cap) { | |
| 409 | − if (lua_isstring(newp)) { | |
| 410 | − char *news = lua_getstring(newp); | |
| 411 | − int l = lua_strlen(newp); | |
| 412 | − int i; | |
| 440 | +static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) { | |
| 441 | + if (lua_isstring(L, 3)) { | |
| 442 | + const char *news = lua_tostring(L, 3); | |
| 443 | + size_t l = lua_strlen(L, 3); | |
| 444 | + size_t i; | |
| 413 | 445 | for (i=0; i<l; i++) { |
| 414 | 446 | if (news[i] != ESC) |
| 415 | − luaL_addchar(news[i]); | |
| 447 | + luaL_putchar(b, news[i]); | |
| 416 | 448 | else { |
| 417 | 449 | i++; /* skip ESC */ |
| 418 | 450 | if (!isdigit((unsigned char)news[i])) |
| 419 | − luaL_addchar(news[i]); | |
| 451 | + luaL_putchar(b, news[i]); | |
| 420 | 452 | else { |
| 421 | − int level = check_cap(news[i], cap); | |
| 422 | − addnchar(cap->capture[level].init, cap->capture[level].len); | |
| 453 | + int level = check_capture(L, news[i], cap); | |
| 454 | + luaL_addlstring(b, cap->capture[level].init, cap->capture[level].len); | |
| 423 | 455 | } |
| 424 | 456 | } |
| 425 | 457 | } |
| 426 | 458 | } |
| 427 | 459 | else { /* is a function */ |
| 428 | − lua_Object res; | |
| 429 | − int status; | |
| 430 | − int oldbuff; | |
| 431 | − lua_beginblock(); | |
| 432 | − push_captures(cap); | |
| 433 | − /* function may use buffer, so save it and create a new one */ | |
| 434 | − oldbuff = luaL_newbuffer(0); | |
| 435 | − status = lua_callfunction(newp); | |
| 436 | − /* restore old buffer */ | |
| 437 | − luaL_oldbuffer(oldbuff); | |
| 438 | − if (status != 0) { | |
| 439 | − lua_endblock(); | |
| 440 | − lua_error(NULL); | |
| 441 | − } | |
| 442 | − res = lua_getresult(1); | |
| 443 | − if (lua_isstring(res)) | |
| 444 | − addnchar(lua_getstring(res), lua_strlen(res)); | |
| 445 | − lua_endblock(); | |
| 460 | + int n; | |
| 461 | + lua_pushvalue(L, 3); | |
| 462 | + n = push_captures(L, cap); | |
| 463 | + lua_rawcall(L, n, 1); | |
| 464 | + if (lua_isstring(L, -1)) | |
| 465 | + luaL_addvalue(b); /* add return to accumulated result */ | |
| 466 | + else | |
| 467 | + lua_pop(L, 1); /* function result is not a string: pop it */ | |
| 446 | 468 | } |
| 447 | 469 | } |
| 448 | 470 | |
| 449 | 471 | |
| 450 | −static void str_gsub (void) { | |
| 451 | − long srcl; | |
| 452 | − char *src = luaL_check_lstr(1, &srcl); | |
| 453 | − char *p = luaL_check_string(2); | |
| 454 | − lua_Object newp = lua_getparam(3); | |
| 455 | − int max_s = luaL_opt_int(4, srcl+1); | |
| 472 | +static int str_gsub (lua_State *L) { | |
| 473 | + size_t srcl; | |
| 474 | + const char *src = luaL_check_lstr(L, 1, &srcl); | |
| 475 | + const char *p = luaL_check_string(L, 2); | |
| 476 | + int max_s = luaL_opt_int(L, 4, srcl+1); | |
| 456 | 477 | int anchor = (*p == '^') ? (p++, 1) : 0; |
| 457 | 478 | int n = 0; |
| 458 | 479 | struct Capture cap; |
| 459 | − luaL_arg_check(lua_isstring(newp) || lua_isfunction(newp), 3, | |
| 460 | − "string or function expected"); | |
| 461 | − luaL_resetbuffer(); | |
| 480 | + luaL_Buffer b; | |
| 481 | + luaL_arg_check(L, | |
| 482 | + lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), | |
| 483 | + 3, "string or function expected"); | |
| 484 | + luaL_buffinit(L, &b); | |
| 462 | 485 | cap.src_end = src+srcl; |
| 463 | 486 | while (n < max_s) { |
| 464 | − char *e; | |
| 487 | + const char *e; | |
| 465 | 488 | cap.level = 0; |
| 466 | − e = match(src, p, &cap); | |
| 489 | + e = match(L, src, p, &cap); | |
| 467 | 490 | if (e) { |
| 468 | 491 | n++; |
| 469 | − add_s(newp, &cap); | |
| 492 | + add_s(L, &b, &cap); | |
| 470 | 493 | } |
| 471 | 494 | if (e && e>src) /* non empty match? */ |
| 472 | 495 | src = e; /* skip it */ |
| 473 | 496 | else if (src < cap.src_end) |
| 474 | − luaL_addchar(*src++); | |
| 497 | + luaL_putchar(&b, *src++); | |
| 475 | 498 | else break; |
| 476 | 499 | if (anchor) break; |
| 477 | 500 | } |
| 478 | − addnchar(src, cap.src_end-src); | |
| 479 | − closeandpush(); | |
| 480 | − lua_pushnumber(n); /* number of substitutions */ | |
| 501 | + luaL_addlstring(&b, src, cap.src_end-src); | |
| 502 | + luaL_pushresult(&b); | |
| 503 | + lua_pushnumber(L, n); /* number of substitutions */ | |
| 504 | + return 2; | |
| 481 | 505 | } |
| 482 | 506 | |
| 483 | 507 | /* }====================================================== */ |
| 484 | 508 | |
| 485 | 509 | |
| 486 | −static void luaI_addquoted (int arg) { | |
| 487 | − long l; | |
| 488 | − char *s = luaL_check_lstr(arg, &l); | |
| 489 | − luaL_addchar('"'); | |
| 510 | +static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { | |
| 511 | + size_t l; | |
| 512 | + const char *s = luaL_check_lstr(L, arg, &l); | |
| 513 | + luaL_putchar(b, '"'); | |
| 490 | 514 | while (l--) { |
| 491 | 515 | switch (*s) { |
| 492 | 516 | case '"': case '\\': case '\n': |
| 493 | − luaL_addchar('\\'); | |
| 494 | − luaL_addchar(*s); | |
| 517 | + luaL_putchar(b, '\\'); | |
| 518 | + luaL_putchar(b, *s); | |
| 495 | 519 | break; |
| 496 | − case '\0': addnchar("\\000", 4); break; | |
| 497 | − default: luaL_addchar(*s); | |
| 520 | + case '\0': luaL_addlstring(b, "\\000", 4); break; | |
| 521 | + default: luaL_putchar(b, *s); | |
| 498 | 522 | } |
| 499 | 523 | s++; |
| 500 | 524 | } |
| 501 | − luaL_addchar('"'); | |
| 525 | + luaL_putchar(b, '"'); | |
| 502 | 526 | } |
| 503 | 527 | |
| 528 | +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ | |
| 529 | +#define MAX_ITEM 512 | |
| 504 | 530 | /* maximum size of each format specification (such as '%-099.99d') */ |
| 505 | −#define MAX_FORMAT 20 /* arbitrary limit */ | |
| 531 | +#define MAX_FORMAT 20 | |
| 506 | 532 | |
| 507 | −static void str_format (void) { | |
| 533 | +static int str_format (lua_State *L) { | |
| 508 | 534 | int arg = 1; |
| 509 | − char *strfrmt = luaL_check_string(arg); | |
| 510 | − luaL_resetbuffer(); | |
| 535 | + const char *strfrmt = luaL_check_string(L, arg); | |
| 536 | + luaL_Buffer b; | |
| 537 | + luaL_buffinit(L, &b); | |
| 511 | 538 | while (*strfrmt) { |
| 512 | 539 | if (*strfrmt != '%') |
| 513 | − luaL_addchar(*strfrmt++); | |
| 540 | + luaL_putchar(&b, *strfrmt++); | |
| 514 | 541 | else if (*++strfrmt == '%') |
| 515 | − luaL_addchar(*strfrmt++); /* %% */ | |
| 542 | + luaL_putchar(&b, *strfrmt++); /* %% */ | |
| 516 | 543 | else { /* format item */ |
| 517 | 544 | struct Capture cap; |
| 518 | 545 | char form[MAX_FORMAT]; /* to store the format ('%...') */ |
| 519 | − char *buff; /* to store the formatted item */ | |
| 520 | − char *initf = strfrmt; | |
| 546 | + char buff[MAX_ITEM]; /* to store the formatted item */ | |
| 547 | + const char *initf = strfrmt; | |
| 521 | 548 | form[0] = '%'; |
| 522 | 549 | if (isdigit((unsigned char)*initf) && *(initf+1) == '$') { |
| 523 | 550 | arg = *initf - '0'; |
| @@ -526,33 +553,33 @@ static void str_format (void) { · 2 unmodified lines | ||
| 526 | 553 | arg++; |
| 527 | 554 | cap.src_end = strfrmt+strlen(strfrmt)+1; |
| 528 | 555 | cap.level = 0; |
| 529 | − strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); | |
| 556 | + strfrmt = match(L, initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); | |
| 530 | 557 | if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */ |
| 531 | 558 | strfrmt-initf > MAX_FORMAT-2) |
| 532 | − lua_error("invalid format (width or precision too long)"); | |
| 559 | + lua_error(L, "invalid format (width or precision too long)"); | |
| 533 | 560 | strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ |
| 534 | 561 | form[strfrmt-initf+2] = 0; |
| 535 | − buff = luaL_openspace(512); /* 512 > size of format('%99.99f', -1e308) */ | |
| 536 | 562 | switch (*strfrmt++) { |
| 537 | 563 | case 'c': case 'd': case 'i': |
| 538 | − sprintf(buff, form, luaL_check_int(arg)); | |
| 564 | + sprintf(buff, form, luaL_check_int(L, arg)); | |
| 539 | 565 | break; |
| 540 | 566 | case 'o': case 'u': case 'x': case 'X': |
| 541 | − sprintf(buff, form, (unsigned int)luaL_check_number(arg)); | |
| 567 | + sprintf(buff, form, (unsigned int)luaL_check_number(L, arg)); | |
| 542 | 568 | break; |
| 543 | 569 | case 'e': case 'E': case 'f': case 'g': case 'G': |
| 544 | − sprintf(buff, form, luaL_check_number(arg)); | |
| 570 | + sprintf(buff, form, luaL_check_number(L, arg)); | |
| 545 | 571 | break; |
| 546 | 572 | case 'q': |
| 547 | − luaI_addquoted(arg); | |
| 573 | + luaI_addquoted(L, &b, arg); | |
| 548 | 574 | continue; /* skip the "addsize" at the end */ |
| 549 | 575 | case 's': { |
| 550 | − long l; | |
| 551 | − char *s = luaL_check_lstr(arg, &l); | |
| 576 | + size_t l; | |
| 577 | + const char *s = luaL_check_lstr(L, arg, &l); | |
| 552 | 578 | if (cap.capture[1].len == 0 && l >= 100) { |
| 553 | − /* no precision and string is too big to be formatted; | |
| 579 | + /* no precision and string is too long to be formatted; | |
| 554 | 580 | keep original string */ |
| 555 | − addnchar(s, l); | |
| 581 | + lua_pushvalue(L, arg); | |
| 582 | + luaL_addvalue(&b); | |
| 556 | 583 | continue; /* skip the "addsize" at the end */ |
| 557 | 584 | } |
| 558 | 585 | else { |
| @@ -561,16 +588,17 @@ static void str_format (void) { · 2 unmodified lines | ||
| 561 | 588 | } |
| 562 | 589 | } |
| 563 | 590 | default: /* also treat cases 'pnLlh' */ |
| 564 | − lua_error("invalid option in `format'"); | |
| 591 | + lua_error(L, "invalid option in `format'"); | |
| 565 | 592 | } |
| 566 | − luaL_addsize(strlen(buff)); | |
| 593 | + luaL_addlstring(&b, buff, strlen(buff)); | |
| 567 | 594 | } |
| 568 | 595 | } |
| 569 | − closeandpush(); /* push the result */ | |
| 596 | + luaL_pushresult(&b); | |
| 597 | + return 1; | |
| 570 | 598 | } |
| 571 | 599 | |
| 572 | 600 | |
| 573 | −static struct luaL_reg strlib[] = { | |
| 601 | +static const struct luaL_reg strlib[] = { | |
| 574 | 602 | {"strlen", str_len}, |
| 575 | 603 | {"strsub", str_sub}, |
| 576 | 604 | {"strlower", str_lower}, |
| @@ -588,7 +616,6 @@ static struct luaL_reg strlib[] = { · 11 unmodified lines | ||
| 588 | 616 | /* |
| 589 | 617 | ** Open string library |
| 590 | 618 | */ |
| 591 | −void strlib_open (void) | |
| 592 | −{ | |
| 593 | − luaL_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0]))); | |
| 619 | +LUALIB_API void lua_strlibopen (lua_State *L) { | |
| 620 | + luaL_openl(L, strlib); | |
| 594 | 621 | } |
| @@ -1,71 +1,85 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: llex.c,v 1.36 1999/06/17 17:04:03 roberto Exp $ | |
| 2 | +** $Id: llex.c,v 1.72 2000/10/20 16:39:03 roberto Exp $ | |
| 3 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | 8 | #include <ctype.h> |
| 9 | +#include <stdio.h> | |
| 9 | 10 | #include <string.h> |
| 10 | 11 | |
| 11 | −#include "lauxlib.h" | |
| 12 | +#include "lua.h" | |
| 13 | + | |
| 12 | 14 | #include "llex.h" |
| 13 | 15 | #include "lmem.h" |
| 14 | 16 | #include "lobject.h" |
| 15 | 17 | #include "lparser.h" |
| 16 | 18 | #include "lstate.h" |
| 17 | 19 | #include "lstring.h" |
| 20 | +#include "ltable.h" | |
| 18 | 21 | #include "luadebug.h" |
| 19 | 22 | #include "lzio.h" |
| 20 | 23 | |
| 21 | 24 | |
| 22 | 25 | |
| 23 | −#define next(LS) (LS->current = zgetc(LS->lex_z)) | |
| 24 | − | |
| 26 | +#define next(LS) (LS->current = zgetc(LS->z)) | |
| 25 | 27 | |
| 26 | −#define save(c) luaL_addchar(c) | |
| 27 | −#define save_and_next(LS) (save(LS->current), next(LS)) | |
| 28 | 28 | |
| 29 | 29 | |
| 30 | −char *reserved [] = {"and", "do", "else", "elseif", "end", "function", | |
| 31 | − "if", "local", "nil", "not", "or", "repeat", "return", "then", | |
| 32 | − "until", "while"}; | |
| 30 | +/* ORDER RESERVED */ | |
| 31 | +static const char *const token2string [] = { | |
| 32 | + "and", "break", "do", "else", "elseif", "end", "for", | |
| 33 | + "function", "if", "local", "nil", "not", "or", "repeat", "return", "then", | |
| 34 | + "until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", "<eof>"}; | |
| 33 | 35 | |
| 34 | 36 | |
| 35 | −void luaX_init (void) { | |
| 37 | +void luaX_init (lua_State *L) { | |
| 36 | 38 | int i; |
| 37 | − for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { | |
| 38 | − TaggedString *ts = luaS_new(reserved[i]); | |
| 39 | − ts->head.marked = FIRST_RESERVED+i; /* reserved word (always > 255) */ | |
| 39 | + for (i=0; i<NUM_RESERVED; i++) { | |
| 40 | + TString *ts = luaS_new(L, token2string[i]); | |
| 41 | + ts->marked = (unsigned char)(RESERVEDMARK+i); /* reserved word */ | |
| 40 | 42 | } |
| 41 | 43 | } |
| 42 | 44 | |
| 43 | 45 | |
| 44 | 46 | #define MAXSRC 80 |
| 45 | 47 | |
| 46 | −void luaX_syntaxerror (LexState *ls, char *s, char *token) { | |
| 48 | + | |
| 49 | +void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) { | |
| 50 | + if (val > limit) { | |
| 51 | + char buff[100]; | |
| 52 | + sprintf(buff, "too many %.50s (limit=%d)", msg, limit); | |
| 53 | + luaX_error(ls, buff, ls->t.token); | |
| 54 | + } | |
| 55 | +} | |
| 56 | + | |
| 57 | + | |
| 58 | +void luaX_syntaxerror (LexState *ls, const char *s, const char *token) { | |
| 47 | 59 | char buff[MAXSRC]; |
| 48 | − luaL_chunkid(buff, zname(ls->lex_z), sizeof(buff)); | |
| 49 | − if (token[0] == '\0') | |
| 50 | − token = "<eof>"; | |
| 51 | − luaL_verror("%.100s;\n last token read: `%.50s' at line %d in %.80s", | |
| 60 | + luaO_chunkid(buff, ls->source->str, sizeof(buff)); | |
| 61 | + luaO_verror(ls->L, "%.99s;\n last token read: `%.30s' at line %d in %.80s", | |
| 52 | 62 | s, token, ls->linenumber, buff); |
| 53 | 63 | } |
| 54 | 64 | |
| 55 | 65 | |
| 56 | −void luaX_error (LexState *ls, char *s) { | |
| 57 | − save('\0'); | |
| 58 | − luaX_syntaxerror(ls, s, luaL_buffer()); | |
| 66 | +void luaX_error (LexState *ls, const char *s, int token) { | |
| 67 | + char buff[TOKEN_LEN]; | |
| 68 | + luaX_token2str(token, buff); | |
| 69 | + if (buff[0] == '\0') | |
| 70 | + luaX_syntaxerror(ls, s, ls->L->Mbuffer); | |
| 71 | + else | |
| 72 | + luaX_syntaxerror(ls, s, buff); | |
| 59 | 73 | } |
| 60 | 74 | |
| 61 | 75 | |
| 62 | 76 | void luaX_token2str (int token, char *s) { |
| 63 | − if (token < 255) { | |
| 77 | + if (token < 256) { | |
| 64 | 78 | s[0] = (char)token; |
| 65 | 79 | s[1] = '\0'; |
| 66 | 80 | } |
| 67 | 81 | else |
| 68 | − strcpy(s, reserved[token-FIRST_RESERVED]); | |
| 82 | + strcpy(s, token2string[token-FIRST_RESERVED]); | |
| 69 | 83 | } |
| 70 | 84 | |
| 71 | 85 | |
| @@ -76,200 +90,199 @@ static void luaX_invalidchar (LexState *ls, int c) { · 4 unmodified lines | ||
| 76 | 90 | } |
| 77 | 91 | |
| 78 | 92 | |
| 79 | −static void firstline (LexState *LS) | |
| 80 | −{ | |
| 81 | − int c = zgetc(LS->lex_z); | |
| 82 | − if (c == '#') | |
| 83 | − while ((c=zgetc(LS->lex_z)) != '\n' && c != EOZ) /* skip first line */; | |
| 84 | − zungetc(LS->lex_z); | |
| 93 | +static void inclinenumber (LexState *LS) { | |
| 94 | + next(LS); /* skip '\n' */ | |
| 95 | + ++LS->linenumber; | |
| 96 | + luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk"); | |
| 85 | 97 | } |
| 86 | 98 | |
| 87 | 99 | |
| 88 | −void luaX_setinput (LexState *LS, ZIO *z) | |
| 89 | −{ | |
| 90 | − LS->current = '\n'; | |
| 91 | − LS->linenumber = 0; | |
| 92 | − LS->iflevel = 0; | |
| 93 | − LS->ifstate[0].skip = 0; | |
| 94 | − LS->ifstate[0].elsepart = 1; /* to avoid a free $else */ | |
| 95 | − LS->lex_z = z; | |
| 100 | +void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) { | |
| 101 | + LS->L = L; | |
| 102 | + LS->lookahead.token = TK_EOS; /* no look-ahead token */ | |
| 103 | + LS->z = z; | |
| 96 | 104 | LS->fs = NULL; |
| 97 | − firstline(LS); | |
| 98 | − luaL_resetbuffer(); | |
| 105 | + LS->linenumber = 1; | |
| 106 | + LS->lastline = 1; | |
| 107 | + LS->source = source; | |
| 108 | + next(LS); /* read first char */ | |
| 109 | + if (LS->current == '#') { | |
| 110 | + do { /* skip first line */ | |
| 111 | + next(LS); | |
| 112 | + } while (LS->current != '\n' && LS->current != EOZ); | |
| 113 | + } | |
| 99 | 114 | } |
| 100 | 115 | |
| 101 | 116 | |
| 102 | 117 | |
| 103 | 118 | /* |
| 104 | 119 | ** ======================================================= |
| 105 | −** PRAGMAS | |
| 120 | +** LEXICAL ANALYZER | |
| 106 | 121 | ** ======================================================= |
| 107 | 122 | */ |
| 108 | 123 | |
| 109 | −#ifndef PRAGMASIZE | |
| 110 | −#define PRAGMASIZE 80 /* arbitrary limit */ | |
| 111 | −#endif | |
| 112 | 124 | |
| 113 | −static void skipspace (LexState *LS) { | |
| 114 | − while (LS->current == ' ' || LS->current == '\t' || LS->current == '\r') | |
| 115 | − next(LS); | |
| 116 | −} | |
| 125 | +/* use Mbuffer to store names, literal strings and numbers */ | |
| 117 | 126 | |
| 127 | +#define EXTRABUFF 128 | |
| 128 | +#define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) \ | |
| 129 | + luaO_openspace(L, (len)+(n)+EXTRABUFF) | |
| 118 | 130 | |
| 119 | −static int checkcond (LexState *LS, char *buff) { | |
| 120 | − static char *opts[] = {"nil", "1", NULL}; | |
| 121 | − int i = luaL_findstring(buff, opts); | |
| 122 | − if (i >= 0) return i; | |
| 123 | − else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') | |
| 124 | − return luaS_globaldefined(buff); | |
| 125 | − else { | |
| 126 | − luaX_syntaxerror(LS, "invalid $if condition", buff); | |
| 127 | − return 0; /* to avoid warnings */ | |
| 128 | − } | |
| 129 | −} | |
| 131 | +#define save(L, c, l) (L->Mbuffer[l++] = (char)c) | |
| 132 | +#define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS)) | |
| 130 | 133 | |
| 131 | 134 | |
| 132 | −static void readname (LexState *LS, char *buff) { | |
| 133 | − int i = 0; | |
| 134 | − skipspace(LS); | |
| 135 | − while (isalnum(LS->current) || LS->current == '_') { | |
| 136 | − if (i >= PRAGMASIZE) { | |
| 137 | − buff[PRAGMASIZE] = 0; | |
| 138 | − luaX_syntaxerror(LS, "pragma too long", buff); | |
| 139 | − } | |
| 140 | − buff[i++] = (char)LS->current; | |
| 141 | − next(LS); | |
| 142 | − } | |
| 143 | − buff[i] = 0; | |
| 135 | +static const char *readname (LexState *LS) { | |
| 136 | + lua_State *L = LS->L; | |
| 137 | + size_t l = 0; | |
| 138 | + checkbuffer(L, 10, l); | |
| 139 | + do { | |
| 140 | + checkbuffer(L, 10, l); | |
| 141 | + save_and_next(L, LS, l); | |
| 142 | + } while (isalnum(LS->current) || LS->current == '_'); | |
| 143 | + save(L, '\0', l); | |
| 144 | + return L->Mbuffer; | |
| 144 | 145 | } |
| 145 | 146 | |
| 146 | 147 | |
| 147 | −static void inclinenumber (LexState *LS); | |
| 148 | − | |
| 149 | − | |
| 150 | −static void ifskip (LexState *LS) { | |
| 151 | − while (LS->ifstate[LS->iflevel].skip) { | |
| 152 | − if (LS->current == '\n') | |
| 153 | − inclinenumber(LS); | |
| 154 | − else if (LS->current == EOZ) | |
| 155 | − luaX_error(LS, "input ends inside a $if"); | |
| 156 | − else next(LS); | |
| 148 | +/* LUA_NUMBER */ | |
| 149 | +static void read_number (LexState *LS, int comma, SemInfo *seminfo) { | |
| 150 | + lua_State *L = LS->L; | |
| 151 | + size_t l = 0; | |
| 152 | + checkbuffer(L, 10, l); | |
| 153 | + if (comma) save(L, '.', l); | |
| 154 | + while (isdigit(LS->current)) { | |
| 155 | + checkbuffer(L, 10, l); | |
| 156 | + save_and_next(L, LS, l); | |
| 157 | 157 | } |
| 158 | −} | |
| 159 | − | |
| 160 | − | |
| 161 | −static void inclinenumber (LexState *LS) { | |
| 162 | − static char *pragmas [] = | |
| 163 | − {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL}; | |
| 164 | − next(LS); /* skip '\n' */ | |
| 165 | − ++LS->linenumber; | |
| 166 | − if (LS->current == '$') { /* is a pragma? */ | |
| 167 | − char buff[PRAGMASIZE+1]; | |
| 168 | − int ifnot = 0; | |
| 169 | − int skip = LS->ifstate[LS->iflevel].skip; | |
| 170 | − next(LS); /* skip $ */ | |
| 171 | − readname(LS, buff); | |
| 172 | − switch (luaL_findstring(buff, pragmas)) { | |
| 173 | − case 0: /* debug */ | |
| 174 | − if (!skip) L->debug = 1; | |
| 175 | − break; | |
| 176 | − case 1: /* nodebug */ | |
| 177 | − if (!skip) L->debug = 0; | |
| 178 | − break; | |
| 179 | − case 2: /* endinput */ | |
| 180 | − if (!skip) { | |
| 181 | − LS->current = EOZ; | |
| 182 | − LS->iflevel = 0; /* to allow $endinput inside a $if */ | |
| 183 | − } | |
| 184 | − break; | |
| 185 | − case 3: /* end */ | |
| 186 | − if (LS->iflevel-- == 0) | |
| 187 | − luaX_syntaxerror(LS, "unmatched $end", "$end"); | |
| 188 | − break; | |
| 189 | − case 4: /* ifnot */ | |
| 190 | − ifnot = 1; | |
| 191 | − /* go through */ | |
| 192 | − case 5: /* if */ | |
| 193 | − if (LS->iflevel == MAX_IFS-1) | |
| 194 | − luaX_syntaxerror(LS, "too many nested $ifs", "$if"); | |
| 195 | − readname(LS, buff); | |
| 196 | − LS->iflevel++; | |
| 197 | − LS->ifstate[LS->iflevel].elsepart = 0; | |
| 198 | − LS->ifstate[LS->iflevel].condition = checkcond(LS, buff) ? !ifnot : ifnot; | |
| 199 | − LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition; | |
| 200 | − break; | |
| 201 | − case 6: /* else */ | |
| 202 | − if (LS->ifstate[LS->iflevel].elsepart) | |
| 203 | − luaX_syntaxerror(LS, "unmatched $else", "$else"); | |
| 204 | − LS->ifstate[LS->iflevel].elsepart = 1; | |
| 205 | − LS->ifstate[LS->iflevel].skip = LS->ifstate[LS->iflevel-1].skip || | |
| 206 | − LS->ifstate[LS->iflevel].condition; | |
| 207 | − break; | |
| 208 | − default: | |
| 209 | − luaX_syntaxerror(LS, "unknown pragma", buff); | |
| 158 | + if (LS->current == '.') { | |
| 159 | + save_and_next(L, LS, l); | |
| 160 | + if (LS->current == '.') { | |
| 161 | + save_and_next(L, LS, l); | |
| 162 | + save(L, '\0', l); | |
| 163 | + luaX_error(LS, "ambiguous syntax" | |
| 164 | + " (decimal point x string concatenation)", TK_NUMBER); | |
| 210 | 165 | } |
| 211 | − skipspace(LS); | |
| 212 | − if (LS->current == '\n') /* pragma must end with a '\n' ... */ | |
| 213 | − inclinenumber(LS); | |
| 214 | − else if (LS->current != EOZ) /* or eof */ | |
| 215 | − luaX_syntaxerror(LS, "invalid pragma format", buff); | |
| 216 | − ifskip(LS); | |
| 217 | 166 | } |
| 167 | + while (isdigit(LS->current)) { | |
| 168 | + checkbuffer(L, 10, l); | |
| 169 | + save_and_next(L, LS, l); | |
| 170 | + } | |
| 171 | + if (LS->current == 'e' || LS->current == 'E') { | |
| 172 | + save_and_next(L, LS, l); /* read 'E' */ | |
| 173 | + if (LS->current == '+' || LS->current == '-') | |
| 174 | + save_and_next(L, LS, l); /* optional exponent sign */ | |
| 175 | + while (isdigit(LS->current)) { | |
| 176 | + checkbuffer(L, 10, l); | |
| 177 | + save_and_next(L, LS, l); | |
| 178 | + } | |
| 179 | + } | |
| 180 | + save(L, '\0', l); | |
| 181 | + if (!luaO_str2d(L->Mbuffer, &seminfo->r)) | |
| 182 | + luaX_error(LS, "malformed number", TK_NUMBER); | |
| 218 | 183 | } |
| 219 | 184 | |
| 220 | 185 | |
| 221 | − | |
| 222 | −/* | |
| 223 | −** ======================================================= | |
| 224 | −** LEXICAL ANALIZER | |
| 225 | −** ======================================================= | |
| 226 | −*/ | |
| 227 | − | |
| 228 | − | |
| 229 | − | |
| 230 | −static int read_long_string (LexState *LS) { | |
| 186 | +static void read_long_string (LexState *LS, SemInfo *seminfo) { | |
| 187 | + lua_State *L = LS->L; | |
| 231 | 188 | int cont = 0; |
| 189 | + size_t l = 0; | |
| 190 | + checkbuffer(L, 10, l); | |
| 191 | + save(L, '[', l); /* save first '[' */ | |
| 192 | + save_and_next(L, LS, l); /* pass the second '[' */ | |
| 232 | 193 | for (;;) { |
| 194 | + checkbuffer(L, 10, l); | |
| 233 | 195 | switch (LS->current) { |
| 234 | 196 | case EOZ: |
| 235 | − luaX_error(LS, "unfinished long string"); | |
| 236 | − return EOS; /* to avoid warnings */ | |
| 197 | + save(L, '\0', l); | |
| 198 | + luaX_error(LS, "unfinished long string", TK_STRING); | |
| 199 | + break; /* to avoid warnings */ | |
| 237 | 200 | case '[': |
| 238 | − save_and_next(LS); | |
| 201 | + save_and_next(L, LS, l); | |
| 239 | 202 | if (LS->current == '[') { |
| 240 | 203 | cont++; |
| 241 | − save_and_next(LS); | |
| 204 | + save_and_next(L, LS, l); | |
| 242 | 205 | } |
| 243 | 206 | continue; |
| 244 | 207 | case ']': |
| 245 | − save_and_next(LS); | |
| 208 | + save_and_next(L, LS, l); | |
| 246 | 209 | if (LS->current == ']') { |
| 247 | 210 | if (cont == 0) goto endloop; |
| 248 | 211 | cont--; |
| 249 | − save_and_next(LS); | |
| 212 | + save_and_next(L, LS, l); | |
| 250 | 213 | } |
| 251 | 214 | continue; |
| 252 | 215 | case '\n': |
| 253 | − save('\n'); | |
| 216 | + save(L, '\n', l); | |
| 254 | 217 | inclinenumber(LS); |
| 255 | 218 | continue; |
| 256 | 219 | default: |
| 257 | − save_and_next(LS); | |
| 220 | + save_and_next(L, LS, l); | |
| 258 | 221 | } |
| 259 | 222 | } endloop: |
| 260 | − save_and_next(LS); /* skip the second ']' */ | |
| 261 | − LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+2), | |
| 262 | − L->Mbuffnext-L->Mbuffbase-4); | |
| 263 | − return STRING; | |
| 223 | + save_and_next(L, LS, l); /* skip the second ']' */ | |
| 224 | + save(L, '\0', l); | |
| 225 | + seminfo->ts = luaS_newlstr(L, L->Mbuffer+2, l-5); | |
| 264 | 226 | } |
| 265 | 227 | |
| 266 | 228 | |
| 267 | −int luaX_lex (LexState *LS) { | |
| 268 | − luaL_resetbuffer(); | |
| 229 | +static void read_string (LexState *LS, int del, SemInfo *seminfo) { | |
| 230 | + lua_State *L = LS->L; | |
| 231 | + size_t l = 0; | |
| 232 | + checkbuffer(L, 10, l); | |
| 233 | + save_and_next(L, LS, l); | |
| 234 | + while (LS->current != del) { | |
| 235 | + checkbuffer(L, 10, l); | |
| 236 | + switch (LS->current) { | |
| 237 | + case EOZ: case '\n': | |
| 238 | + save(L, '\0', l); | |
| 239 | + luaX_error(LS, "unfinished string", TK_STRING); | |
| 240 | + break; /* to avoid warnings */ | |
| 241 | + case '\\': | |
| 242 | + next(LS); /* do not save the '\' */ | |
| 243 | + switch (LS->current) { | |
| 244 | + case 'a': save(L, '\a', l); next(LS); break; | |
| 245 | + case 'b': save(L, '\b', l); next(LS); break; | |
| 246 | + case 'f': save(L, '\f', l); next(LS); break; | |
| 247 | + case 'n': save(L, '\n', l); next(LS); break; | |
| 248 | + case 'r': save(L, '\r', l); next(LS); break; | |
| 249 | + case 't': save(L, '\t', l); next(LS); break; | |
| 250 | + case 'v': save(L, '\v', l); next(LS); break; | |
| 251 | + case '\n': save(L, '\n', l); inclinenumber(LS); break; | |
| 252 | + case '0': case '1': case '2': case '3': case '4': | |
| 253 | + case '5': case '6': case '7': case '8': case '9': { | |
| 254 | + int c = 0; | |
| 255 | + int i = 0; | |
| 256 | + do { | |
| 257 | + c = 10*c + (LS->current-'0'); | |
| 258 | + next(LS); | |
| 259 | + } while (++i<3 && isdigit(LS->current)); | |
| 260 | + if (c != (unsigned char)c) { | |
| 261 | + save(L, '\0', l); | |
| 262 | + luaX_error(LS, "escape sequence too large", TK_STRING); | |
| 263 | + } | |
| 264 | + save(L, c, l); | |
| 265 | + break; | |
| 266 | + } | |
| 267 | + default: /* handles \\, \", \', and \? */ | |
| 268 | + save_and_next(L, LS, l); | |
| 269 | + } | |
| 270 | + break; | |
| 271 | + default: | |
| 272 | + save_and_next(L, LS, l); | |
| 273 | + } | |
| 274 | + } | |
| 275 | + save_and_next(L, LS, l); /* skip delimiter */ | |
| 276 | + save(L, '\0', l); | |
| 277 | + seminfo->ts = luaS_newlstr(L, L->Mbuffer+1, l-3); | |
| 278 | +} | |
| 279 | + | |
| 280 | + | |
| 281 | +int luaX_lex (LexState *LS, SemInfo *seminfo) { | |
| 269 | 282 | for (;;) { |
| 270 | 283 | switch (LS->current) { |
| 271 | 284 | |
| 272 | − case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */ | |
| 285 | + case ' ': case '\t': case '\r': /* `\r' to avoid problems with DOS */ | |
| 273 | 286 | next(LS); |
| 274 | 287 | continue; |
| 275 | 288 | |
| @@ -277,159 +290,89 @@ int luaX_lex (LexState *LS) { · 1 unmodified line | ||
| 277 | 290 | inclinenumber(LS); |
| 278 | 291 | continue; |
| 279 | 292 | |
| 293 | + case '$': | |
| 294 | + luaX_error(LS, "unexpected `$' (pragmas are no longer supported)", '$'); | |
| 295 | + break; | |
| 296 | + | |
| 280 | 297 | case '-': |
| 281 | − save_and_next(LS); | |
| 298 | + next(LS); | |
| 282 | 299 | if (LS->current != '-') return '-'; |
| 283 | 300 | do { next(LS); } while (LS->current != '\n' && LS->current != EOZ); |
| 284 | − luaL_resetbuffer(); | |
| 285 | 301 | continue; |
| 286 | 302 | |
| 287 | 303 | case '[': |
| 288 | − save_and_next(LS); | |
| 304 | + next(LS); | |
| 289 | 305 | if (LS->current != '[') return '['; |
| 290 | 306 | else { |
| 291 | − save_and_next(LS); /* pass the second '[' */ | |
| 292 | − return read_long_string(LS); | |
| 307 | + read_long_string(LS, seminfo); | |
| 308 | + return TK_STRING; | |
| 293 | 309 | } |
| 294 | 310 | |
| 295 | 311 | case '=': |
| 296 | − save_and_next(LS); | |
| 312 | + next(LS); | |
| 297 | 313 | if (LS->current != '=') return '='; |
| 298 | − else { save_and_next(LS); return EQ; } | |
| 314 | + else { next(LS); return TK_EQ; } | |
| 299 | 315 | |
| 300 | 316 | case '<': |
| 301 | − save_and_next(LS); | |
| 317 | + next(LS); | |
| 302 | 318 | if (LS->current != '=') return '<'; |
| 303 | − else { save_and_next(LS); return LE; } | |
| 319 | + else { next(LS); return TK_LE; } | |
| 304 | 320 | |
| 305 | 321 | case '>': |
| 306 | − save_and_next(LS); | |
| 322 | + next(LS); | |
| 307 | 323 | if (LS->current != '=') return '>'; |
| 308 | − else { save_and_next(LS); return GE; } | |
| 324 | + else { next(LS); return TK_GE; } | |
| 309 | 325 | |
| 310 | 326 | case '~': |
| 311 | − save_and_next(LS); | |
| 327 | + next(LS); | |
| 312 | 328 | if (LS->current != '=') return '~'; |
| 313 | − else { save_and_next(LS); return NE; } | |
| 329 | + else { next(LS); return TK_NE; } | |
| 314 | 330 | |
| 315 | 331 | case '"': |
| 316 | − case '\'': { | |
| 317 | − int del = LS->current; | |
| 318 | − save_and_next(LS); | |
| 319 | − while (LS->current != del) { | |
| 320 | − switch (LS->current) { | |
| 321 | − case EOZ: | |
| 322 | − case '\n': | |
| 323 | − luaX_error(LS, "unfinished string"); | |
| 324 | − return EOS; /* to avoid warnings */ | |
| 325 | − case '\\': | |
| 326 | − next(LS); /* do not save the '\' */ | |
| 327 | − switch (LS->current) { | |
| 328 | − case 'a': save('\a'); next(LS); break; | |
| 329 | − case 'b': save('\b'); next(LS); break; | |
| 330 | − case 'f': save('\f'); next(LS); break; | |
| 331 | − case 'n': save('\n'); next(LS); break; | |
| 332 | − case 'r': save('\r'); next(LS); break; | |
| 333 | − case 't': save('\t'); next(LS); break; | |
| 334 | − case 'v': save('\v'); next(LS); break; | |
| 335 | − case '\n': save('\n'); inclinenumber(LS); break; | |
| 336 | − default : { | |
| 337 | − if (isdigit(LS->current)) { | |
| 338 | − int c = 0; | |
| 339 | − int i = 0; | |
| 340 | − do { | |
| 341 | − c = 10*c + (LS->current-'0'); | |
| 342 | − next(LS); | |
| 343 | − } while (++i<3 && isdigit(LS->current)); | |
| 344 | − if (c != (unsigned char)c) | |
| 345 | − luaX_error(LS, "escape sequence too large"); | |
| 346 | − save(c); | |
| 347 | − } | |
| 348 | − else { /* handles \, ", ', and ? */ | |
| 349 | − save(LS->current); | |
| 350 | − next(LS); | |
| 351 | − } | |
| 352 | − break; | |
| 353 | − } | |
| 354 | − } | |
| 355 | − break; | |
| 356 | − default: | |
| 357 | − save_and_next(LS); | |
| 358 | − } | |
| 359 | − } | |
| 360 | − save_and_next(LS); /* skip delimiter */ | |
| 361 | − LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+1), | |
| 362 | − L->Mbuffnext-L->Mbuffbase-2); | |
| 363 | − return STRING; | |
| 364 | − } | |
| 332 | + case '\'': | |
| 333 | + read_string(LS, LS->current, seminfo); | |
| 334 | + return TK_STRING; | |
| 365 | 335 | |
| 366 | 336 | case '.': |
| 367 | − save_and_next(LS); | |
| 368 | − if (LS->current == '.') | |
| 369 | − { | |
| 370 | − save_and_next(LS); | |
| 371 | − if (LS->current == '.') | |
| 372 | − { | |
| 373 | − save_and_next(LS); | |
| 374 | − return DOTS; /* ... */ | |
| 337 | + next(LS); | |
| 338 | + if (LS->current == '.') { | |
| 339 | + next(LS); | |
| 340 | + if (LS->current == '.') { | |
| 341 | + next(LS); | |
| 342 | + return TK_DOTS; /* ... */ | |
| 375 | 343 | } |
| 376 | − else return CONC; /* .. */ | |
| 344 | + else return TK_CONCAT; /* .. */ | |
| 377 | 345 | } |
| 378 | 346 | else if (!isdigit(LS->current)) return '.'; |
| 379 | − goto fraction; /* LS->current is a digit: goes through to number */ | |
| 347 | + else { | |
| 348 | + read_number(LS, 1, seminfo); | |
| 349 | + return TK_NUMBER; | |
| 350 | + } | |
| 380 | 351 | |
| 381 | 352 | case '0': case '1': case '2': case '3': case '4': |
| 382 | 353 | case '5': case '6': case '7': case '8': case '9': |
| 383 | − do { | |
| 384 | − save_and_next(LS); | |
| 385 | − } while (isdigit(LS->current)); | |
| 386 | − if (LS->current == '.') { | |
| 387 | − save_and_next(LS); | |
| 388 | − if (LS->current == '.') { | |
| 389 | − save('.'); | |
| 390 | − luaX_error(LS, | |
| 391 | − "ambiguous syntax (decimal point x string concatenation)"); | |
| 392 | − } | |
| 393 | − } | |
| 394 | − fraction: | |
| 395 | − while (isdigit(LS->current)) | |
| 396 | − save_and_next(LS); | |
| 397 | − if (toupper(LS->current) == 'E') { | |
| 398 | − save_and_next(LS); /* read 'E' */ | |
| 399 | − save_and_next(LS); /* read '+', '-' or first digit */ | |
| 400 | − while (isdigit(LS->current)) | |
| 401 | − save_and_next(LS); | |
| 402 | − } | |
| 403 | − save('\0'); | |
| 404 | − LS->seminfo.r = luaO_str2d(L->Mbuffer+L->Mbuffbase); | |
| 405 | − if (LS->seminfo.r < 0) | |
| 406 | − luaX_error(LS, "invalid numeric format"); | |
| 407 | − return NUMBER; | |
| 354 | + read_number(LS, 0, seminfo); | |
| 355 | + return TK_NUMBER; | |
| 408 | 356 | |
| 409 | 357 | case EOZ: |
| 410 | − if (LS->iflevel > 0) | |
| 411 | − luaX_error(LS, "input ends inside a $if"); | |
| 412 | − return EOS; | |
| 358 | + return TK_EOS; | |
| 359 | + | |
| 360 | + case '_': goto tname; | |
| 413 | 361 | |
| 414 | 362 | default: |
| 415 | − if (LS->current != '_' && !isalpha(LS->current)) { | |
| 363 | + if (!isalpha(LS->current)) { | |
| 416 | 364 | int c = LS->current; |
| 417 | 365 | if (iscntrl(c)) |
| 418 | 366 | luaX_invalidchar(LS, c); |
| 419 | − save_and_next(LS); | |
| 367 | + next(LS); | |
| 420 | 368 | return c; |
| 421 | 369 | } |
| 422 | − else { /* identifier or reserved word */ | |
| 423 | − TaggedString *ts; | |
| 424 | − do { | |
| 425 | − save_and_next(LS); | |
| 426 | − } while (isalnum(LS->current) || LS->current == '_'); | |
| 427 | − save('\0'); | |
| 428 | − ts = luaS_new(L->Mbuffer+L->Mbuffbase); | |
| 429 | − if (ts->head.marked >= FIRST_RESERVED) | |
| 430 | − return ts->head.marked; /* reserved word */ | |
| 431 | − LS->seminfo.ts = ts; | |
| 432 | − return NAME; | |
| 370 | + tname: { /* identifier or reserved word */ | |
| 371 | + TString *ts = luaS_new(LS->L, readname(LS)); | |
| 372 | + if (ts->marked >= RESERVEDMARK) /* reserved word? */ | |
| 373 | + return ts->marked-RESERVEDMARK+FIRST_RESERVED; | |
| 374 | + seminfo->ts = ts; | |
| 375 | + return TK_NAME; | |
| 433 | 376 | } |
| 434 | 377 | } |
| 435 | 378 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: llex.h,v 1.12 1999/06/17 17:04:03 roberto Exp $ | |
| 2 | +** $Id: llex.h,v 1.31 2000/09/27 17:41:58 roberto Exp $ | |
| 3 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -11,53 +11,61 @@ · 5 unmodified lines | ||
| 11 | 11 | #include "lzio.h" |
| 12 | 12 | |
| 13 | 13 | |
| 14 | −#define FIRST_RESERVED 260 | |
| 14 | +#define FIRST_RESERVED 257 | |
| 15 | 15 | |
| 16 | −/* maximum length of a reserved word (+1 for terminal 0) */ | |
| 16 | +/* maximum length of a reserved word (+1 for final 0) */ | |
| 17 | 17 | #define TOKEN_LEN 15 |
| 18 | 18 | |
| 19 | + | |
| 20 | +/* | |
| 21 | +* WARNING: if you change the order of this enumeration, | |
| 22 | +* grep "ORDER RESERVED" | |
| 23 | +*/ | |
| 19 | 24 | enum RESERVED { |
| 20 | 25 | /* terminal symbols denoted by reserved words */ |
| 21 | − AND = FIRST_RESERVED, | |
| 22 | − DO, ELSE, ELSEIF, END, FUNCTION, IF, LOCAL, NIL, NOT, OR, | |
| 23 | − REPEAT, RETURN, THEN, UNTIL, WHILE, | |
| 26 | + TK_AND = FIRST_RESERVED, TK_BREAK, | |
| 27 | + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FOR, TK_FUNCTION, TK_IF, TK_LOCAL, | |
| 28 | + TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_UNTIL, TK_WHILE, | |
| 24 | 29 | /* other terminal symbols */ |
| 25 | − NAME, CONC, DOTS, EQ, GE, LE, NE, NUMBER, STRING, EOS}; | |
| 30 | + TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, | |
| 31 | + TK_STRING, TK_EOS | |
| 32 | +}; | |
| 26 | 33 | |
| 34 | +/* number of reserved words */ | |
| 35 | +#define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED+1)) | |
| 27 | 36 | |
| 28 | −#ifndef MAX_IFS | |
| 29 | −#define MAX_IFS 5 /* arbitrary limit */ | |
| 30 | −#endif | |
| 31 | 37 | |
| 32 | −/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */ | |
| 38 | +typedef union { | |
| 39 | + Number r; | |
| 40 | + TString *ts; | |
| 41 | +} SemInfo; /* semantics information */ | |
| 33 | 42 | |
| 34 | −struct ifState { | |
| 35 | − int elsepart; /* true if it's in the $else part */ | |
| 36 | − int condition; /* true if $if condition is true */ | |
| 37 | − int skip; /* true if part must be skipped */ | |
| 38 | −}; | |
| 43 | + | |
| 44 | +typedef struct Token { | |
| 45 | + int token; | |
| 46 | + SemInfo seminfo; | |
| 47 | +} Token; | |
| 39 | 48 | |
| 40 | 49 | |
| 41 | 50 | typedef struct LexState { |
| 42 | − int current; /* look ahead character */ | |
| 43 | − int token; /* look ahead token */ | |
| 44 | − struct FuncState *fs; /* 'FuncState' is private for the parser */ | |
| 45 | − union { | |
| 46 | − real r; | |
| 47 | − TaggedString *ts; | |
| 48 | − } seminfo; /* semantics information */ | |
| 49 | − struct zio *lex_z; /* input stream */ | |
| 51 | + int current; /* current character */ | |
| 52 | + Token t; /* current token */ | |
| 53 | + Token lookahead; /* look ahead token */ | |
| 54 | + struct FuncState *fs; /* `FuncState' is private to the parser */ | |
| 55 | + struct lua_State *L; | |
| 56 | + struct zio *z; /* input stream */ | |
| 50 | 57 | int linenumber; /* input line counter */ |
| 51 | − int iflevel; /* level of nested $if's (for lexical analysis) */ | |
| 52 | − struct ifState ifstate[MAX_IFS]; | |
| 58 | + int lastline; /* line of last token `consumed' */ | |
| 59 | + TString *source; /* current source name */ | |
| 53 | 60 | } LexState; |
| 54 | 61 | |
| 55 | 62 | |
| 56 | −void luaX_init (void); | |
| 57 | −void luaX_setinput (LexState *LS, ZIO *z); | |
| 58 | −int luaX_lex (LexState *LS); | |
| 59 | −void luaX_syntaxerror (LexState *ls, char *s, char *token); | |
| 60 | −void luaX_error (LexState *ls, char *s); | |
| 63 | +void luaX_init (lua_State *L); | |
| 64 | +void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source); | |
| 65 | +int luaX_lex (LexState *LS, SemInfo *seminfo); | |
| 66 | +void luaX_checklimit (LexState *ls, int val, int limit, const char *msg); | |
| 67 | +void luaX_syntaxerror (LexState *ls, const char *s, const char *token); | |
| 68 | +void luaX_error (LexState *ls, const char *s, int token); | |
| 61 | 69 | void luaX_token2str (int token, char *s); |
| 62 | 70 | |
| 63 | 71 | |
| @@ -0,0 +1,204 @@ | ||
| 1 | +/* | |
| 2 | +** $Id: llimits.h,v 1.19 2000/10/26 12:47:05 roberto Exp $ | |
| 3 | +** Limits, basic types, and some other "installation-dependent" definitions | |
| 4 | +** See Copyright Notice in lua.h | |
| 5 | +*/ | |
| 6 | + | |
| 7 | +#ifndef llimits_h | |
| 8 | +#define llimits_h | |
| 9 | + | |
| 10 | + | |
| 11 | +#include <limits.h> | |
| 12 | +#include <stddef.h> | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | +/* | |
| 17 | +** try to find number of bits in an integer | |
| 18 | +*/ | |
| 19 | +#ifndef BITS_INT | |
| 20 | +/* avoid overflows in comparison */ | |
| 21 | +#if INT_MAX-20 < 32760 | |
| 22 | +#define BITS_INT 16 | |
| 23 | +#else | |
| 24 | +#if INT_MAX > 2147483640L | |
| 25 | +/* machine has at least 32 bits */ | |
| 26 | +#define BITS_INT 32 | |
| 27 | +#else | |
| 28 | +#error "you must define BITS_INT with number of bits in an integer" | |
| 29 | +#endif | |
| 30 | +#endif | |
| 31 | +#endif | |
| 32 | + | |
| 33 | + | |
| 34 | +/* | |
| 35 | +** Define the type `number' of Lua | |
| 36 | +** GREP LUA_NUMBER to change that | |
| 37 | +*/ | |
| 38 | +#ifndef LUA_NUM_TYPE | |
| 39 | +#define LUA_NUM_TYPE double | |
| 40 | +#endif | |
| 41 | + | |
| 42 | +typedef LUA_NUM_TYPE Number; | |
| 43 | + | |
| 44 | +/* function to convert a Number to a string */ | |
| 45 | +#define NUMBER_FMT "%.16g" /* LUA_NUMBER */ | |
| 46 | +#define lua_number2str(s,n) sprintf((s), NUMBER_FMT, (n)) | |
| 47 | + | |
| 48 | +/* function to convert a string to a Number */ | |
| 49 | +#define lua_str2number(s,p) strtod((s), (p)) | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | +typedef unsigned long lint32; /* unsigned int with at least 32 bits */ | |
| 54 | + | |
| 55 | + | |
| 56 | +#define MAX_SIZET ((size_t)(~(size_t)0)-2) | |
| 57 | + | |
| 58 | + | |
| 59 | +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ | |
| 60 | + | |
| 61 | +/* | |
| 62 | +** conversion of pointer to int (for hashing only) | |
| 63 | +** (the shift removes bits that are usually 0 because of alignment) | |
| 64 | +*/ | |
| 65 | +#define IntPoint(p) (((unsigned long)(p)) >> 3) | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | +#define MINPOWER2 4 /* minimum size for "growing" vectors */ | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | +#ifndef DEFAULT_STACK_SIZE | |
| 74 | +#define DEFAULT_STACK_SIZE 1024 | |
| 75 | +#endif | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | +/* type to ensure maximum alignment */ | |
| 80 | +union L_Umaxalign { double d; char *s; long l; }; | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | +/* | |
| 85 | +** type for virtual-machine instructions | |
| 86 | +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) | |
| 87 | +** For a very small machine, you may change that to 2 bytes (and adjust | |
| 88 | +** the following limits accordingly) | |
| 89 | +*/ | |
| 90 | +typedef unsigned long Instruction; | |
| 91 | + | |
| 92 | + | |
| 93 | +/* | |
| 94 | +** size and position of opcode arguments. | |
| 95 | +** For an instruction with 2 bytes, size is 16, and size_b can be 5 | |
| 96 | +** (accordingly, size_u will be 10, and size_a will be 5) | |
| 97 | +*/ | |
| 98 | +#define SIZE_INSTRUCTION 32 | |
| 99 | +#define SIZE_B 9 | |
| 100 | + | |
| 101 | +#define SIZE_OP 6 | |
| 102 | +#define SIZE_U (SIZE_INSTRUCTION-SIZE_OP) | |
| 103 | +#define POS_U SIZE_OP | |
| 104 | +#define POS_B SIZE_OP | |
| 105 | +#define SIZE_A (SIZE_INSTRUCTION-(SIZE_OP+SIZE_B)) | |
| 106 | +#define POS_A (SIZE_OP+SIZE_B) | |
| 107 | + | |
| 108 | + | |
| 109 | +/* | |
| 110 | +** limits for opcode arguments. | |
| 111 | +** we use (signed) int to manipulate most arguments, | |
| 112 | +** so they must fit in BITS_INT-1 bits (-1 for sign) | |
| 113 | +*/ | |
| 114 | +#if SIZE_U < BITS_INT-1 | |
| 115 | +#define MAXARG_U ((1<<SIZE_U)-1) | |
| 116 | +#define MAXARG_S (MAXARG_U>>1) /* `S' is signed */ | |
| 117 | +#else | |
| 118 | +#define MAXARG_U MAX_INT | |
| 119 | +#define MAXARG_S MAX_INT | |
| 120 | +#endif | |
| 121 | + | |
| 122 | +#if SIZE_A < BITS_INT-1 | |
| 123 | +#define MAXARG_A ((1<<SIZE_A)-1) | |
| 124 | +#else | |
| 125 | +#define MAXARG_A MAX_INT | |
| 126 | +#endif | |
| 127 | + | |
| 128 | +#if SIZE_B < BITS_INT-1 | |
| 129 | +#define MAXARG_B ((1<<SIZE_B)-1) | |
| 130 | +#else | |
| 131 | +#define MAXARG_B MAX_INT | |
| 132 | +#endif | |
| 133 | + | |
| 134 | + | |
| 135 | +/* maximum stack size in a function */ | |
| 136 | +#ifndef MAXSTACK | |
| 137 | +#define MAXSTACK 250 | |
| 138 | +#endif | |
| 139 | + | |
| 140 | +#if MAXSTACK > MAXARG_B | |
| 141 | +#undef MAXSTACK | |
| 142 | +#define MAXSTACK MAXARG_B | |
| 143 | +#endif | |
| 144 | + | |
| 145 | + | |
| 146 | +/* maximum number of local variables */ | |
| 147 | +#ifndef MAXLOCALS | |
| 148 | +#define MAXLOCALS 200 /* arbitrary limit (<MAXSTACK) */ | |
| 149 | +#endif | |
| 150 | +#if MAXLOCALS>=MAXSTACK | |
| 151 | +#undef MAXLOCALS | |
| 152 | +#define MAXLOCALS (MAXSTACK-1) | |
| 153 | +#endif | |
| 154 | + | |
| 155 | + | |
| 156 | +/* maximum number of upvalues */ | |
| 157 | +#ifndef MAXUPVALUES | |
| 158 | +#define MAXUPVALUES 32 /* arbitrary limit (<=MAXARG_B) */ | |
| 159 | +#endif | |
| 160 | +#if MAXUPVALUES>MAXARG_B | |
| 161 | +#undef MAXUPVALUES | |
| 162 | +#define MAXUPVALUES MAXARG_B | |
| 163 | +#endif | |
| 164 | + | |
| 165 | + | |
| 166 | +/* maximum number of variables in the left side of an assignment */ | |
| 167 | +#ifndef MAXVARSLH | |
| 168 | +#define MAXVARSLH 100 /* arbitrary limit (<MULT_RET) */ | |
| 169 | +#endif | |
| 170 | +#if MAXVARSLH>=MULT_RET | |
| 171 | +#undef MAXVARSLH | |
| 172 | +#define MAXVARSLH (MULT_RET-1) | |
| 173 | +#endif | |
| 174 | + | |
| 175 | + | |
| 176 | +/* maximum number of parameters in a function */ | |
| 177 | +#ifndef MAXPARAMS | |
| 178 | +#define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */ | |
| 179 | +#endif | |
| 180 | +#if MAXPARAMS>=MAXLOCALS | |
| 181 | +#undef MAXPARAMS | |
| 182 | +#define MAXPARAMS (MAXLOCALS-1) | |
| 183 | +#endif | |
| 184 | + | |
| 185 | + | |
| 186 | +/* number of list items to accumulate before a SETLIST instruction */ | |
| 187 | +#define LFIELDS_PER_FLUSH 64 | |
| 188 | +#if LFIELDS_PER_FLUSH>(MAXSTACK/4) | |
| 189 | +#undef LFIELDS_PER_FLUSH | |
| 190 | +#define LFIELDS_PER_FLUSH (MAXSTACK/4) | |
| 191 | +#endif | |
| 192 | + | |
| 193 | +/* number of record items to accumulate before a SETMAP instruction */ | |
| 194 | +/* (each item counts 2 elements on the stack: an index and a value) */ | |
| 195 | +#define RFIELDS_PER_FLUSH (LFIELDS_PER_FLUSH/2) | |
| 196 | + | |
| 197 | + | |
| 198 | +/* maximum lookback to find a real constant (for code generation) */ | |
| 199 | +#ifndef LOOKBACKNUMS | |
| 200 | +#define LOOKBACKNUMS 20 /* arbitrary constant */ | |
| 201 | +#endif | |
| 202 | + | |
| 203 | + | |
| 204 | +#endif | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lmem.c,v 1.17 1999/05/24 17:51:05 roberto Exp $ | |
| 2 | +** $Id: lmem.c,v 1.39 2000/10/30 16:29:59 roberto Exp $ | |
| 3 | 3 | ** Interface to Memory Manager |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -7,134 +7,144 @@ · 1 unmodified line | ||
| 7 | 7 | |
| 8 | 8 | #include <stdlib.h> |
| 9 | 9 | |
| 10 | −#include "lmem.h" | |
| 11 | −#include "lstate.h" | |
| 12 | 10 | #include "lua.h" |
| 13 | 11 | |
| 12 | +#include "ldo.h" | |
| 13 | +#include "lmem.h" | |
| 14 | +#include "lobject.h" | |
| 15 | +#include "lstate.h" | |
| 14 | 16 | |
| 15 | −/* | |
| 16 | −** real ANSI systems do not need these tests; | |
| 17 | −** but some systems (Sun OS) are not that ANSI... | |
| 18 | −*/ | |
| 19 | −#ifdef OLD_ANSI | |
| 20 | −#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s)) | |
| 21 | −#define free(b) if (b) (free)(b) | |
| 22 | −#endif | |
| 23 | − | |
| 24 | − | |
| 25 | −#define MINSIZE 8 /* minimum size for "growing" vectors */ | |
| 26 | − | |
| 27 | − | |
| 28 | − | |
| 29 | − | |
| 30 | −static unsigned long power2 (unsigned long n) { | |
| 31 | − unsigned long p = MINSIZE; | |
| 32 | − while (p<=n) p<<=1; | |
| 33 | − return p; | |
| 34 | −} | |
| 35 | − | |
| 36 | − | |
| 37 | −void *luaM_growaux (void *block, unsigned long nelems, int inc, int size, | |
| 38 | − char *errormsg, unsigned long limit) { | |
| 39 | − unsigned long newn = nelems+inc; | |
| 40 | − if (newn >= limit) lua_error(errormsg); | |
| 41 | − if ((newn ^ nelems) <= nelems || /* still the same power of 2 limit? */ | |
| 42 | − (nelems > 0 && newn < MINSIZE)) /* or block already is MINSIZE? */ | |
| 43 | − return block; /* do not need to reallocate */ | |
| 44 | − else /* it crossed a power of 2 boundary; grow to next power */ | |
| 45 | − return luaM_realloc(block, power2(newn)*size); | |
| 46 | −} | |
| 47 | 17 | |
| 48 | 18 | |
| 49 | −#ifndef DEBUG | |
| 50 | 19 | |
| 20 | +#ifdef LUA_DEBUG | |
| 51 | 21 | /* |
| 52 | −** generic allocation routine. | |
| 22 | +** {====================================================================== | |
| 23 | +** Controlled version for realloc. | |
| 24 | +** ======================================================================= | |
| 53 | 25 | */ |
| 54 | −void *luaM_realloc (void *block, unsigned long size) { | |
| 55 | − size_t s = (size_t)size; | |
| 56 | − if (s != size) | |
| 57 | − lua_error("memory allocation error: block too big"); | |
| 58 | − if (size == 0) { | |
| 59 | − free(block); /* block may be NULL, that is OK for free */ | |
| 60 | − return NULL; | |
| 61 | − } | |
| 62 | − block = realloc(block, s); | |
| 63 | − if (block == NULL) | |
| 64 | − lua_error(memEM); | |
| 65 | − return block; | |
| 66 | −} | |
| 67 | 26 | |
| 68 | 27 | |
| 28 | +#include <assert.h> | |
| 29 | +#include <limits.h> | |
| 30 | +#include <string.h> | |
| 69 | 31 | |
| 70 | −#else | |
| 71 | −/* DEBUG */ | |
| 32 | +#define realloc(b, s) debug_realloc(b, s) | |
| 33 | +#define malloc(b) debug_realloc(NULL, b) | |
| 34 | +#define free(b) debug_realloc(b, 0) | |
| 72 | 35 | |
| 73 | −#include <string.h> | |
| 74 | 36 | |
| 37 | +/* ensures maximum alignment for HEADER */ | |
| 38 | +#define HEADER (sizeof(union L_Umaxalign)) | |
| 75 | 39 | |
| 76 | −#define HEADER (sizeof(double)) | |
| 77 | 40 | #define MARKSIZE 16 |
| 78 | − | |
| 79 | −#define MARK 55 | |
| 41 | +#define MARK 0x55 /* 01010101 (a nice pattern) */ | |
| 80 | 42 | |
| 81 | 43 | |
| 82 | 44 | #define blocksize(b) ((unsigned long *)((char *)(b) - HEADER)) |
| 83 | 45 | |
| 84 | −unsigned long numblocks = 0; | |
| 85 | −unsigned long totalmem = 0; | |
| 46 | +unsigned long memdebug_numblocks = 0; | |
| 47 | +unsigned long memdebug_total = 0; | |
| 48 | +unsigned long memdebug_maxmem = 0; | |
| 49 | +unsigned long memdebug_memlimit = LONG_MAX; | |
| 86 | 50 | |
| 87 | 51 | |
| 88 | 52 | static void *checkblock (void *block) { |
| 89 | − if (block == NULL) | |
| 90 | − return NULL; | |
| 91 | − else { | |
| 92 | − unsigned long *b = blocksize(block); | |
| 93 | − unsigned long size = *b; | |
| 94 | − int i; | |
| 95 | − for (i=0;i<MARKSIZE;i++) | |
| 96 | − LUA_ASSERT(*(((char *)b)+HEADER+size+i) == MARK+i, "corrupted block"); | |
| 97 | − numblocks--; | |
| 98 | − totalmem -= size; | |
| 99 | − return b; | |
| 100 | − } | |
| 53 | + unsigned long *b = blocksize(block); | |
| 54 | + unsigned long size = *b; | |
| 55 | + int i; | |
| 56 | + for (i=0;i<MARKSIZE;i++) | |
| 57 | + assert(*(((char *)b)+HEADER+size+i) == MARK+i); /* corrupted block? */ | |
| 58 | + memdebug_numblocks--; | |
| 59 | + memdebug_total -= size; | |
| 60 | + return b; | |
| 101 | 61 | } |
| 102 | 62 | |
| 103 | 63 | |
| 104 | 64 | static void freeblock (void *block) { |
| 105 | − if (block) | |
| 106 | − memset(block, -1, *blocksize(block)); /* erase block */ | |
| 107 | − free(checkblock(block)); | |
| 65 | + if (block) { | |
| 66 | + size_t size = *blocksize(block); | |
| 67 | + block = checkblock(block); | |
| 68 | + memset(block, -1, size+HEADER+MARKSIZE); /* erase block */ | |
| 69 | + (free)(block); /* free original block */ | |
| 70 | + } | |
| 108 | 71 | } |
| 109 | 72 | |
| 110 | 73 | |
| 111 | −void *luaM_realloc (void *block, unsigned long size) { | |
| 112 | − unsigned long realsize = HEADER+size+MARKSIZE; | |
| 113 | − if (realsize != (size_t)realsize) | |
| 114 | − lua_error("memory allocation error: block too big"); | |
| 74 | +static void *debug_realloc (void *block, size_t size) { | |
| 115 | 75 | if (size == 0) { |
| 116 | 76 | freeblock(block); |
| 117 | 77 | return NULL; |
| 118 | 78 | } |
| 79 | + else if (memdebug_total+size > memdebug_memlimit) | |
| 80 | + return NULL; /* to test memory allocation errors */ | |
| 119 | 81 | else { |
| 120 | − char *newblock = malloc(realsize); | |
| 82 | + size_t realsize = HEADER+size+MARKSIZE; | |
| 83 | + char *newblock = (char *)(malloc)(realsize); /* alloc a new block */ | |
| 121 | 84 | int i; |
| 85 | + if (realsize < size) return NULL; /* overflow! */ | |
| 86 | + if (newblock == NULL) return NULL; | |
| 122 | 87 | if (block) { |
| 123 | − unsigned long oldsize = *blocksize(block); | |
| 88 | + size_t oldsize = *blocksize(block); | |
| 124 | 89 | if (oldsize > size) oldsize = size; |
| 125 | 90 | memcpy(newblock+HEADER, block, oldsize); |
| 126 | 91 | freeblock(block); /* erase (and check) old copy */ |
| 127 | 92 | } |
| 128 | − if (newblock == NULL) | |
| 129 | − lua_error(memEM); | |
| 130 | − totalmem += size; | |
| 131 | − numblocks++; | |
| 93 | + memdebug_total += size; | |
| 94 | + if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total; | |
| 95 | + memdebug_numblocks++; | |
| 132 | 96 | *(unsigned long *)newblock = size; |
| 133 | 97 | for (i=0;i<MARKSIZE;i++) |
| 134 | − *(newblock+HEADER+size+i) = MARK+i; | |
| 98 | + *(newblock+HEADER+size+i) = (char)(MARK+i); | |
| 135 | 99 | return newblock+HEADER; |
| 136 | 100 | } |
| 137 | 101 | } |
| 138 | 102 | |
| 139 | 103 | |
| 104 | +/* }====================================================================== */ | |
| 105 | +#endif | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | +/* | |
| 110 | +** Real ISO (ANSI) systems do not need these tests; | |
| 111 | +** but some systems (Sun OS) are not that ISO... | |
| 112 | +*/ | |
| 113 | +#ifdef OLD_ANSI | |
| 114 | +#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s)) | |
| 115 | +#define free(b) if (b) (free)(b) | |
| 140 | 116 | #endif |
| 117 | + | |
| 118 | + | |
| 119 | +void *luaM_growaux (lua_State *L, void *block, size_t nelems, | |
| 120 | + int inc, size_t size, const char *errormsg, size_t limit) { | |
| 121 | + size_t newn = nelems+inc; | |
| 122 | + if (nelems >= limit-inc) lua_error(L, errormsg); | |
| 123 | + if ((newn ^ nelems) <= nelems || /* still the same power-of-2 limit? */ | |
| 124 | + (nelems > 0 && newn < MINPOWER2)) /* or block already is MINPOWER2? */ | |
| 125 | + return block; /* do not need to reallocate */ | |
| 126 | + else /* it crossed a power-of-2 boundary; grow to next power */ | |
| 127 | + return luaM_realloc(L, block, luaO_power2(newn)*size); | |
| 128 | +} | |
| 129 | + | |
| 130 | + | |
| 131 | +/* | |
| 132 | +** generic allocation routine. | |
| 133 | +*/ | |
| 134 | +void *luaM_realloc (lua_State *L, void *block, lint32 size) { | |
| 135 | + if (size == 0) { | |
| 136 | + free(block); /* block may be NULL; that is OK for free */ | |
| 137 | + return NULL; | |
| 138 | + } | |
| 139 | + else if (size >= MAX_SIZET) | |
| 140 | + lua_error(L, "memory allocation error: block too big"); | |
| 141 | + block = realloc(block, size); | |
| 142 | + if (block == NULL) { | |
| 143 | + if (L) | |
| 144 | + luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */ | |
| 145 | + else return NULL; /* error before creating state! */ | |
| 146 | + } | |
| 147 | + return block; | |
| 148 | +} | |
| 149 | + | |
| 150 | + | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lmem.h,v 1.8 1999/02/26 15:48:55 roberto Exp $ | |
| 2 | +** $Id: lmem.h,v 1.16 2000/10/30 16:29:59 roberto Exp $ | |
| 3 | 3 | ** Interface to Memory Manager |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,32 +8,33 @@ · 2 unmodified lines | ||
| 8 | 8 | #define lmem_h |
| 9 | 9 | |
| 10 | 10 | |
| 11 | −#include <stdlib.h> | |
| 11 | +#include <stddef.h> | |
| 12 | 12 | |
| 13 | −/* memory error messages */ | |
| 14 | −#define codeEM "code size overflow" | |
| 15 | −#define constantEM "constant table overflow" | |
| 16 | −#define refEM "reference table overflow" | |
| 17 | −#define tableEM "table overflow" | |
| 18 | −#define memEM "not enough memory" | |
| 19 | −#define arrEM "internal array bigger than `int' limit" | |
| 13 | +#include "llimits.h" | |
| 14 | +#include "lua.h" | |
| 20 | 15 | |
| 21 | −void *luaM_realloc (void *oldblock, unsigned long size); | |
| 22 | −void *luaM_growaux (void *block, unsigned long nelems, int inc, int size, | |
| 23 | − char *errormsg, unsigned long limit); | |
| 16 | +void *luaM_realloc (lua_State *L, void *oldblock, lint32 size); | |
| 17 | +void *luaM_growaux (lua_State *L, void *block, size_t nelems, | |
| 18 | + int inc, size_t size, const char *errormsg, | |
| 19 | + size_t limit); | |
| 24 | 20 | |
| 25 | −#define luaM_free(b) luaM_realloc((b), 0) | |
| 26 | −#define luaM_malloc(t) luaM_realloc(NULL, (t)) | |
| 27 | −#define luaM_new(t) ((t *)luaM_malloc(sizeof(t))) | |
| 28 | −#define luaM_newvector(n,t) ((t *)luaM_malloc((n)*sizeof(t))) | |
| 29 | −#define luaM_growvector(v,nelems,inc,t,e,l) \ | |
| 30 | − ((v)=(t *)luaM_growaux(v,nelems,inc,sizeof(t),e,l)) | |
| 31 | −#define luaM_reallocvector(v,n,t) ((v)=(t *)luaM_realloc(v,(n)*sizeof(t))) | |
| 21 | +#define luaM_free(L, b) luaM_realloc(L, (b), 0) | |
| 22 | +#define luaM_malloc(L, t) luaM_realloc(L, NULL, (t)) | |
| 23 | +#define luaM_new(L, t) ((t *)luaM_malloc(L, sizeof(t))) | |
| 24 | +#define luaM_newvector(L, n,t) ((t *)luaM_malloc(L, (n)*(lint32)sizeof(t))) | |
| 32 | 25 | |
| 26 | +#define luaM_growvector(L, v,nelems,inc,t,e,l) \ | |
| 27 | + ((v)=(t *)luaM_growaux(L, v,nelems,inc,sizeof(t),e,l)) | |
| 33 | 28 | |
| 34 | −#ifdef DEBUG | |
| 35 | −extern unsigned long numblocks; | |
| 36 | −extern unsigned long totalmem; | |
| 29 | +#define luaM_reallocvector(L, v,n,t) \ | |
| 30 | + ((v)=(t *)luaM_realloc(L, v,(n)*(lint32)sizeof(t))) | |
| 31 | + | |
| 32 | + | |
| 33 | +#ifdef LUA_DEBUG | |
| 34 | +extern unsigned long memdebug_numblocks; | |
| 35 | +extern unsigned long memdebug_total; | |
| 36 | +extern unsigned long memdebug_maxmem; | |
| 37 | +extern unsigned long memdebug_memlimit; | |
| 37 | 38 | #endif |
| 38 | 39 | |
| 39 | 40 | |
| @@ -1,129 +1,125 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lobject.c,v 1.19 1999/04/13 19:28:49 roberto Exp $ | |
| 2 | +** $Id: lobject.c,v 1.55 2000/10/20 16:36:32 roberto Exp $ | |
| 3 | 3 | ** Some generic functions over Lua objects |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | #include <ctype.h> |
| 8 | +#include <stdarg.h> | |
| 9 | +#include <stdio.h> | |
| 8 | 10 | #include <stdlib.h> |
| 11 | +#include <string.h> | |
| 9 | 12 | |
| 10 | −#include "lobject.h" | |
| 11 | 13 | #include "lua.h" |
| 12 | 14 | |
| 15 | +#include "lmem.h" | |
| 16 | +#include "lobject.h" | |
| 17 | +#include "lstate.h" | |
| 13 | 18 | |
| 14 | −char *luaO_typenames[] = { /* ORDER LUA_T */ | |
| 15 | − "userdata", "number", "string", "table", "function", "function", | |
| 16 | − "nil", "function", "mark", "mark", "mark", "line", NULL | |
| 17 | −}; | |
| 18 | 19 | |
| 19 | 20 | |
| 20 | −TObject luaO_nilobject = {LUA_T_NIL, {NULL}}; | |
| 21 | +const TObject luaO_nilobject = {LUA_TNIL, {NULL}}; | |
| 21 | 22 | |
| 22 | 23 | |
| 24 | +const char *const luaO_typenames[] = { | |
| 25 | + "userdata", "nil", "number", "string", "table", "function" | |
| 26 | +}; | |
| 23 | 27 | |
| 24 | −/* hash dimensions values */ | |
| 25 | −static long dimensions[] = | |
| 26 | − {5L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L, | |
| 27 | − 12853L, 25717L, 51437L, 102811L, 205619L, 411233L, 822433L, | |
| 28 | − 1644817L, 3289613L, 6579211L, 13158023L, MAX_INT}; | |
| 29 | 28 | |
| 30 | 29 | |
| 31 | −int luaO_redimension (int oldsize) | |
| 32 | −{ | |
| 33 | − int i; | |
| 34 | − for (i=0; dimensions[i]<MAX_INT; i++) { | |
| 35 | − if (dimensions[i] > oldsize) | |
| 36 | − return dimensions[i]; | |
| 37 | − } | |
| 38 | − lua_error("tableEM"); | |
| 39 | − return 0; /* to avoid warnings */ | |
| 30 | +/* | |
| 31 | +** returns smaller power of 2 larger than `n' (minimum is MINPOWER2) | |
| 32 | +*/ | |
| 33 | +lint32 luaO_power2 (lint32 n) { | |
| 34 | + lint32 p = MINPOWER2; | |
| 35 | + while (p<=n) p<<=1; | |
| 36 | + return p; | |
| 40 | 37 | } |
| 41 | 38 | |
| 42 | 39 | |
| 43 | −int luaO_equalval (TObject *t1, TObject *t2) { | |
| 40 | +int luaO_equalObj (const TObject *t1, const TObject *t2) { | |
| 41 | + if (ttype(t1) != ttype(t2)) return 0; | |
| 44 | 42 | switch (ttype(t1)) { |
| 45 | − case LUA_T_NIL: return 1; | |
| 46 | − case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); | |
| 47 | − case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2); | |
| 48 | − case LUA_T_ARRAY: return avalue(t1) == avalue(t2); | |
| 49 | − case LUA_T_PROTO: return tfvalue(t1) == tfvalue(t2); | |
| 50 | − case LUA_T_CPROTO: return fvalue(t1) == fvalue(t2); | |
| 51 | − case LUA_T_CLOSURE: return t1->value.cl == t2->value.cl; | |
| 43 | + case LUA_TNUMBER: | |
| 44 | + return nvalue(t1) == nvalue(t2); | |
| 45 | + case LUA_TSTRING: case LUA_TUSERDATA: | |
| 46 | + return tsvalue(t1) == tsvalue(t2); | |
| 47 | + case LUA_TTABLE: | |
| 48 | + return hvalue(t1) == hvalue(t2); | |
| 49 | + case LUA_TFUNCTION: | |
| 50 | + return clvalue(t1) == clvalue(t2); | |
| 52 | 51 | default: |
| 53 | − LUA_INTERNALERROR("invalid type"); | |
| 54 | − return 0; /* UNREACHABLE */ | |
| 52 | + LUA_ASSERT(ttype(t1) == LUA_TNIL, "invalid type"); | |
| 53 | + return 1; /* LUA_TNIL */ | |
| 55 | 54 | } |
| 56 | 55 | } |
| 57 | 56 | |
| 58 | 57 | |
| 59 | −void luaO_insertlist (GCnode *root, GCnode *node) | |
| 60 | −{ | |
| 61 | − node->next = root->next; | |
| 62 | − root->next = node; | |
| 63 | − node->marked = 0; | |
| 58 | +char *luaO_openspace (lua_State *L, size_t n) { | |
| 59 | + if (n > L->Mbuffsize) { | |
| 60 | + luaM_reallocvector(L, L->Mbuffer, n, char); | |
| 61 | + L->nblocks += (n - L->Mbuffsize)*sizeof(char); | |
| 62 | + L->Mbuffsize = n; | |
| 63 | + } | |
| 64 | + return L->Mbuffer; | |
| 64 | 65 | } |
| 65 | 66 | |
| 66 | 67 | |
| 67 | −#ifdef OLD_ANSI | |
| 68 | −void luaO_memup (void *dest, void *src, int size) { | |
| 69 | − while (size--) | |
| 70 | − ((char *)dest)[size]=((char *)src)[size]; | |
| 71 | −} | |
| 72 | − | |
| 73 | −void luaO_memdown (void *dest, void *src, int size) { | |
| 74 | − int i; | |
| 75 | − for (i=0; i<size; i++) | |
| 76 | − ((char *)dest)[i]=((char *)src)[i]; | |
| 68 | +int luaO_str2d (const char *s, Number *result) { /* LUA_NUMBER */ | |
| 69 | + char *endptr; | |
| 70 | + Number res = lua_str2number(s, &endptr); | |
| 71 | + if (endptr == s) return 0; /* no conversion */ | |
| 72 | + while (isspace((unsigned char)*endptr)) endptr++; | |
| 73 | + if (*endptr != '\0') return 0; /* invalid trailing characters? */ | |
| 74 | + *result = res; | |
| 75 | + return 1; | |
| 77 | 76 | } |
| 78 | −#endif | |
| 79 | 77 | |
| 80 | 78 | |
| 79 | +/* maximum length of a string format for `luaO_verror' */ | |
| 80 | +#define MAX_VERROR 280 | |
| 81 | 81 | |
| 82 | −static double expten (unsigned int e) { | |
| 83 | − double exp = 10.0; | |
| 84 | − double res = 1.0; | |
| 85 | − for (; e; e>>=1) { | |
| 86 | − if (e & 1) res *= exp; | |
| 87 | − exp *= exp; | |
| 88 | − } | |
| 89 | − return res; | |
| 82 | +/* this function needs to handle only '%d' and '%.XXs' formats */ | |
| 83 | +void luaO_verror (lua_State *L, const char *fmt, ...) { | |
| 84 | + va_list argp; | |
| 85 | + char buff[MAX_VERROR]; /* to hold formatted message */ | |
| 86 | + va_start(argp, fmt); | |
| 87 | + vsprintf(buff, fmt, argp); | |
| 88 | + va_end(argp); | |
| 89 | + lua_error(L, buff); | |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | |
| 93 | −double luaO_str2d (char *s) { /* LUA_NUMBER */ | |
| 94 | − double a = 0.0; | |
| 95 | − int point = 0; | |
| 96 | − while (isdigit((unsigned char)*s)) { | |
| 97 | − a = 10.0*a + (*(s++)-'0'); | |
| 93 | +void luaO_chunkid (char *out, const char *source, int bufflen) { | |
| 94 | + if (*source == '=') { | |
| 95 | + strncpy(out, source+1, bufflen); /* remove first char */ | |
| 96 | + out[bufflen-1] = '\0'; /* ensures null termination */ | |
| 98 | 97 | } |
| 99 | − if (*s == '.') { | |
| 100 | − s++; | |
| 101 | − while (isdigit((unsigned char)*s)) { | |
| 102 | − a = 10.0*a + (*(s++)-'0'); | |
| 103 | − point++; | |
| 98 | + else { | |
| 99 | + if (*source == '@') { | |
| 100 | + int l; | |
| 101 | + source++; /* skip the `@' */ | |
| 102 | + bufflen -= sizeof("file `...%s'"); | |
| 103 | + l = strlen(source); | |
| 104 | + if (l>bufflen) { | |
| 105 | + source += (l-bufflen); /* get last part of file name */ | |
| 106 | + sprintf(out, "file `...%.99s'", source); | |
| 107 | + } | |
| 108 | + else | |
| 109 | + sprintf(out, "file `%.99s'", source); | |
| 104 | 110 | } |
| 105 | − } | |
| 106 | − if (toupper((unsigned char)*s) == 'E') { | |
| 107 | − int e = 0; | |
| 108 | − int sig = 1; | |
| 109 | − s++; | |
| 110 | − if (*s == '-') { | |
| 111 | − s++; | |
| 112 | − sig = -1; | |
| 111 | + else { | |
| 112 | + int len = strcspn(source, "\n"); /* stop at first newline */ | |
| 113 | + bufflen -= sizeof("string \"%.*s...\""); | |
| 114 | + if (len > bufflen) len = bufflen; | |
| 115 | + if (source[len] != '\0') { /* must truncate? */ | |
| 116 | + strcpy(out, "string \""); | |
| 117 | + out += strlen(out); | |
| 118 | + strncpy(out, source, len); | |
| 119 | + strcpy(out+len, "...\""); | |
| 120 | + } | |
| 121 | + else | |
| 122 | + sprintf(out, "string \"%.99s\"", source); | |
| 113 | 123 | } |
| 114 | − else if (*s == '+') s++; | |
| 115 | − if (!isdigit((unsigned char)*s)) return -1; /* no digit in the exponent? */ | |
| 116 | − do { | |
| 117 | − e = 10*e + (*(s++)-'0'); | |
| 118 | − } while (isdigit((unsigned char)*s)); | |
| 119 | − point -= sig*e; | |
| 120 | 124 | } |
| 121 | − while (isspace((unsigned char)*s)) s++; | |
| 122 | − if (*s != '\0') return -1; /* invalid trailing characters? */ | |
| 123 | − if (point > 0) | |
| 124 | − a /= expten(point); | |
| 125 | − else if (point < 0) | |
| 126 | − a *= expten(-point); | |
| 127 | − return a; | |
| 128 | 125 | } |
| 129 | − | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lobject.h,v 1.28 1999/03/16 16:43:27 roberto Exp $ | |
| 2 | +** $Id: lobject.h,v 1.82 2000/10/30 17:49:19 roberto Exp $ | |
| 3 | 3 | ** Type definitions for Lua objects |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,197 +8,197 @@ · 2 unmodified lines | ||
| 8 | 8 | #define lobject_h |
| 9 | 9 | |
| 10 | 10 | |
| 11 | −#include <limits.h> | |
| 12 | − | |
| 11 | +#include "llimits.h" | |
| 13 | 12 | #include "lua.h" |
| 14 | 13 | |
| 15 | 14 | |
| 16 | −#ifdef DEBUG | |
| 17 | −#include "lauxlib.h" | |
| 18 | −#define LUA_INTERNALERROR(s) \ | |
| 19 | − luaL_verror("INTERNAL ERROR - %s [%s:%d]",(s),__FILE__,__LINE__) | |
| 20 | −#define LUA_ASSERT(c,s) { if (!(c)) LUA_INTERNALERROR(s); } | |
| 15 | +#ifdef LUA_DEBUG | |
| 16 | +#undef NDEBUG | |
| 17 | +#include <assert.h> | |
| 18 | +#define LUA_INTERNALERROR(s) assert(((void)s,0)) | |
| 19 | +#define LUA_ASSERT(c,s) assert(((void)s,(c))) | |
| 21 | 20 | #else |
| 22 | −#define LUA_INTERNALERROR(s) /* empty */ | |
| 23 | −#define LUA_ASSERT(c,s) /* empty */ | |
| 21 | +#define LUA_INTERNALERROR(s) /* empty */ | |
| 22 | +#define LUA_ASSERT(c,s) /* empty */ | |
| 24 | 23 | #endif |
| 25 | 24 | |
| 26 | 25 | |
| 27 | −/* | |
| 28 | −** "real" is the type "number" of Lua | |
| 29 | −** GREP LUA_NUMBER to change that | |
| 30 | −*/ | |
| 31 | −#ifndef LUA_NUM_TYPE | |
| 32 | −#define LUA_NUM_TYPE double | |
| 26 | +#ifdef LUA_DEBUG | |
| 27 | +/* to avoid warnings, and make sure value is really unused */ | |
| 28 | +#define UNUSED(x) (x=0, (void)(x)) | |
| 29 | +#else | |
| 30 | +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ | |
| 33 | 31 | #endif |
| 34 | 32 | |
| 35 | 33 | |
| 36 | −typedef LUA_NUM_TYPE real; | |
| 37 | − | |
| 38 | −#define Byte lua_Byte /* some systems have Byte as a predefined type */ | |
| 39 | −typedef unsigned char Byte; /* unsigned 8 bits */ | |
| 40 | − | |
| 34 | +/* mark for closures active in the stack */ | |
| 35 | +#define LUA_TMARK 6 | |
| 41 | 36 | |
| 42 | −#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ | |
| 43 | 37 | |
| 44 | −typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */ | |
| 38 | +/* tags for values visible from Lua == first user-created tag */ | |
| 39 | +#define NUM_TAGS 6 | |
| 45 | 40 | |
| 46 | 41 | |
| 47 | −/* | |
| 48 | −** Lua TYPES | |
| 49 | −** WARNING: if you change the order of this enumeration, | |
| 50 | −** grep "ORDER LUA_T" | |
| 51 | −*/ | |
| 52 | −typedef enum { | |
| 53 | − LUA_T_USERDATA = 0, /* tag default for userdata */ | |
| 54 | − LUA_T_NUMBER = -1, /* fixed tag for numbers */ | |
| 55 | − LUA_T_STRING = -2, /* fixed tag for strings */ | |
| 56 | − LUA_T_ARRAY = -3, /* tag default for tables (or arrays) */ | |
| 57 | − LUA_T_PROTO = -4, /* fixed tag for functions */ | |
| 58 | − LUA_T_CPROTO = -5, /* fixed tag for Cfunctions */ | |
| 59 | − LUA_T_NIL = -6, /* last "pre-defined" tag */ | |
| 60 | − LUA_T_CLOSURE = -7, | |
| 61 | − LUA_T_CLMARK = -8, /* mark for closures */ | |
| 62 | − LUA_T_PMARK = -9, /* mark for Lua prototypes */ | |
| 63 | − LUA_T_CMARK = -10, /* mark for C prototypes */ | |
| 64 | − LUA_T_LINE = -11 | |
| 65 | −} lua_Type; | |
| 66 | − | |
| 67 | −#define NUM_TAGS 7 | |
| 42 | +/* check whether `t' is a mark */ | |
| 43 | +#define is_T_MARK(t) ((t) == LUA_TMARK) | |
| 68 | 44 | |
| 69 | 45 | |
| 70 | 46 | typedef union { |
| 71 | − lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */ | |
| 72 | − real n; /* LUA_T_NUMBER */ | |
| 73 | − struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */ | |
| 74 | − struct TProtoFunc *tf; /* LUA_T_PROTO, LUA_T_PMARK */ | |
| 75 | − struct Closure *cl; /* LUA_T_CLOSURE, LUA_T_CLMARK */ | |
| 76 | − struct Hash *a; /* LUA_T_ARRAY */ | |
| 77 | − int i; /* LUA_T_LINE */ | |
| 47 | + struct TString *ts; /* LUA_TSTRING, LUA_TUSERDATA */ | |
| 48 | + struct Closure *cl; /* LUA_TFUNCTION */ | |
| 49 | + struct Hash *a; /* LUA_TTABLE */ | |
| 50 | + struct CallInfo *i; /* LUA_TLMARK */ | |
| 51 | + Number n; /* LUA_TNUMBER */ | |
| 78 | 52 | } Value; |
| 79 | 53 | |
| 80 | 54 | |
| 81 | −typedef struct TObject { | |
| 82 | − lua_Type ttype; | |
| 55 | +/* Macros to access values */ | |
| 56 | +#define ttype(o) ((o)->ttype) | |
| 57 | +#define nvalue(o) ((o)->value.n) | |
| 58 | +#define tsvalue(o) ((o)->value.ts) | |
| 59 | +#define clvalue(o) ((o)->value.cl) | |
| 60 | +#define hvalue(o) ((o)->value.a) | |
| 61 | +#define infovalue(o) ((o)->value.i) | |
| 62 | +#define svalue(o) (tsvalue(o)->str) | |
| 63 | + | |
| 64 | + | |
| 65 | +typedef struct lua_TObject { | |
| 66 | + int ttype; | |
| 83 | 67 | Value value; |
| 84 | 68 | } TObject; |
| 85 | 69 | |
| 86 | 70 | |
| 87 | − | |
| 88 | 71 | /* |
| 89 | −** generic header for garbage collector lists | |
| 72 | +** String headers for string table | |
| 90 | 73 | */ |
| 91 | −typedef struct GCnode { | |
| 92 | − struct GCnode *next; | |
| 93 | − int marked; | |
| 94 | −} GCnode; | |
| 95 | − | |
| 96 | 74 | |
| 97 | 75 | /* |
| 98 | −** String headers for string table | |
| 76 | +** most `malloc' libraries allocate memory in blocks of 8 bytes. TSPACK | |
| 77 | +** tries to make sizeof(TString) a multiple of this granularity, to reduce | |
| 78 | +** waste of space. | |
| 99 | 79 | */ |
| 80 | +#define TSPACK ((int)sizeof(int)) | |
| 100 | 81 | |
| 101 | −typedef struct TaggedString { | |
| 102 | − GCnode head; | |
| 103 | − unsigned long hash; | |
| 104 | − int constindex; /* hint to reuse constants (= -1 if this is a userdata) */ | |
| 82 | +typedef struct TString { | |
| 105 | 83 | union { |
| 106 | − struct { | |
| 107 | − TObject globalval; | |
| 108 | − long len; /* if this is a string, here is its length */ | |
| 84 | + struct { /* for strings */ | |
| 85 | + unsigned long hash; | |
| 86 | + int constindex; /* hint to reuse constants */ | |
| 109 | 87 | } s; |
| 110 | − struct { | |
| 88 | + struct { /* for userdata */ | |
| 111 | 89 | int tag; |
| 112 | − void *v; /* if this is a userdata, here is its value */ | |
| 90 | + void *value; | |
| 113 | 91 | } d; |
| 114 | 92 | } u; |
| 115 | − char str[1]; /* \0 byte already reserved */ | |
| 116 | −} TaggedString; | |
| 117 | − | |
| 118 | − | |
| 93 | + size_t len; | |
| 94 | + struct TString *nexthash; /* chain for hash table */ | |
| 95 | + int marked; | |
| 96 | + char str[TSPACK]; /* variable length string!! must be the last field! */ | |
| 97 | +} TString; | |
| 119 | 98 | |
| 120 | 99 | |
| 121 | 100 | /* |
| 122 | 101 | ** Function Prototypes |
| 123 | 102 | */ |
| 124 | −typedef struct TProtoFunc { | |
| 125 | − GCnode head; | |
| 126 | − struct TObject *consts; | |
| 127 | − int nconsts; | |
| 128 | − Byte *code; /* ends with opcode ENDCODE */ | |
| 103 | +typedef struct Proto { | |
| 104 | + Number *knum; /* Number numbers used by the function */ | |
| 105 | + int nknum; /* size of `knum' */ | |
| 106 | + struct TString **kstr; /* strings used by the function */ | |
| 107 | + int nkstr; /* size of `kstr' */ | |
| 108 | + struct Proto **kproto; /* functions defined inside the function */ | |
| 109 | + int nkproto; /* size of `kproto' */ | |
| 110 | + Instruction *code; | |
| 111 | + int ncode; /* size of `code'; when 0 means an incomplete `Proto' */ | |
| 112 | + short numparams; | |
| 113 | + short is_vararg; | |
| 114 | + short maxstacksize; | |
| 115 | + short marked; | |
| 116 | + struct Proto *next; | |
| 117 | + /* debug information */ | |
| 118 | + int *lineinfo; /* map from opcodes to source lines */ | |
| 119 | + int nlineinfo; /* size of `lineinfo' */ | |
| 120 | + int nlocvars; | |
| 121 | + struct LocVar *locvars; /* information about local variables */ | |
| 129 | 122 | int lineDefined; |
| 130 | − TaggedString *source; | |
| 131 | − struct LocVar *locvars; /* ends with line = -1 */ | |
| 132 | −} TProtoFunc; | |
| 123 | + TString *source; | |
| 124 | +} Proto; | |
| 125 | + | |
| 133 | 126 | |
| 134 | 127 | typedef struct LocVar { |
| 135 | − TaggedString *varname; /* NULL signals end of scope */ | |
| 136 | − int line; | |
| 128 | + TString *varname; | |
| 129 | + int startpc; /* first point where variable is active */ | |
| 130 | + int endpc; /* first point where variable is dead */ | |
| 137 | 131 | } LocVar; |
| 138 | 132 | |
| 139 | 133 | |
| 140 | − | |
| 141 | − | |
| 142 | − | |
| 143 | −/* Macros to access structure members */ | |
| 144 | −#define ttype(o) ((o)->ttype) | |
| 145 | −#define nvalue(o) ((o)->value.n) | |
| 146 | −#define svalue(o) ((o)->value.ts->str) | |
| 147 | −#define tsvalue(o) ((o)->value.ts) | |
| 148 | −#define clvalue(o) ((o)->value.cl) | |
| 149 | −#define avalue(o) ((o)->value.a) | |
| 150 | −#define fvalue(o) ((o)->value.f) | |
| 151 | −#define tfvalue(o) ((o)->value.tf) | |
| 152 | − | |
| 153 | −#define protovalue(o) ((o)->value.cl->consts) | |
| 154 | − | |
| 155 | − | |
| 156 | 134 | /* |
| 157 | 135 | ** Closures |
| 158 | 136 | */ |
| 159 | 137 | typedef struct Closure { |
| 160 | − GCnode head; | |
| 161 | − int nelems; /* not included the first one (always the prototype) */ | |
| 162 | − TObject consts[1]; /* at least one for prototype */ | |
| 138 | + union { | |
| 139 | + lua_CFunction c; /* C functions */ | |
| 140 | + struct Proto *l; /* Lua functions */ | |
| 141 | + } f; | |
| 142 | + struct Closure *next; | |
| 143 | + struct Closure *mark; /* marked closures (point to itself when not marked) */ | |
| 144 | + short isC; /* 0 for Lua functions, 1 for C functions */ | |
| 145 | + short nupvalues; | |
| 146 | + TObject upvalue[1]; | |
| 163 | 147 | } Closure; |
| 164 | 148 | |
| 165 | 149 | |
| 150 | +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC) | |
| 151 | + | |
| 166 | 152 | |
| 167 | −typedef struct node { | |
| 168 | − TObject ref; | |
| 153 | +typedef struct Node { | |
| 154 | + TObject key; | |
| 169 | 155 | TObject val; |
| 156 | + struct Node *next; /* for chaining */ | |
| 170 | 157 | } Node; |
| 171 | 158 | |
| 172 | 159 | typedef struct Hash { |
| 173 | − GCnode head; | |
| 174 | 160 | Node *node; |
| 175 | − int nhash; | |
| 176 | − int nuse; | |
| 177 | 161 | int htag; |
| 162 | + int size; | |
| 163 | + Node *firstfree; /* this position is free; all positions after it are full */ | |
| 164 | + struct Hash *next; | |
| 165 | + struct Hash *mark; /* marked tables (point to itself when not marked) */ | |
| 178 | 166 | } Hash; |
| 179 | 167 | |
| 180 | 168 | |
| 181 | −extern char *luaO_typenames[]; | |
| 169 | +/* unmarked tables and closures are represented by pointing `mark' to | |
| 170 | +** themselves | |
| 171 | +*/ | |
| 172 | +#define ismarked(x) ((x)->mark != (x)) | |
| 173 | + | |
| 182 | 174 | |
| 183 | −#define luaO_typename(o) luaO_typenames[-ttype(o)] | |
| 175 | +/* | |
| 176 | +** informations about a call (for debugging) | |
| 177 | +*/ | |
| 178 | +typedef struct CallInfo { | |
| 179 | + struct Closure *func; /* function being called */ | |
| 180 | + const Instruction **pc; /* current pc of called function */ | |
| 181 | + int lastpc; /* last pc traced */ | |
| 182 | + int line; /* current line */ | |
| 183 | + int refi; /* current index in `lineinfo' */ | |
| 184 | +} CallInfo; | |
| 184 | 185 | |
| 185 | 186 | |
| 186 | −extern TObject luaO_nilobject; | |
| 187 | +extern const TObject luaO_nilobject; | |
| 188 | +extern const char *const luaO_typenames[]; | |
| 187 | 189 | |
| 188 | −#define luaO_equalObj(t1,t2) ((ttype(t1) != ttype(t2)) ? 0 \ | |
| 189 | − : luaO_equalval(t1,t2)) | |
| 190 | −int luaO_equalval (TObject *t1, TObject *t2); | |
| 191 | −int luaO_redimension (int oldsize); | |
| 192 | −void luaO_insertlist (GCnode *root, GCnode *node); | |
| 193 | −double luaO_str2d (char *s); | |
| 194 | 190 | |
| 195 | −#ifdef OLD_ANSI | |
| 196 | −void luaO_memup (void *dest, void *src, int size); | |
| 197 | −void luaO_memdown (void *dest, void *src, int size); | |
| 198 | −#else | |
| 199 | −#include <string.h> | |
| 200 | −#define luaO_memup(d,s,n) memmove(d,s,n) | |
| 201 | −#define luaO_memdown(d,s,n) memmove(d,s,n) | |
| 202 | −#endif | |
| 191 | +#define luaO_typename(o) (luaO_typenames[ttype(o)]) | |
| 192 | + | |
| 193 | + | |
| 194 | +lint32 luaO_power2 (lint32 n); | |
| 195 | +char *luaO_openspace (lua_State *L, size_t n); | |
| 196 | + | |
| 197 | +int luaO_equalObj (const TObject *t1, const TObject *t2); | |
| 198 | +int luaO_str2d (const char *s, Number *result); | |
| 199 | + | |
| 200 | +void luaO_verror (lua_State *L, const char *fmt, ...); | |
| 201 | +void luaO_chunkid (char *out, const char *source, int len); | |
| 202 | + | |
| 203 | 203 | |
| 204 | 204 | #endif |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lopcodes.h,v 1.33 1999/06/17 17:04:03 roberto Exp $ | |
| 2 | +** $Id: lopcodes.h,v 1.68 2000/10/24 16:05:59 roberto Exp $ | |
| 3 | 3 | ** Opcodes for Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -7,132 +7,162 @@ · 1 unmodified line | ||
| 7 | 7 | #ifndef lopcodes_h |
| 8 | 8 | #define lopcodes_h |
| 9 | 9 | |
| 10 | +#include "llimits.h" | |
| 10 | 11 | |
| 11 | −/* | |
| 12 | −** NOTICE: variants of the same opcode must be consecutive: First, those | |
| 13 | −** with word parameter, then with byte parameter. | |
| 14 | −*/ | |
| 15 | 12 | |
| 13 | +/*=========================================================================== | |
| 14 | + We assume that instructions are unsigned numbers. | |
| 15 | + All instructions have an opcode in the first 6 bits. Moreover, | |
| 16 | + an instruction can have 0, 1, or 2 arguments. Instructions can | |
| 17 | + have the following types: | |
| 18 | + type 0: no arguments | |
| 19 | + type 1: 1 unsigned argument in the higher bits (called `U') | |
| 20 | + type 2: 1 signed argument in the higher bits (`S') | |
| 21 | + type 3: 1st unsigned argument in the higher bits (`A') | |
| 22 | + 2nd unsigned argument in the middle bits (`B') | |
| 16 | 23 | |
| 17 | −typedef enum { | |
| 18 | −/* name parm before after side effect | |
| 19 | −-----------------------------------------------------------------------------*/ | |
| 20 | −ENDCODE,/* - - (return) */ | |
| 21 | −RETCODE,/* b - (return) */ | |
| 24 | + A signed argument is represented in excess K; that is, the number | |
| 25 | + value is the unsigned value minus K. K is exactly the maximum value | |
| 26 | + for that argument (so that -max is represented by 0, and +max is | |
| 27 | + represented by 2*max), which is half the maximum for the corresponding | |
| 28 | + unsigned argument. | |
| 22 | 29 | |
| 23 | −CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */ | |
| 30 | + The size of each argument is defined in `llimits.h'. The usual is an | |
| 31 | + instruction with 32 bits, U arguments with 26 bits (32-6), B arguments | |
| 32 | + with 9 bits, and A arguments with 17 bits (32-6-9). For small | |
| 33 | + installations, the instruction size can be 16, so U has 10 bits, | |
| 34 | + and A and B have 5 bits each. | |
| 35 | +===========================================================================*/ | |
| 24 | 36 | |
| 25 | −TAILCALL,/* b c v_c...v_1 f (return) f(v1,...,v_c) */ | |
| 26 | 37 | |
| 27 | −PUSHNIL,/* b - nil_0...nil_b */ | |
| 28 | −POP,/* b a_b...a_1 - */ | |
| 29 | 38 | |
| 30 | −PUSHNUMBERW,/* w - (float)w */ | |
| 31 | −PUSHNUMBER,/* b - (float)b */ | |
| 32 | 39 | |
| 33 | −PUSHNUMBERNEGW,/* w - (float)-w */ | |
| 34 | −PUSHNUMBERNEG,/* b - (float)-b */ | |
| 40 | +/* creates a mask with `n' 1 bits at position `p' */ | |
| 41 | +#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p) | |
| 35 | 42 | |
| 36 | −PUSHCONSTANTW,/*w - CNST[w] */ | |
| 37 | −PUSHCONSTANT,/* b - CNST[b] */ | |
| 43 | +/* creates a mask with `n' 0 bits at position `p' */ | |
| 44 | +#define MASK0(n,p) (~MASK1(n,p)) | |
| 38 | 45 | |
| 39 | −PUSHUPVALUE,/* b - Closure[b] */ | |
| 46 | +/* | |
| 47 | +** the following macros help to manipulate instructions | |
| 48 | +*/ | |
| 40 | 49 | |
| 41 | −PUSHLOCAL,/* b - LOC[b] */ | |
| 50 | +#define CREATE_0(o) ((Instruction)(o)) | |
| 51 | +#define GET_OPCODE(i) ((OpCode)((i)&MASK1(SIZE_OP,0))) | |
| 52 | +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o))) | |
| 42 | 53 | |
| 43 | −GETGLOBALW,/* w - VAR[CNST[w]] */ | |
| 44 | −GETGLOBAL,/* b - VAR[CNST[b]] */ | |
| 54 | +#define CREATE_U(o,u) ((Instruction)(o) | ((Instruction)(u)<<POS_U)) | |
| 55 | +#define GETARG_U(i) ((int)((i)>>POS_U)) | |
| 56 | +#define SETARG_U(i,u) ((i) = (((i)&MASK0(SIZE_U,POS_U)) | \ | |
| 57 | + ((Instruction)(u)<<POS_U))) | |
| 45 | 58 | |
| 46 | −GETTABLE,/* - i t t[i] */ | |
| 59 | +#define CREATE_S(o,s) CREATE_U((o),(s)+MAXARG_S) | |
| 60 | +#define GETARG_S(i) (GETARG_U(i)-MAXARG_S) | |
| 61 | +#define SETARG_S(i,s) SETARG_U((i),(s)+MAXARG_S) | |
| 47 | 62 | |
| 48 | −GETDOTTEDW,/* w t t[CNST[w]] */ | |
| 49 | −GETDOTTED,/* b t t[CNST[b]] */ | |
| 50 | 63 | |
| 51 | −PUSHSELFW,/* w t t t[CNST[w]] */ | |
| 52 | −PUSHSELF,/* b t t t[CNST[b]] */ | |
| 64 | +#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<POS_A) \ | |
| 65 | + | ((Instruction)(b)<<POS_B)) | |
| 66 | +#define GETARG_A(i) ((int)((i)>>POS_A)) | |
| 67 | +#define SETARG_A(i,a) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ | |
| 68 | + ((Instruction)(a)<<POS_A))) | |
| 69 | +#define GETARG_B(i) ((int)(((i)>>POS_B) & MASK1(SIZE_B,0))) | |
| 70 | +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ | |
| 71 | + ((Instruction)(b)<<POS_B))) | |
| 53 | 72 | |
| 54 | −CREATEARRAYW,/* w - newarray(size = w) */ | |
| 55 | −CREATEARRAY,/* b - newarray(size = b) */ | |
| 56 | 73 | |
| 57 | −SETLOCAL,/* b x - LOC[b]=x */ | |
| 74 | +/* | |
| 75 | +** K = U argument used as index to `kstr' | |
| 76 | +** J = S argument used as jump offset (relative to pc of next instruction) | |
| 77 | +** L = unsigned argument used as index of local variable | |
| 78 | +** N = U argument used as index to `knum' | |
| 79 | +*/ | |
| 58 | 80 | |
| 59 | −SETGLOBALW,/* w x - VAR[CNST[w]]=x */ | |
| 60 | −SETGLOBAL,/* b x - VAR[CNST[b]]=x */ | |
| 81 | +typedef enum { | |
| 82 | +/*---------------------------------------------------------------------- | |
| 83 | +name args stack before stack after side effects | |
| 84 | +------------------------------------------------------------------------*/ | |
| 85 | +OP_END,/* - - (return) no results */ | |
| 86 | +OP_RETURN,/* U v_n-v_x(at u) (return) returns v_x-v_n */ | |
| 61 | 87 | |
| 62 | −SETTABLEPOP,/* - v i t - t[i]=v */ | |
| 88 | +OP_CALL,/* A B v_n-v_1 f(at a) r_b-r_1 f(v1,...,v_n) */ | |
| 89 | +OP_TAILCALL,/* A B v_n-v_1 f(at a) (return) f(v1,...,v_n) */ | |
| 63 | 90 | |
| 64 | −SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ | |
| 91 | +OP_PUSHNIL,/* U - nil_1-nil_u */ | |
| 92 | +OP_POP,/* U a_u-a_1 - */ | |
| 65 | 93 | |
| 66 | −SETLISTW,/* w c v_c...v_1 t t t[i+w*FPF]=v_i */ | |
| 67 | −SETLIST,/* b c v_c...v_1 t t t[i+b*FPF]=v_i */ | |
| 94 | +OP_PUSHINT,/* S - (Number)s */ | |
| 95 | +OP_PUSHSTRING,/* K - KSTR[k] */ | |
| 96 | +OP_PUSHNUM,/* N - KNUM[n] */ | |
| 97 | +OP_PUSHNEGNUM,/* N - -KNUM[n] */ | |
| 68 | 98 | |
| 69 | −SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */ | |
| 99 | +OP_PUSHUPVALUE,/* U - Closure[u] */ | |
| 70 | 100 | |
| 71 | −NEQOP,/* - y x (x~=y)? 1 : nil */ | |
| 72 | −EQOP,/* - y x (x==y)? 1 : nil */ | |
| 73 | −LTOP,/* - y x (x<y)? 1 : nil */ | |
| 74 | −LEOP,/* - y x (x<y)? 1 : nil */ | |
| 75 | −GTOP,/* - y x (x>y)? 1 : nil */ | |
| 76 | −GEOP,/* - y x (x>=y)? 1 : nil */ | |
| 77 | −ADDOP,/* - y x x+y */ | |
| 78 | −SUBOP,/* - y x x-y */ | |
| 79 | −MULTOP,/* - y x x*y */ | |
| 80 | −DIVOP,/* - y x x/y */ | |
| 81 | −POWOP,/* - y x x^y */ | |
| 82 | −CONCOP,/* - y x x..y */ | |
| 83 | −MINUSOP,/* - x -x */ | |
| 84 | −NOTOP,/* - x (x==nil)? 1 : nil */ | |
| 101 | +OP_GETLOCAL,/* L - LOC[l] */ | |
| 102 | +OP_GETGLOBAL,/* K - VAR[KSTR[k]] */ | |
| 85 | 103 | |
| 86 | −ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */ | |
| 87 | −ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */ | |
| 88 | −ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */ | |
| 89 | −ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */ | |
| 90 | −JMPW,/* w - - PC+=w */ | |
| 91 | −JMP,/* b - - PC+=b */ | |
| 92 | −IFFJMPW,/* w x - (x==nil)? PC+=w */ | |
| 93 | −IFFJMP,/* b x - (x==nil)? PC+=b */ | |
| 94 | −IFTUPJMPW,/* w x - (x!=nil)? PC-=w */ | |
| 95 | −IFTUPJMP,/* b x - (x!=nil)? PC-=b */ | |
| 96 | −IFFUPJMPW,/* w x - (x==nil)? PC-=w */ | |
| 97 | −IFFUPJMP,/* b x - (x==nil)? PC-=b */ | |
| 104 | +OP_GETTABLE,/* - i t t[i] */ | |
| 105 | +OP_GETDOTTED,/* K t t[KSTR[k]] */ | |
| 106 | +OP_GETINDEXED,/* L t t[LOC[l]] */ | |
| 107 | +OP_PUSHSELF,/* K t t t[KSTR[k]] */ | |
| 98 | 108 | |
| 99 | −CLOSUREW,/* w c v_c...v_1 closure(CNST[w], v_c...v_1) */ | |
| 100 | −CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */ | |
| 109 | +OP_CREATETABLE,/* U - newarray(size = u) */ | |
| 101 | 110 | |
| 102 | −SETLINEW,/* w - - LINE=w */ | |
| 103 | −SETLINE,/* b - - LINE=b */ | |
| 111 | +OP_SETLOCAL,/* L x - LOC[l]=x */ | |
| 112 | +OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */ | |
| 113 | +OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ | |
| 104 | 114 | |
| 105 | −LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */ | |
| 106 | −LONGARG,/* b (add b*(1<<16) to arg of next instruction) */ | |
| 115 | +OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */ | |
| 116 | +OP_SETMAP,/* U v_u k_u - v_1 k_1 t t t[k_i]=v_i */ | |
| 107 | 117 | |
| 108 | −CHECKSTACK /* b (assert #temporaries == b; only for internal debuging!) */ | |
| 118 | +OP_ADD,/* - y x x+y */ | |
| 119 | +OP_ADDI,/* S x x+s */ | |
| 120 | +OP_SUB,/* - y x x-y */ | |
| 121 | +OP_MULT,/* - y x x*y */ | |
| 122 | +OP_DIV,/* - y x x/y */ | |
| 123 | +OP_POW,/* - y x x^y */ | |
| 124 | +OP_CONCAT,/* U v_u-v_1 v1..-..v_u */ | |
| 125 | +OP_MINUS,/* - x -x */ | |
| 126 | +OP_NOT,/* - x (x==nil)? 1 : nil */ | |
| 109 | 127 | |
| 110 | −} OpCode; | |
| 128 | +OP_JMPNE,/* J y x - (x~=y)? PC+=s */ | |
| 129 | +OP_JMPEQ,/* J y x - (x==y)? PC+=s */ | |
| 130 | +OP_JMPLT,/* J y x - (x<y)? PC+=s */ | |
| 131 | +OP_JMPLE,/* J y x - (x<y)? PC+=s */ | |
| 132 | +OP_JMPGT,/* J y x - (x>y)? PC+=s */ | |
| 133 | +OP_JMPGE,/* J y x - (x>=y)? PC+=s */ | |
| 111 | 134 | |
| 135 | +OP_JMPT,/* J x - (x~=nil)? PC+=s */ | |
| 136 | +OP_JMPF,/* J x - (x==nil)? PC+=s */ | |
| 137 | +OP_JMPONT,/* J x (x~=nil)? x : - (x~=nil)? PC+=s */ | |
| 138 | +OP_JMPONF,/* J x (x==nil)? x : - (x==nil)? PC+=s */ | |
| 139 | +OP_JMP,/* J - - PC+=s */ | |
| 112 | 140 | |
| 113 | −#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */ | |
| 114 | −#define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) */ | |
| 141 | +OP_PUSHNILJMP,/* - - nil PC++; */ | |
| 115 | 142 | |
| 116 | −#define ZEROVARARG 128 | |
| 143 | +OP_FORPREP,/* J */ | |
| 144 | +OP_FORLOOP,/* J */ | |
| 117 | 145 | |
| 146 | +OP_LFORPREP,/* J */ | |
| 147 | +OP_LFORLOOP,/* J */ | |
| 118 | 148 | |
| 119 | −/* maximum value of an arg of 3 bytes; must fit in an "int" */ | |
| 120 | −#if MAX_INT < (1<<24) | |
| 121 | −#define MAX_ARG MAX_INT | |
| 122 | −#else | |
| 123 | −#define MAX_ARG ((1<<24)-1) | |
| 124 | −#endif | |
| 149 | +OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */ | |
| 125 | 150 | |
| 126 | −/* maximum value of a word of 2 bytes; cannot be bigger than MAX_ARG */ | |
| 127 | −#if MAX_ARG < (1<<16) | |
| 128 | −#define MAX_WORD MAX_ARG | |
| 129 | −#else | |
| 130 | −#define MAX_WORD ((1<<16)-1) | |
| 131 | −#endif | |
| 151 | +} OpCode; | |
| 152 | + | |
| 153 | +#define NUM_OPCODES ((int)OP_CLOSURE+1) | |
| 132 | 154 | |
| 133 | 155 | |
| 134 | −/* maximum value of a byte */ | |
| 135 | −#define MAX_BYTE ((1<<8)-1) | |
| 156 | +#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP) | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | +/* special code to fit a LUA_MULTRET inside an argB */ | |
| 161 | +#define MULT_RET 255 /* (<=MAXARG_B) */ | |
| 162 | +#if MULT_RET>MAXARG_B | |
| 163 | +#undef MULT_RET | |
| 164 | +#define MULT_RET MAXARG_B | |
| 165 | +#endif | |
| 136 | 166 | |
| 137 | 167 | |
| 138 | 168 | #endif |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lparser.c,v 1.37a 1999/06/17 17:04:03 roberto Exp $ | |
| 2 | +** $Id: lparser.c,v 1.116 2000/10/27 11:39:52 roberto Exp $ | |
| 3 | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,1385 +8,1117 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <stdio.h> |
| 9 | 9 | #include <string.h> |
| 10 | 10 | |
| 11 | −#include "lauxlib.h" | |
| 12 | −#include "ldo.h" | |
| 11 | +#include "lua.h" | |
| 12 | + | |
| 13 | +#include "lcode.h" | |
| 13 | 14 | #include "lfunc.h" |
| 14 | 15 | #include "llex.h" |
| 15 | 16 | #include "lmem.h" |
| 17 | +#include "lobject.h" | |
| 16 | 18 | #include "lopcodes.h" |
| 17 | 19 | #include "lparser.h" |
| 18 | 20 | #include "lstate.h" |
| 19 | 21 | #include "lstring.h" |
| 20 | −#include "lua.h" | |
| 21 | −#include "luadebug.h" | |
| 22 | −#include "lzio.h" | |
| 23 | − | |
| 24 | − | |
| 25 | − | |
| 26 | −/* size of a "normal" jump instruction: OpCode + 1 byte */ | |
| 27 | −#define JMPSIZE 2 | |
| 28 | − | |
| 29 | −/* maximum number of local variables */ | |
| 30 | −#ifndef MAXLOCALS | |
| 31 | −#define MAXLOCALS 200 /* arbitrary limit (<256) */ | |
| 32 | −#endif | |
| 33 | − | |
| 34 | − | |
| 35 | −/* maximum number of upvalues */ | |
| 36 | −#ifndef MAXUPVALUES | |
| 37 | −#define MAXUPVALUES 32 /* arbitrary limit (<256) */ | |
| 38 | −#endif | |
| 39 | − | |
| 40 | − | |
| 41 | −/* maximum number of variables in the left side of an assignment */ | |
| 42 | −#ifndef MAXVARSLH | |
| 43 | −#define MAXVARSLH 100 /* arbitrary limit (<255) */ | |
| 44 | −#endif | |
| 45 | − | |
| 46 | − | |
| 47 | −/* maximum number of parameters in a function */ | |
| 48 | −#ifndef MAXPARAMS | |
| 49 | −#define MAXPARAMS 100 /* arbitrary limit (<ZEROVARARG) */ | |
| 50 | −#endif | |
| 51 | − | |
| 52 | − | |
| 53 | −/* | |
| 54 | −** Variable descriptor: | |
| 55 | −** must include an "exp" option because LL(1) cannot distinguish | |
| 56 | −** between variables, upvalues and function calls on first sight. | |
| 57 | −*/ | |
| 58 | −typedef enum { | |
| 59 | − VGLOBAL, /* info is constant index of global name */ | |
| 60 | − VLOCAL, /* info is stack index */ | |
| 61 | − VDOT, /* info is constant index of index name */ | |
| 62 | − VINDEXED, /* no info (table and index are on the stack) */ | |
| 63 | − VEXP /* info is pc index of "nparam" of a call (or 0 if exp is closed) */ | |
| 64 | −} varkind; | |
| 65 | − | |
| 66 | −typedef struct vardesc { | |
| 67 | − varkind k; | |
| 68 | − int info; | |
| 69 | −} vardesc; | |
| 70 | − | |
| 71 | − | |
| 72 | −/* | |
| 73 | −** Expression List descriptor: | |
| 74 | −** tells number of expressions in the list, | |
| 75 | −** and, if last expression is open (a function call), | |
| 76 | −** where is its pc index of "nparam" | |
| 77 | −*/ | |
| 78 | −typedef struct listdesc { | |
| 79 | − int n; | |
| 80 | − int pc; /* 0 if last expression is closed */ | |
| 81 | −} listdesc; | |
| 82 | 22 | |
| 83 | 23 | |
| 84 | 24 | /* |
| 85 | 25 | ** Constructors descriptor: |
| 86 | −** "n" indicates number of elements, and "k" signals whether | |
| 26 | +** `n' indicates number of elements, and `k' signals whether | |
| 87 | 27 | ** it is a list constructor (k = 0) or a record constructor (k = 1) |
| 88 | 28 | ** or empty (k = ';' or '}') |
| 89 | 29 | */ |
| 90 | −typedef struct constdesc { | |
| 30 | +typedef struct Constdesc { | |
| 91 | 31 | int n; |
| 92 | 32 | int k; |
| 93 | −} constdesc; | |
| 33 | +} Constdesc; | |
| 34 | + | |
| 35 | + | |
| 36 | +typedef struct Breaklabel { | |
| 37 | + struct Breaklabel *previous; /* chain */ | |
| 38 | + int breaklist; | |
| 39 | + int stacklevel; | |
| 40 | +} Breaklabel; | |
| 94 | 41 | |
| 95 | 42 | |
| 96 | −/* state needed to generate code for a given function */ | |
| 97 | −typedef struct FuncState { | |
| 98 | − TProtoFunc *f; /* current function header */ | |
| 99 | − struct FuncState *prev; /* enclosuring function */ | |
| 100 | − int pc; /* next position to code */ | |
| 101 | − int stacksize; /* number of values on activation register */ | |
| 102 | − int maxstacksize; /* maximum number of values on activation register */ | |
| 103 | − int nlocalvar; /* number of active local variables */ | |
| 104 | − int nupvalues; /* number of upvalues */ | |
| 105 | − int nvars; /* number of entries in f->locvars (-1 if no debug information) */ | |
| 106 | − int lastsetline; /* line where last SETLINE was issued */ | |
| 107 | − vardesc upvalues[MAXUPVALUES]; /* upvalues */ | |
| 108 | − TaggedString *localvar[MAXLOCALS]; /* store local variable names */ | |
| 109 | −} FuncState; | |
| 110 | 43 | |
| 111 | 44 | |
| 112 | 45 | /* |
| 113 | −** prototypes for non-terminal functions | |
| 46 | +** prototypes for recursive non-terminal functions | |
| 114 | 47 | */ |
| 115 | −static int assignment (LexState *ls, vardesc *v, int nvars); | |
| 116 | −static int cond (LexState *ls); | |
| 117 | −static int funcname (LexState *ls, vardesc *v); | |
| 118 | −static int funcparams (LexState *ls, int slf); | |
| 119 | −static int listfields (LexState *ls); | |
| 120 | −static int localnamelist (LexState *ls); | |
| 121 | −static int optional (LexState *ls, int c); | |
| 122 | −static int recfields (LexState *ls); | |
| 123 | −static int stat (LexState *ls); | |
| 124 | −static void block (LexState *ls); | |
| 125 | 48 | static void body (LexState *ls, int needself, int line); |
| 126 | 49 | static void chunk (LexState *ls); |
| 127 | 50 | static void constructor (LexState *ls); |
| 128 | −static void decinit (LexState *ls, listdesc *d); | |
| 129 | −static void exp0 (LexState *ls, vardesc *v); | |
| 51 | +static void expr (LexState *ls, expdesc *v); | |
| 130 | 52 | static void exp1 (LexState *ls); |
| 131 | −static void exp2 (LexState *ls, vardesc *v); | |
| 132 | −static void explist (LexState *ls, listdesc *e); | |
| 133 | −static void explist1 (LexState *ls, listdesc *e); | |
| 134 | −static void ifpart (LexState *ls, int line); | |
| 135 | −static void parlist (LexState *ls); | |
| 136 | −static void part (LexState *ls, constdesc *cd); | |
| 137 | −static void recfield (LexState *ls); | |
| 138 | −static void ret (LexState *ls); | |
| 139 | −static void statlist (LexState *ls); | |
| 140 | −static void var_or_func (LexState *ls, vardesc *v); | |
| 141 | −static void var_or_func_tail (LexState *ls, vardesc *v); | |
| 142 | − | |
| 143 | − | |
| 144 | − | |
| 145 | −static void checklimit (LexState *ls, int val, int limit, char *msg) { | |
| 146 | − if (val > limit) { | |
| 147 | − char buff[100]; | |
| 148 | − sprintf(buff, "too many %s (limit=%d)", msg, limit); | |
| 149 | − luaX_error(ls, buff); | |
| 150 | − } | |
| 151 | −} | |
| 152 | − | |
| 153 | 53 | |
| 154 | −static void check_pc (FuncState *fs, int n) { | |
| 155 | − luaM_growvector(fs->f->code, fs->pc, n, Byte, codeEM, MAX_INT); | |
| 156 | −} | |
| 157 | − | |
| 158 | − | |
| 159 | −static void code_byte (FuncState *fs, Byte c) { | |
| 160 | − check_pc(fs, 1); | |
| 161 | − fs->f->code[fs->pc++] = c; | |
| 162 | −} | |
| 163 | − | |
| 164 | − | |
| 165 | −static void deltastack (LexState *ls, int delta) { | |
| 166 | − FuncState *fs = ls->fs; | |
| 167 | − fs->stacksize += delta; | |
| 168 | − if (fs->stacksize > fs->maxstacksize) { | |
| 169 | − if (fs->stacksize > MAX_BYTE) | |
| 170 | − luaX_error(ls, "function/expression too complex"); | |
| 171 | − fs->maxstacksize = fs->stacksize; | |
| 172 | − } | |
| 173 | −} | |
| 174 | 54 | |
| 175 | 55 | |
| 176 | −static void code_oparg_at (LexState *ls, int pc, OpCode op, | |
| 177 | − int arg, int delta) { | |
| 178 | − Byte *code = ls->fs->f->code; | |
| 179 | − deltastack(ls, delta); | |
| 180 | − if (arg <= MAX_BYTE) { | |
| 181 | − code[pc] = (Byte)op; | |
| 182 | − code[pc+1] = (Byte)arg; | |
| 183 | − } | |
| 184 | − else if (arg > MAX_ARG) | |
| 185 | − luaX_error(ls, "code too long"); | |
| 186 | − else { /* MAX_BYTE < arg < MAX_ARG */ | |
| 187 | − if (arg > MAX_WORD) { | |
| 188 | − code[pc] = (Byte)LONGARG; | |
| 189 | − code[pc+1] = (Byte)(arg>>16); | |
| 190 | − pc += 2; | |
| 191 | − } | |
| 192 | − code[pc] = (Byte)(op-1); /* opcode for word argument */ | |
| 193 | − code[pc+1] = (Byte)((arg&0xFFFF)>>8); | |
| 194 | − code[pc+2] = (Byte)(arg&0xFF); | |
| 56 | +static void next (LexState *ls) { | |
| 57 | + ls->lastline = ls->linenumber; | |
| 58 | + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ | |
| 59 | + ls->t = ls->lookahead; /* use this one */ | |
| 60 | + ls->lookahead.token = TK_EOS; /* and discharge it */ | |
| 195 | 61 | } |
| 62 | + else | |
| 63 | + ls->t.token = luaX_lex(ls, &ls->t.seminfo); /* read next token */ | |
| 196 | 64 | } |
| 197 | 65 | |
| 198 | 66 | |
| 199 | −static int codesize (int arg) { | |
| 200 | − if (arg <= MAX_BYTE) return 2; /* opcode + 1 byte */ | |
| 201 | − else if (arg <= MAX_WORD) return 3; /* opcode + 1 word (2 bytes) */ | |
| 202 | − else return 5; /* LONGARG + 1 byte + opcode + 1 word (2 bytes) */ | |
| 67 | +static void lookahead (LexState *ls) { | |
| 68 | + LUA_ASSERT(ls->lookahead.token == TK_EOS, "two look-aheads"); | |
| 69 | + ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo); | |
| 203 | 70 | } |
| 204 | 71 | |
| 205 | 72 | |
| 206 | −static int fix_opcode (LexState *ls, int pc, OpCode op, int arg) { | |
| 207 | − int tomove = codesize(arg)-2; | |
| 208 | − if (tomove > 0) { /* need to open space? */ | |
| 209 | − FuncState *fs = ls->fs; | |
| 210 | − TProtoFunc *f = fs->f; | |
| 211 | − check_pc(fs, tomove); | |
| 212 | − luaO_memup(f->code+pc+tomove, f->code+pc, fs->pc-pc); | |
| 213 | − fs->pc += tomove; | |
| 214 | − } | |
| 215 | − code_oparg_at(ls, pc, op, arg, 0); | |
| 216 | − return tomove; | |
| 73 | +static void error_expected (LexState *ls, int token) { | |
| 74 | + char buff[100], t[TOKEN_LEN]; | |
| 75 | + luaX_token2str(token, t); | |
| 76 | + sprintf(buff, "`%.20s' expected", t); | |
| 77 | + luaK_error(ls, buff); | |
| 217 | 78 | } |
| 218 | 79 | |
| 219 | 80 | |
| 220 | −static void code_oparg (LexState *ls, OpCode op, int arg, int delta) { | |
| 221 | − int size = codesize(arg); | |
| 222 | − check_pc(ls->fs, size); | |
| 223 | − code_oparg_at(ls, ls->fs->pc, op, arg, delta); | |
| 224 | − ls->fs->pc += size; | |
| 81 | +static void check (LexState *ls, int c) { | |
| 82 | + if (ls->t.token != c) | |
| 83 | + error_expected(ls, c); | |
| 84 | + next(ls); | |
| 225 | 85 | } |
| 226 | 86 | |
| 227 | 87 | |
| 228 | −static void code_opcode (LexState *ls, OpCode op, int delta) { | |
| 229 | − deltastack(ls, delta); | |
| 230 | − code_byte(ls->fs, (Byte)op); | |
| 88 | +static void check_condition (LexState *ls, int c, const char *msg) { | |
| 89 | + if (!c) luaK_error(ls, msg); | |
| 231 | 90 | } |
| 232 | 91 | |
| 233 | 92 | |
| 234 | −static void code_constant (LexState *ls, int c) { | |
| 235 | − code_oparg(ls, PUSHCONSTANT, c, 1); | |
| 93 | +static int optional (LexState *ls, int c) { | |
| 94 | + if (ls->t.token == c) { | |
| 95 | + next(ls); | |
| 96 | + return 1; | |
| 97 | + } | |
| 98 | + else return 0; | |
| 236 | 99 | } |
| 237 | 100 | |
| 238 | 101 | |
| 239 | −static int next_constant (FuncState *fs) { | |
| 240 | − TProtoFunc *f = fs->f; | |
| 241 | − luaM_growvector(f->consts, f->nconsts, 1, TObject, constantEM, MAX_ARG); | |
| 242 | − return f->nconsts++; | |
| 102 | +static void check_match (LexState *ls, int what, int who, int where) { | |
| 103 | + if (ls->t.token != what) { | |
| 104 | + if (where == ls->linenumber) | |
| 105 | + error_expected(ls, what); | |
| 106 | + else { | |
| 107 | + char buff[100]; | |
| 108 | + char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; | |
| 109 | + luaX_token2str(what, t_what); | |
| 110 | + luaX_token2str(who, t_who); | |
| 111 | + sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", | |
| 112 | + t_what, t_who, where); | |
| 113 | + luaK_error(ls, buff); | |
| 114 | + } | |
| 115 | + } | |
| 116 | + next(ls); | |
| 243 | 117 | } |
| 244 | 118 | |
| 245 | 119 | |
| 246 | −static int string_constant (FuncState *fs, TaggedString *s) { | |
| 247 | − TProtoFunc *f = fs->f; | |
| 248 | − int c = s->constindex; | |
| 249 | − if (!(c < f->nconsts && | |
| 250 | − ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) { | |
| 251 | − c = next_constant(fs); | |
| 252 | − ttype(&f->consts[c]) = LUA_T_STRING; | |
| 253 | − tsvalue(&f->consts[c]) = s; | |
| 254 | − s->constindex = c; /* hint for next time */ | |
| 120 | +static int string_constant (FuncState *fs, TString *s) { | |
| 121 | + Proto *f = fs->f; | |
| 122 | + int c = s->u.s.constindex; | |
| 123 | + if (c >= f->nkstr || f->kstr[c] != s) { | |
| 124 | + luaM_growvector(fs->L, f->kstr, f->nkstr, 1, TString *, | |
| 125 | + "constant table overflow", MAXARG_U); | |
| 126 | + c = f->nkstr++; | |
| 127 | + f->kstr[c] = s; | |
| 128 | + s->u.s.constindex = c; /* hint for next time */ | |
| 255 | 129 | } |
| 256 | 130 | return c; |
| 257 | 131 | } |
| 258 | 132 | |
| 259 | 133 | |
| 260 | −static void code_string (LexState *ls, TaggedString *s) { | |
| 261 | − code_constant(ls, string_constant(ls->fs, s)); | |
| 262 | −} | |
| 263 | − | |
| 264 | − | |
| 265 | −#define LIM 20 | |
| 266 | −static int real_constant (FuncState *fs, real r) { | |
| 267 | − /* check whether 'r' has appeared within the last LIM entries */ | |
| 268 | − TObject *cnt = fs->f->consts; | |
| 269 | − int c = fs->f->nconsts; | |
| 270 | − int lim = c < LIM ? 0 : c-LIM; | |
| 271 | − while (--c >= lim) { | |
| 272 | − if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r) | |
| 273 | − return c; | |
| 274 | − } | |
| 275 | − /* not found; create a new entry */ | |
| 276 | − c = next_constant(fs); | |
| 277 | − cnt = fs->f->consts; /* 'next_constant' may have reallocated this vector */ | |
| 278 | − ttype(&cnt[c]) = LUA_T_NUMBER; | |
| 279 | − nvalue(&cnt[c]) = r; | |
| 280 | − return c; | |
| 134 | +static void code_string (LexState *ls, TString *s) { | |
| 135 | + luaK_kstr(ls, string_constant(ls->fs, s)); | |
| 281 | 136 | } |
| 282 | 137 | |
| 283 | 138 | |
| 284 | −static void code_number (LexState *ls, real f) { | |
| 285 | − real af = (f<0) ? -f : f; | |
| 286 | − if (0 <= af && af <= (real)MAX_WORD && (int)af == af) { | |
| 287 | − /* abs(f) has a short integer value */ | |
| 288 | − code_oparg(ls, (f<0) ? PUSHNUMBERNEG : PUSHNUMBER, (int)af, 1); | |
| 289 | − } | |
| 290 | − else | |
| 291 | − code_constant(ls, real_constant(ls->fs, f)); | |
| 139 | +static TString *str_checkname (LexState *ls) { | |
| 140 | + TString *ts; | |
| 141 | + check_condition(ls, (ls->t.token == TK_NAME), "<name> expected"); | |
| 142 | + ts = ls->t.seminfo.ts; | |
| 143 | + next(ls); | |
| 144 | + return ts; | |
| 292 | 145 | } |
| 293 | 146 | |
| 294 | 147 | |
| 295 | −static void flush_record (LexState *ls, int n) { | |
| 296 | − if (n > 0) | |
| 297 | − code_oparg(ls, SETMAP, n-1, -2*n); | |
| 148 | +static int checkname (LexState *ls) { | |
| 149 | + return string_constant(ls->fs, str_checkname(ls)); | |
| 298 | 150 | } |
| 299 | 151 | |
| 300 | 152 | |
| 301 | −static void flush_list (LexState *ls, int m, int n) { | |
| 302 | − if (n > 0) { | |
| 303 | − code_oparg(ls, SETLIST, m, -n); | |
| 304 | − code_byte(ls->fs, (Byte)n); | |
| 305 | − } | |
| 153 | +static int luaI_registerlocalvar (LexState *ls, TString *varname) { | |
| 154 | + Proto *f = ls->fs->f; | |
| 155 | + luaM_growvector(ls->L, f->locvars, f->nlocvars, 1, LocVar, "", MAX_INT); | |
| 156 | + f->locvars[f->nlocvars].varname = varname; | |
| 157 | + return f->nlocvars++; | |
| 306 | 158 | } |
| 307 | 159 | |
| 308 | 160 | |
| 309 | −static void luaI_registerlocalvar (FuncState *fs, TaggedString *varname, | |
| 310 | − int line) { | |
| 311 | − if (fs->nvars != -1) { /* debug information? */ | |
| 312 | − TProtoFunc *f = fs->f; | |
| 313 | − luaM_growvector(f->locvars, fs->nvars, 1, LocVar, "", MAX_INT); | |
| 314 | − f->locvars[fs->nvars].varname = varname; | |
| 315 | − f->locvars[fs->nvars].line = line; | |
| 316 | − fs->nvars++; | |
| 317 | − } | |
| 161 | +static void new_localvar (LexState *ls, TString *name, int n) { | |
| 162 | + FuncState *fs = ls->fs; | |
| 163 | + luaX_checklimit(ls, fs->nactloc+n+1, MAXLOCALS, "local variables"); | |
| 164 | + fs->actloc[fs->nactloc+n] = luaI_registerlocalvar(ls, name); | |
| 318 | 165 | } |
| 319 | 166 | |
| 320 | 167 | |
| 321 | −static void luaI_unregisterlocalvar (FuncState *fs, int line) { | |
| 322 | − luaI_registerlocalvar(fs, NULL, line); | |
| 168 | +static void adjustlocalvars (LexState *ls, int nvars) { | |
| 169 | + FuncState *fs = ls->fs; | |
| 170 | + while (nvars--) | |
| 171 | + fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc; | |
| 323 | 172 | } |
| 324 | 173 | |
| 325 | 174 | |
| 326 | −static void store_localvar (LexState *ls, TaggedString *name, int n) { | |
| 175 | +static void removelocalvars (LexState *ls, int nvars) { | |
| 327 | 176 | FuncState *fs = ls->fs; |
| 328 | − checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables"); | |
| 329 | − fs->localvar[fs->nlocalvar+n] = name; | |
| 330 | − luaI_registerlocalvar(fs, name, ls->linenumber); | |
| 177 | + while (nvars--) | |
| 178 | + fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc; | |
| 331 | 179 | } |
| 332 | 180 | |
| 333 | 181 | |
| 334 | −static void add_localvar (LexState *ls, TaggedString *name) { | |
| 335 | − store_localvar(ls, name, 0); | |
| 336 | − ls->fs->nlocalvar++; | |
| 182 | +static void new_localvarstr (LexState *ls, const char *name, int n) { | |
| 183 | + new_localvar(ls, luaS_newfixed(ls->L, name), n); | |
| 337 | 184 | } |
| 338 | 185 | |
| 339 | 186 | |
| 340 | −static void correctvarlines (LexState *ls, int nvars) { | |
| 341 | − FuncState *fs = ls->fs; | |
| 342 | − if (fs->nvars != -1) { /* debug information? */ | |
| 343 | − for (; nvars; nvars--) { /* correct line information */ | |
| 344 | − fs->f->locvars[fs->nvars-nvars].line = fs->lastsetline; | |
| 187 | +static int search_local (LexState *ls, TString *n, expdesc *var) { | |
| 188 | + FuncState *fs; | |
| 189 | + int level = 0; | |
| 190 | + for (fs=ls->fs; fs; fs=fs->prev) { | |
| 191 | + int i; | |
| 192 | + for (i=fs->nactloc-1; i >= 0; i--) { | |
| 193 | + if (n == fs->f->locvars[fs->actloc[i]].varname) { | |
| 194 | + var->k = VLOCAL; | |
| 195 | + var->u.index = i; | |
| 196 | + return level; | |
| 197 | + } | |
| 345 | 198 | } |
| 199 | + level++; /* `var' not found; check outer level */ | |
| 346 | 200 | } |
| 201 | + var->k = VGLOBAL; /* not found in any level; must be global */ | |
| 202 | + return -1; | |
| 347 | 203 | } |
| 348 | 204 | |
| 349 | 205 | |
| 350 | −static int aux_localname (FuncState *fs, TaggedString *n) { | |
| 351 | − int i; | |
| 352 | − for (i=fs->nlocalvar-1; i >= 0; i--) | |
| 353 | − if (n == fs->localvar[i]) return i; /* local var index */ | |
| 354 | − return -1; /* not found */ | |
| 355 | −} | |
| 356 | − | |
| 357 | − | |
| 358 | −static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int prev) { | |
| 359 | − FuncState *fs = prev ? ls->fs->prev : ls->fs; | |
| 360 | − int i = aux_localname(fs, n); | |
| 361 | − if (i >= 0) { /* local value? */ | |
| 362 | − var->k = VLOCAL; | |
| 363 | − var->info = i; | |
| 364 | − } | |
| 365 | − else { | |
| 366 | − FuncState *level = fs; | |
| 367 | − while ((level = level->prev) != NULL) /* check shadowing */ | |
| 368 | − if (aux_localname(level, n) >= 0) | |
| 369 | − luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); | |
| 370 | − var->k = VGLOBAL; | |
| 371 | − var->info = string_constant(fs, n); | |
| 372 | − } | |
| 206 | +static void singlevar (LexState *ls, TString *n, expdesc *var) { | |
| 207 | + int level = search_local(ls, n, var); | |
| 208 | + if (level >= 1) /* neither local (0) nor global (-1)? */ | |
| 209 | + luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); | |
| 210 | + else if (level == -1) /* global? */ | |
| 211 | + var->u.index = string_constant(ls->fs, n); | |
| 373 | 212 | } |
| 374 | 213 | |
| 375 | 214 | |
| 376 | −static int indexupvalue (LexState *ls, TaggedString *n) { | |
| 215 | +static int indexupvalue (LexState *ls, expdesc *v) { | |
| 377 | 216 | FuncState *fs = ls->fs; |
| 378 | − vardesc v; | |
| 379 | 217 | int i; |
| 380 | − singlevar(ls, n, &v, 1); | |
| 381 | 218 | for (i=0; i<fs->nupvalues; i++) { |
| 382 | − if (fs->upvalues[i].k == v.k && fs->upvalues[i].info == v.info) | |
| 219 | + if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.index == v->u.index) | |
| 383 | 220 | return i; |
| 384 | 221 | } |
| 385 | 222 | /* new one */ |
| 386 | − ++(fs->nupvalues); | |
| 387 | − checklimit(ls, fs->nupvalues, MAXUPVALUES, "upvalues"); | |
| 388 | − fs->upvalues[i] = v; /* i = fs->nupvalues - 1 */ | |
| 389 | − return i; | |
| 390 | −} | |
| 391 | − | |
| 392 | − | |
| 393 | −static void pushupvalue (LexState *ls, TaggedString *n) { | |
| 394 | − if (ls->fs->prev == NULL) | |
| 395 | − luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | |
| 396 | − if (aux_localname(ls->fs, n) >= 0) | |
| 397 | − luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); | |
| 398 | − code_oparg(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); | |
| 399 | −} | |
| 400 | − | |
| 401 | − | |
| 402 | − | |
| 403 | −static void check_debugline (LexState *ls) { | |
| 404 | − if (L->debug && ls->linenumber != ls->fs->lastsetline) { | |
| 405 | − code_oparg(ls, SETLINE, ls->linenumber, 0); | |
| 406 | − ls->fs->lastsetline = ls->linenumber; | |
| 407 | − } | |
| 408 | −} | |
| 409 | − | |
| 410 | − | |
| 411 | −static void adjuststack (LexState *ls, int n) { | |
| 412 | − if (n > 0) | |
| 413 | − code_oparg(ls, POP, n, -n); | |
| 414 | − else if (n < 0) | |
| 415 | − code_oparg(ls, PUSHNIL, (-n)-1, -n); | |
| 223 | + luaX_checklimit(ls, fs->nupvalues+1, MAXUPVALUES, "upvalues"); | |
| 224 | + fs->upvalues[fs->nupvalues] = *v; | |
| 225 | + return fs->nupvalues++; | |
| 416 | 226 | } |
| 417 | 227 | |
| 418 | 228 | |
| 419 | −static void close_exp (LexState *ls, int pc, int nresults) { | |
| 420 | − if (pc > 0) { /* expression is an open function call? */ | |
| 421 | − Byte *code = ls->fs->f->code; | |
| 422 | − code[pc-1] = (Byte)nresults; /* set nresults */ | |
| 423 | − /* push results, pop params (at code[pc]) and function */ | |
| 424 | − deltastack(ls, nresults-(code[pc]+1)); | |
| 229 | +static void pushupvalue (LexState *ls, TString *n) { | |
| 230 | + FuncState *fs = ls->fs; | |
| 231 | + expdesc v; | |
| 232 | + int level = search_local(ls, n, &v); | |
| 233 | + if (level == -1) { /* global? */ | |
| 234 | + if (fs->prev == NULL) | |
| 235 | + luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | |
| 236 | + v.u.index = string_constant(fs->prev, n); | |
| 425 | 237 | } |
| 426 | −#ifdef DEBUG | |
| 427 | − code_oparg(ls, CHECKSTACK, ls->fs->stacksize, 0); | |
| 428 | −#endif | |
| 238 | + else if (level != 1) | |
| 239 | + luaX_syntaxerror(ls, | |
| 240 | + "upvalue must be global or local to immediately outer scope", n->str); | |
| 241 | + luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, &v)); | |
| 429 | 242 | } |
| 430 | 243 | |
| 431 | 244 | |
| 432 | −static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { | |
| 433 | − int diff = d->n - nvars; | |
| 434 | − if (d->pc == 0) { /* list is closed */ | |
| 435 | − /* push or pop eventual difference between list lengths */ | |
| 436 | − adjuststack(ls, diff); | |
| 437 | − } | |
| 438 | − else { /* must correct function call */ | |
| 245 | +static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { | |
| 246 | + FuncState *fs = ls->fs; | |
| 247 | + int diff = nexps - nvars; | |
| 248 | + if (nexps > 0 && luaK_lastisopen(fs)) { /* list ends in a function call */ | |
| 439 | 249 | diff--; /* do not count function call itself */ |
| 440 | 250 | if (diff <= 0) { /* more variables than values? */ |
| 441 | − /* function call must provide extra values */ | |
| 442 | − close_exp(ls, d->pc, -diff); | |
| 443 | − } | |
| 444 | − else { /* more values than variables */ | |
| 445 | − close_exp(ls, d->pc, 0); /* call should provide no value */ | |
| 446 | − adjuststack(ls, diff); /* pop eventual extra values */ | |
| 251 | + luaK_setcallreturns(fs, -diff); /* function call provide extra values */ | |
| 252 | + diff = 0; /* no more difference */ | |
| 447 | 253 | } |
| 254 | + else /* more values than variables */ | |
| 255 | + luaK_setcallreturns(fs, 0); /* call should provide no value */ | |
| 448 | 256 | } |
| 257 | + /* push or pop eventual difference between list lengths */ | |
| 258 | + luaK_adjuststack(fs, diff); | |
| 449 | 259 | } |
| 450 | 260 | |
| 451 | 261 | |
| 452 | −static void code_args (LexState *ls, int nparams, int dots) { | |
| 262 | +static void code_params (LexState *ls, int nparams, int dots) { | |
| 453 | 263 | FuncState *fs = ls->fs; |
| 454 | − fs->nlocalvar += nparams; /* "self" may already be there */ | |
| 455 | − checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); | |
| 456 | − nparams = fs->nlocalvar; | |
| 457 | − if (!dots) { | |
| 458 | − fs->f->code[1] = (Byte)nparams; /* fill-in arg information */ | |
| 459 | − deltastack(ls, nparams); | |
| 460 | − } | |
| 461 | − else { | |
| 462 | − fs->f->code[1] = (Byte)(nparams+ZEROVARARG); | |
| 463 | − deltastack(ls, nparams+1); | |
| 464 | − add_localvar(ls, luaS_new("arg")); | |
| 465 | − } | |
| 466 | −} | |
| 467 | − | |
| 468 | − | |
| 469 | −static void unloaddot (LexState *ls, vardesc *v) { | |
| 470 | − /* dotted variables <a.x> must be stored like regular indexed vars <a["x"]> */ | |
| 471 | − if (v->k == VDOT) { | |
| 472 | − code_constant(ls, v->info); | |
| 473 | − v->k = VINDEXED; | |
| 474 | − } | |
| 475 | −} | |
| 476 | − | |
| 477 | − | |
| 478 | −static void lua_pushvar (LexState *ls, vardesc *var) { | |
| 479 | − switch (var->k) { | |
| 480 | − case VLOCAL: | |
| 481 | − code_oparg(ls, PUSHLOCAL, var->info, 1); | |
| 482 | − break; | |
| 483 | − case VGLOBAL: | |
| 484 | − code_oparg(ls, GETGLOBAL, var->info, 1); | |
| 485 | − break; | |
| 486 | − case VDOT: | |
| 487 | − code_oparg(ls, GETDOTTED, var->info, 0); | |
| 488 | − break; | |
| 489 | − case VINDEXED: | |
| 490 | − code_opcode(ls, GETTABLE, -1); | |
| 491 | − break; | |
| 492 | − case VEXP: | |
| 493 | − close_exp(ls, var->info, 1); /* function must return 1 value */ | |
| 494 | − break; | |
| 495 | − } | |
| 496 | − var->k = VEXP; | |
| 497 | − var->info = 0; /* now this is a closed expression */ | |
| 498 | −} | |
| 499 | − | |
| 500 | − | |
| 501 | −static void storevar (LexState *ls, vardesc *var) { | |
| 502 | − switch (var->k) { | |
| 503 | − case VLOCAL: | |
| 504 | − code_oparg(ls, SETLOCAL, var->info, -1); | |
| 505 | − break; | |
| 506 | − case VGLOBAL: | |
| 507 | − code_oparg(ls, SETGLOBAL, var->info, -1); | |
| 508 | − break; | |
| 509 | − case VINDEXED: | |
| 510 | − code_opcode(ls, SETTABLEPOP, -3); | |
| 511 | − break; | |
| 512 | − default: | |
| 513 | − LUA_INTERNALERROR("invalid var kind to store"); | |
| 264 | + adjustlocalvars(ls, nparams); | |
| 265 | + luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters"); | |
| 266 | + fs->f->numparams = fs->nactloc; /* `self' could be there already */ | |
| 267 | + fs->f->is_vararg = dots; | |
| 268 | + if (dots) { | |
| 269 | + new_localvarstr(ls, "arg", 0); | |
| 270 | + adjustlocalvars(ls, 1); | |
| 514 | 271 | } |
| 272 | + luaK_deltastack(fs, fs->nactloc); /* count parameters in the stack */ | |
| 515 | 273 | } |
| 516 | 274 | |
| 517 | 275 | |
| 518 | −static int fix_jump (LexState *ls, int pc, OpCode op, int n) { | |
| 519 | − /* jump is relative to position following jump instruction */ | |
| 520 | − return fix_opcode(ls, pc, op, n-(pc+JMPSIZE)); | |
| 521 | −} | |
| 522 | − | |
| 523 | − | |
| 524 | −static void fix_upjmp (LexState *ls, OpCode op, int pos) { | |
| 525 | − int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */ | |
| 526 | − code_oparg(ls, op, delta+(codesize(delta)-2), 0); | |
| 276 | +static void enterbreak (FuncState *fs, Breaklabel *bl) { | |
| 277 | + bl->stacklevel = fs->stacklevel; | |
| 278 | + bl->breaklist = NO_JUMP; | |
| 279 | + bl->previous = fs->bl; | |
| 280 | + fs->bl = bl; | |
| 527 | 281 | } |
| 528 | 282 | |
| 529 | 283 | |
| 530 | −static void codeIf (LexState *ls, int thenAdd, int elseAdd) { | |
| 531 | − FuncState *fs = ls->fs; | |
| 532 | − int elseinit = elseAdd+JMPSIZE; | |
| 533 | − if (fs->pc == elseinit) { /* no else part? */ | |
| 534 | − fs->pc -= JMPSIZE; | |
| 535 | − elseinit = fs->pc; | |
| 536 | − } | |
| 537 | − else | |
| 538 | − elseinit += fix_jump(ls, elseAdd, JMP, fs->pc); | |
| 539 | − fix_jump(ls, thenAdd, IFFJMP, elseinit); | |
| 284 | +static void leavebreak (FuncState *fs, Breaklabel *bl) { | |
| 285 | + fs->bl = bl->previous; | |
| 286 | + LUA_ASSERT(bl->stacklevel == fs->stacklevel, "wrong levels"); | |
| 287 | + luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs)); | |
| 540 | 288 | } |
| 541 | 289 | |
| 542 | 290 | |
| 543 | −static void func_onstack (LexState *ls, FuncState *func) { | |
| 291 | +static void pushclosure (LexState *ls, FuncState *func) { | |
| 544 | 292 | FuncState *fs = ls->fs; |
| 293 | + Proto *f = fs->f; | |
| 545 | 294 | int i; |
| 546 | − int c = next_constant(fs); | |
| 547 | − ttype(&fs->f->consts[c]) = LUA_T_PROTO; | |
| 548 | − fs->f->consts[c].value.tf = func->f; | |
| 549 | − if (func->nupvalues == 0) | |
| 550 | − code_constant(ls, c); | |
| 551 | − else { | |
| 552 | − for (i=0; i<func->nupvalues; i++) | |
| 553 | − lua_pushvar(ls, &func->upvalues[i]); | |
| 554 | − deltastack(ls, 1); /* CLOSURE puts one extra element (before poping) */ | |
| 555 | − code_oparg(ls, CLOSURE, c, -func->nupvalues); | |
| 556 | − code_byte(fs, (Byte)func->nupvalues); | |
| 557 | − } | |
| 295 | + for (i=0; i<func->nupvalues; i++) | |
| 296 | + luaK_tostack(ls, &func->upvalues[i], 1); | |
| 297 | + luaM_growvector(ls->L, f->kproto, f->nkproto, 1, Proto *, | |
| 298 | + "constant table overflow", MAXARG_A); | |
| 299 | + f->kproto[f->nkproto++] = func->f; | |
| 300 | + luaK_code2(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues); | |
| 558 | 301 | } |
| 559 | 302 | |
| 560 | 303 | |
| 561 | −static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { | |
| 562 | − TProtoFunc *f = luaF_newproto(); | |
| 304 | +static void open_func (LexState *ls, FuncState *fs) { | |
| 305 | + Proto *f = luaF_newproto(ls->L); | |
| 563 | 306 | fs->prev = ls->fs; /* linked list of funcstates */ |
| 307 | + fs->ls = ls; | |
| 308 | + fs->L = ls->L; | |
| 564 | 309 | ls->fs = fs; |
| 565 | − fs->stacksize = 0; | |
| 566 | − fs->maxstacksize = 0; | |
| 567 | − fs->nlocalvar = 0; | |
| 310 | + fs->stacklevel = 0; | |
| 311 | + fs->nactloc = 0; | |
| 568 | 312 | fs->nupvalues = 0; |
| 569 | − fs->lastsetline = 0; | |
| 313 | + fs->bl = NULL; | |
| 570 | 314 | fs->f = f; |
| 571 | − f->source = source; | |
| 315 | + f->source = ls->source; | |
| 572 | 316 | fs->pc = 0; |
| 317 | + fs->lasttarget = 0; | |
| 318 | + fs->lastline = 0; | |
| 319 | + fs->jlt = NO_JUMP; | |
| 573 | 320 | f->code = NULL; |
| 574 | − fs->nvars = (L->debug) ? 0 : -1; /* flag no debug information? */ | |
| 575 | − code_byte(fs, 0); /* to be filled with maxstacksize */ | |
| 576 | − code_byte(fs, 0); /* to be filled with arg information */ | |
| 577 | − /* push function (to avoid GC) */ | |
| 578 | − tfvalue(L->stack.top) = f; ttype(L->stack.top) = LUA_T_PROTO; | |
| 579 | − incr_top; | |
| 321 | + f->maxstacksize = 0; | |
| 322 | + f->numparams = 0; /* default for main chunk */ | |
| 323 | + f->is_vararg = 0; /* default for main chunk */ | |
| 580 | 324 | } |
| 581 | 325 | |
| 582 | 326 | |
| 583 | 327 | static void close_func (LexState *ls) { |
| 328 | + lua_State *L = ls->L; | |
| 584 | 329 | FuncState *fs = ls->fs; |
| 585 | − TProtoFunc *f = fs->f; | |
| 586 | − code_opcode(ls, ENDCODE, 0); | |
| 587 | − f->code[0] = (Byte)fs->maxstacksize; | |
| 588 | − luaM_reallocvector(f->code, fs->pc, Byte); | |
| 589 | − luaM_reallocvector(f->consts, f->nconsts, TObject); | |
| 590 | − if (fs->nvars != -1) { /* debug information? */ | |
| 591 | − luaI_registerlocalvar(fs, NULL, -1); /* flag end of vector */ | |
| 592 | − luaM_reallocvector(f->locvars, fs->nvars, LocVar); | |
| 593 | − } | |
| 330 | + Proto *f = fs->f; | |
| 331 | + luaK_code0(fs, OP_END); | |
| 332 | + luaK_getlabel(fs); /* close eventual list of pending jumps */ | |
| 333 | + luaM_reallocvector(L, f->code, fs->pc, Instruction); | |
| 334 | + luaM_reallocvector(L, f->kstr, f->nkstr, TString *); | |
| 335 | + luaM_reallocvector(L, f->knum, f->nknum, Number); | |
| 336 | + luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); | |
| 337 | + removelocalvars(ls, fs->nactloc); | |
| 338 | + luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar); | |
| 339 | + luaM_reallocvector(L, f->lineinfo, f->nlineinfo+1, int); | |
| 340 | + f->lineinfo[f->nlineinfo++] = MAX_INT; /* end flag */ | |
| 341 | + luaF_protook(L, f, fs->pc); /* proto is ok now */ | |
| 594 | 342 | ls->fs = fs->prev; |
| 595 | − L->stack.top--; /* pop function */ | |
| 596 | −} | |
| 597 | − | |
| 598 | − | |
| 599 | − | |
| 600 | −static int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, DO, NAME, | |
| 601 | − LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';', EOS, ',', 0}; | |
| 602 | − | |
| 603 | − | |
| 604 | −static int is_in (int tok, int *toks) { | |
| 605 | − int *t; | |
| 606 | − for (t=toks; *t; t++) | |
| 607 | − if (*t == tok) return t-toks; | |
| 608 | − return -1; | |
| 609 | −} | |
| 610 | − | |
| 611 | − | |
| 612 | −static void next (LexState *ls) { | |
| 613 | − ls->token = luaX_lex(ls); | |
| 614 | −} | |
| 615 | − | |
| 616 | − | |
| 617 | −static void error_expected (LexState *ls, int token) { | |
| 618 | − char buff[100], t[TOKEN_LEN]; | |
| 619 | − luaX_token2str(token, t); | |
| 620 | − sprintf(buff, "`%s' expected", t); | |
| 621 | − luaX_error(ls, buff); | |
| 622 | −} | |
| 623 | − | |
| 624 | − | |
| 625 | −static void error_unexpected (LexState *ls) { | |
| 626 | − luaX_error(ls, "unexpected token"); | |
| 627 | −} | |
| 628 | − | |
| 629 | − | |
| 630 | −static void error_unmatched (LexState *ls, int what, int who, int where) { | |
| 631 | − if (where == ls->linenumber) | |
| 632 | − error_expected(ls, what); | |
| 633 | − else { | |
| 634 | − char buff[100]; | |
| 635 | − char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; | |
| 636 | − luaX_token2str(what, t_what); | |
| 637 | − luaX_token2str(who, t_who); | |
| 638 | − sprintf(buff, "`%s' expected (to close `%s' at line %d)", | |
| 639 | − t_what, t_who, where); | |
| 640 | − luaX_error(ls, buff); | |
| 641 | − } | |
| 642 | −} | |
| 643 | − | |
| 644 | −static void check (LexState *ls, int c) { | |
| 645 | − if (ls->token != c) | |
| 646 | − error_expected(ls, c); | |
| 647 | − next(ls); | |
| 648 | −} | |
| 649 | − | |
| 650 | −static void check_match (LexState *ls, int what, int who, int where) { | |
| 651 | − if (ls->token != what) | |
| 652 | − error_unmatched(ls, what, who, where); | |
| 653 | − check_debugline(ls); /* to 'mark' the 'what' */ | |
| 654 | − next(ls); | |
| 655 | −} | |
| 656 | − | |
| 657 | −static int checkname (LexState *ls) { | |
| 658 | − int sc; | |
| 659 | − if (ls->token != NAME) | |
| 660 | − luaX_error(ls, "`NAME' expected"); | |
| 661 | − sc = string_constant(ls->fs, ls->seminfo.ts); | |
| 662 | − next(ls); | |
| 663 | − return sc; | |
| 664 | −} | |
| 665 | − | |
| 666 | − | |
| 667 | −static TaggedString *str_checkname (LexState *ls) { | |
| 668 | − int i = checkname(ls); /* this call may realloc `f->consts' */ | |
| 669 | − return tsvalue(&ls->fs->f->consts[i]); | |
| 670 | −} | |
| 671 | − | |
| 672 | − | |
| 673 | −static int optional (LexState *ls, int c) { | |
| 674 | − if (ls->token == c) { | |
| 675 | − next(ls); | |
| 676 | − return 1; | |
| 677 | − } | |
| 678 | − else return 0; | |
| 343 | + LUA_ASSERT(fs->bl == NULL, "wrong list end"); | |
| 679 | 344 | } |
| 680 | 345 | |
| 681 | 346 | |
| 682 | −TProtoFunc *luaY_parser (ZIO *z) { | |
| 347 | +Proto *luaY_parser (lua_State *L, ZIO *z) { | |
| 683 | 348 | struct LexState lexstate; |
| 684 | 349 | struct FuncState funcstate; |
| 685 | − luaX_setinput(&lexstate, z); | |
| 686 | − init_state(&lexstate, &funcstate, luaS_new(zname(z))); | |
| 350 | + luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); | |
| 351 | + open_func(&lexstate, &funcstate); | |
| 687 | 352 | next(&lexstate); /* read first token */ |
| 688 | 353 | chunk(&lexstate); |
| 689 | − if (lexstate.token != EOS) | |
| 690 | − luaX_error(&lexstate, "<eof> expected"); | |
| 354 | + check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); | |
| 691 | 355 | close_func(&lexstate); |
| 356 | + LUA_ASSERT(funcstate.prev == NULL, "wrong list end"); | |
| 357 | + LUA_ASSERT(funcstate.nupvalues == 0, "no upvalues in main"); | |
| 692 | 358 | return funcstate.f; |
| 693 | 359 | } |
| 694 | 360 | |
| 695 | 361 | |
| 696 | 362 | |
| 697 | 363 | /*============================================================*/ |
| 698 | −/* GRAMAR RULES */ | |
| 364 | +/* GRAMMAR RULES */ | |
| 699 | 365 | /*============================================================*/ |
| 700 | 366 | |
| 701 | −static void chunk (LexState *ls) { | |
| 702 | − /* chunk -> statlist ret */ | |
| 703 | − statlist(ls); | |
| 704 | − ret(ls); | |
| 705 | −} | |
| 706 | 367 | |
| 707 | −static void statlist (LexState *ls) { | |
| 708 | − /* statlist -> { stat [;] } */ | |
| 709 | − while (stat(ls)) { | |
| 710 | − LUA_ASSERT(ls->fs->stacksize == ls->fs->nlocalvar, | |
| 711 | − "stack size != # local vars"); | |
| 712 | − optional(ls, ';'); | |
| 368 | +static int explist1 (LexState *ls) { | |
| 369 | + /* explist1 -> expr { ',' expr } */ | |
| 370 | + int n = 1; /* at least one expression */ | |
| 371 | + expdesc v; | |
| 372 | + expr(ls, &v); | |
| 373 | + while (ls->t.token == ',') { | |
| 374 | + luaK_tostack(ls, &v, 1); /* gets only 1 value from previous expression */ | |
| 375 | + next(ls); /* skip comma */ | |
| 376 | + expr(ls, &v); | |
| 377 | + n++; | |
| 713 | 378 | } |
| 379 | + luaK_tostack(ls, &v, 0); /* keep open number of values of last expression */ | |
| 380 | + return n; | |
| 714 | 381 | } |
| 715 | 382 | |
| 716 | −static int stat (LexState *ls) { | |
| 717 | − int line = ls->linenumber; /* may be needed for error messages */ | |
| 718 | − FuncState *fs = ls->fs; | |
| 719 | − switch (ls->token) { | |
| 720 | − case IF: /* stat -> IF ifpart END */ | |
| 721 | − ifpart(ls, line); | |
| 722 | − return 1; | |
| 723 | 383 | |
| 724 | − case WHILE: { /* stat -> WHILE cond DO block END */ | |
| 725 | − TProtoFunc *f = fs->f; | |
| 726 | − int while_init = fs->pc; | |
| 727 | − int cond_end, cond_size; | |
| 384 | +static void funcargs (LexState *ls, int slf) { | |
| 385 | + FuncState *fs = ls->fs; | |
| 386 | + int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ | |
| 387 | + switch (ls->t.token) { | |
| 388 | + case '(': { /* funcargs -> '(' [ explist1 ] ')' */ | |
| 389 | + int line = ls->linenumber; | |
| 390 | + int nargs = 0; | |
| 728 | 391 | next(ls); |
| 729 | − cond_end = cond(ls); | |
| 730 | − check(ls, DO); | |
| 731 | − block(ls); | |
| 732 | − check_match(ls, END, WHILE, line); | |
| 733 | − cond_size = cond_end-while_init; | |
| 734 | − check_pc(fs, cond_size); | |
| 735 | − memcpy(f->code+fs->pc, f->code+while_init, cond_size); | |
| 736 | − luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init); | |
| 737 | − while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size); | |
| 738 | − fix_upjmp(ls, IFTUPJMP, while_init); | |
| 739 | − return 1; | |
| 392 | + if (ls->t.token != ')') /* arg list not empty? */ | |
| 393 | + nargs = explist1(ls); | |
| 394 | + check_match(ls, ')', '(', line); | |
| 395 | +#ifdef LUA_COMPAT_ARGRET | |
| 396 | + if (nargs > 0) /* arg list is not empty? */ | |
| 397 | + luaK_setcallreturns(fs, 1); /* last call returns only 1 value */ | |
| 398 | +#else | |
| 399 | + UNUSED(nargs); /* to avoid warnings */ | |
| 400 | +#endif | |
| 401 | + break; | |
| 740 | 402 | } |
| 741 | − | |
| 742 | − case DO: { /* stat -> DO block END */ | |
| 743 | − next(ls); | |
| 744 | − block(ls); | |
| 745 | − check_match(ls, END, DO, line); | |
| 746 | − return 1; | |
| 403 | + case '{': { /* funcargs -> constructor */ | |
| 404 | + constructor(ls); | |
| 405 | + break; | |
| 747 | 406 | } |
| 748 | − | |
| 749 | − case REPEAT: { /* stat -> REPEAT block UNTIL exp1 */ | |
| 750 | − int repeat_init = fs->pc; | |
| 407 | + case TK_STRING: { /* funcargs -> STRING */ | |
| 408 | + code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ | |
| 751 | 409 | next(ls); |
| 752 | − block(ls); | |
| 753 | − check_match(ls, UNTIL, REPEAT, line); | |
| 754 | − exp1(ls); | |
| 755 | − fix_upjmp(ls, IFFUPJMP, repeat_init); | |
| 756 | − deltastack(ls, -1); /* pops condition */ | |
| 757 | − return 1; | |
| 410 | + break; | |
| 758 | 411 | } |
| 759 | − | |
| 760 | − case FUNCTION: { /* stat -> FUNCTION funcname body */ | |
| 761 | − int needself; | |
| 762 | − vardesc v; | |
| 763 | − if (ls->fs->prev) /* inside other function? */ | |
| 764 | − return 0; | |
| 765 | − check_debugline(ls); | |
| 766 | − next(ls); | |
| 767 | − needself = funcname(ls, &v); | |
| 768 | − body(ls, needself, line); | |
| 769 | − storevar(ls, &v); | |
| 770 | − return 1; | |
| 412 | + default: { | |
| 413 | + luaK_error(ls, "function arguments expected"); | |
| 414 | + break; | |
| 771 | 415 | } |
| 416 | + } | |
| 417 | + fs->stacklevel = slevel; /* call will remove function and arguments */ | |
| 418 | + luaK_code2(fs, OP_CALL, slevel, MULT_RET); | |
| 419 | +} | |
| 772 | 420 | |
| 773 | − case LOCAL: { /* stat -> LOCAL localnamelist decinit */ | |
| 774 | − listdesc d; | |
| 775 | − int nvars; | |
| 776 | − check_debugline(ls); | |
| 777 | − next(ls); | |
| 778 | − nvars = localnamelist(ls); | |
| 779 | − decinit(ls, &d); | |
| 780 | − fs->nlocalvar += nvars; | |
| 781 | − correctvarlines(ls, nvars); /* vars will be alive only after decinit */ | |
| 782 | − adjust_mult_assign(ls, nvars, &d); | |
| 783 | − return 1; | |
| 784 | − } | |
| 785 | 421 | |
| 786 | − case NAME: case '%': { /* stat -> func | ['%'] NAME assignment */ | |
| 787 | − vardesc v; | |
| 788 | − check_debugline(ls); | |
| 789 | − var_or_func(ls, &v); | |
| 790 | − if (v.k == VEXP) { /* stat -> func */ | |
| 791 | − if (v.info == 0) /* is just an upper value? */ | |
| 792 | − luaX_error(ls, "syntax error"); | |
| 793 | − close_exp(ls, v.info, 0); | |
| 422 | +static void var_or_func_tail (LexState *ls, expdesc *v) { | |
| 423 | + for (;;) { | |
| 424 | + switch (ls->t.token) { | |
| 425 | + case '.': { /* var_or_func_tail -> '.' NAME */ | |
| 426 | + next(ls); | |
| 427 | + luaK_tostack(ls, v, 1); /* `v' must be on stack */ | |
| 428 | + luaK_kstr(ls, checkname(ls)); | |
| 429 | + v->k = VINDEXED; | |
| 430 | + break; | |
| 794 | 431 | } |
| 795 | − else { /* stat -> ['%'] NAME assignment */ | |
| 796 | − int left = assignment(ls, &v, 1); | |
| 797 | − adjuststack(ls, left); /* remove eventual 'garbage' left on stack */ | |
| 432 | + case '[': { /* var_or_func_tail -> '[' exp1 ']' */ | |
| 433 | + next(ls); | |
| 434 | + luaK_tostack(ls, v, 1); /* `v' must be on stack */ | |
| 435 | + v->k = VINDEXED; | |
| 436 | + exp1(ls); | |
| 437 | + check(ls, ']'); | |
| 438 | + break; | |
| 798 | 439 | } |
| 799 | − return 1; | |
| 440 | + case ':': { /* var_or_func_tail -> ':' NAME funcargs */ | |
| 441 | + int name; | |
| 442 | + next(ls); | |
| 443 | + name = checkname(ls); | |
| 444 | + luaK_tostack(ls, v, 1); /* `v' must be on stack */ | |
| 445 | + luaK_code1(ls->fs, OP_PUSHSELF, name); | |
| 446 | + funcargs(ls, 1); | |
| 447 | + v->k = VEXP; | |
| 448 | + v->u.l.t = v->u.l.f = NO_JUMP; | |
| 449 | + break; | |
| 450 | + } | |
| 451 | + case '(': case TK_STRING: case '{': { /* var_or_func_tail -> funcargs */ | |
| 452 | + luaK_tostack(ls, v, 1); /* `v' must be on stack */ | |
| 453 | + funcargs(ls, 0); | |
| 454 | + v->k = VEXP; | |
| 455 | + v->u.l.t = v->u.l.f = NO_JUMP; | |
| 456 | + break; | |
| 457 | + } | |
| 458 | + default: return; /* should be follow... */ | |
| 800 | 459 | } |
| 460 | + } | |
| 461 | +} | |
| 801 | 462 | |
| 802 | − case RETURN: case ';': case ELSE: case ELSEIF: | |
| 803 | − case END: case UNTIL: case EOS: /* 'stat' follow */ | |
| 804 | − return 0; | |
| 805 | 463 | |
| 806 | − default: | |
| 807 | − error_unexpected(ls); | |
| 808 | − return 0; /* to avoid warnings */ | |
| 464 | +static void var_or_func (LexState *ls, expdesc *v) { | |
| 465 | + /* var_or_func -> ['%'] NAME var_or_func_tail */ | |
| 466 | + if (optional(ls, '%')) { /* upvalue? */ | |
| 467 | + pushupvalue(ls, str_checkname(ls)); | |
| 468 | + v->k = VEXP; | |
| 469 | + v->u.l.t = v->u.l.f = NO_JUMP; | |
| 809 | 470 | } |
| 471 | + else /* variable name */ | |
| 472 | + singlevar(ls, str_checkname(ls), v); | |
| 473 | + var_or_func_tail(ls, v); | |
| 810 | 474 | } |
| 811 | 475 | |
| 812 | −static int SaveWord (LexState *ls) { | |
| 813 | − int res = ls->fs->pc; | |
| 814 | − check_pc(ls->fs, JMPSIZE); | |
| 815 | − ls->fs->pc += JMPSIZE; /* open space */ | |
| 816 | − return res; | |
| 817 | −} | |
| 818 | 476 | |
| 819 | −static int SaveWordPop (LexState *ls) { | |
| 820 | − deltastack(ls, -1); /* pop condition */ | |
| 821 | − return SaveWord(ls); | |
| 822 | −} | |
| 823 | 477 | |
| 824 | −static int cond (LexState *ls) { | |
| 825 | − /* cond -> exp1 */ | |
| 826 | − exp1(ls); | |
| 827 | − return SaveWordPop(ls); | |
| 828 | −} | |
| 478 | +/* | |
| 479 | +** {====================================================================== | |
| 480 | +** Rules for Constructors | |
| 481 | +** ======================================================================= | |
| 482 | +*/ | |
| 829 | 483 | |
| 830 | −static void block (LexState *ls) { | |
| 831 | − /* block -> chunk */ | |
| 832 | − FuncState *fs = ls->fs; | |
| 833 | − int nlocalvar = fs->nlocalvar; | |
| 834 | − chunk(ls); | |
| 835 | − adjuststack(ls, fs->nlocalvar - nlocalvar); | |
| 836 | − for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--) | |
| 837 | − luaI_unregisterlocalvar(fs, fs->lastsetline); | |
| 838 | −} | |
| 839 | 484 | |
| 840 | −static int funcname (LexState *ls, vardesc *v) { | |
| 841 | − /* funcname -> NAME [':' NAME | '.' NAME] */ | |
| 842 | − int needself = 0; | |
| 843 | − singlevar(ls, str_checkname(ls), v, 0); | |
| 844 | − if (ls->token == ':' || ls->token == '.') { | |
| 845 | − needself = (ls->token == ':'); | |
| 846 | − next(ls); | |
| 847 | − lua_pushvar(ls, v); | |
| 848 | − code_constant(ls, checkname(ls)); | |
| 849 | − v->k = VINDEXED; | |
| 485 | +static void recfield (LexState *ls) { | |
| 486 | + /* recfield -> (NAME | '['exp1']') = exp1 */ | |
| 487 | + switch (ls->t.token) { | |
| 488 | + case TK_NAME: { | |
| 489 | + luaK_kstr(ls, checkname(ls)); | |
| 490 | + break; | |
| 491 | + } | |
| 492 | + case '[': { | |
| 493 | + next(ls); | |
| 494 | + exp1(ls); | |
| 495 | + check(ls, ']'); | |
| 496 | + break; | |
| 497 | + } | |
| 498 | + default: luaK_error(ls, "<name> or `[' expected"); | |
| 850 | 499 | } |
| 851 | − return needself; | |
| 852 | −} | |
| 853 | − | |
| 854 | −static void body (LexState *ls, int needself, int line) { | |
| 855 | − /* body -> '(' parlist ')' chunk END */ | |
| 856 | − FuncState newfs; | |
| 857 | − init_state(ls, &newfs, ls->fs->f->source); | |
| 858 | − newfs.f->lineDefined = line; | |
| 859 | − check(ls, '('); | |
| 860 | − if (needself) | |
| 861 | − add_localvar(ls, luaS_new("self")); | |
| 862 | − parlist(ls); | |
| 863 | − check(ls, ')'); | |
| 864 | − chunk(ls); | |
| 865 | − check_match(ls, END, FUNCTION, line); | |
| 866 | − close_func(ls); | |
| 867 | − func_onstack(ls, &newfs); | |
| 500 | + check(ls, '='); | |
| 501 | + exp1(ls); | |
| 868 | 502 | } |
| 869 | 503 | |
| 870 | 504 | |
| 871 | −static void ifpart (LexState *ls, int line) { | |
| 872 | − /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ | |
| 873 | − int c; | |
| 874 | − int e; | |
| 875 | − next(ls); /* skip IF or ELSEIF */ | |
| 876 | − c = cond(ls); | |
| 877 | − check(ls, THEN); | |
| 878 | − block(ls); | |
| 879 | − e = SaveWord(ls); | |
| 880 | − if (ls->token == ELSEIF) | |
| 881 | − ifpart(ls, line); | |
| 882 | − else { | |
| 883 | − if (optional(ls, ELSE)) | |
| 884 | − block(ls); | |
| 885 | − check_match(ls, END, IF, line); | |
| 505 | +static int recfields (LexState *ls) { | |
| 506 | + /* recfields -> recfield { ',' recfield } [','] */ | |
| 507 | + FuncState *fs = ls->fs; | |
| 508 | + int n = 1; /* at least one element */ | |
| 509 | + recfield(ls); | |
| 510 | + while (ls->t.token == ',') { | |
| 511 | + next(ls); | |
| 512 | + if (ls->t.token == ';' || ls->t.token == '}') | |
| 513 | + break; | |
| 514 | + recfield(ls); | |
| 515 | + n++; | |
| 516 | + if (n%RFIELDS_PER_FLUSH == 0) | |
| 517 | + luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH); | |
| 886 | 518 | } |
| 887 | − codeIf(ls, c, e); | |
| 519 | + luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH); | |
| 520 | + return n; | |
| 888 | 521 | } |
| 889 | 522 | |
| 890 | 523 | |
| 891 | −static void ret (LexState *ls) { | |
| 892 | − /* ret -> [RETURN explist sc] */ | |
| 893 | − if (optional(ls, RETURN)) { | |
| 894 | − listdesc e; | |
| 895 | − check_debugline(ls); | |
| 896 | − explist(ls, &e); | |
| 897 | − if (e.pc > 0) { /* expression is an open function call? */ | |
| 898 | − Byte *code = ls->fs->f->code; | |
| 899 | − code[e.pc-2] = TAILCALL; /* instead of a conventional CALL */ | |
| 900 | − code[e.pc-1] = (Byte)ls->fs->nlocalvar; | |
| 901 | − } | |
| 902 | − else | |
| 903 | − code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0); | |
| 904 | − ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ | |
| 905 | − optional(ls, ';'); | |
| 524 | +static int listfields (LexState *ls) { | |
| 525 | + /* listfields -> exp1 { ',' exp1 } [','] */ | |
| 526 | + FuncState *fs = ls->fs; | |
| 527 | + int n = 1; /* at least one element */ | |
| 528 | + exp1(ls); | |
| 529 | + while (ls->t.token == ',') { | |
| 530 | + next(ls); | |
| 531 | + if (ls->t.token == ';' || ls->t.token == '}') | |
| 532 | + break; | |
| 533 | + exp1(ls); | |
| 534 | + n++; | |
| 535 | + luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, | |
| 536 | + "`item groups' in a list initializer"); | |
| 537 | + if (n%LFIELDS_PER_FLUSH == 0) | |
| 538 | + luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); | |
| 906 | 539 | } |
| 540 | + luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); | |
| 541 | + return n; | |
| 907 | 542 | } |
| 908 | 543 | |
| 909 | 544 | |
| 910 | −/* | |
| 911 | −** For parsing expressions, we use a classic stack with priorities. | |
| 912 | −** Each binary operator is represented by its index in "binop" + FIRSTBIN | |
| 913 | −** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1. | |
| 914 | −*/ | |
| 915 | − | |
| 916 | −#define INDNOT 0 | |
| 917 | −#define INDMINUS 1 | |
| 918 | − | |
| 919 | −/* code of first binary operator */ | |
| 920 | −#define FIRSTBIN 2 | |
| 921 | − | |
| 922 | −/* code for power operator (last operator) | |
| 923 | −** '^' needs special treatment because it is right associative | |
| 924 | −*/ | |
| 925 | −#define POW 13 | |
| 926 | − | |
| 927 | −static int binop [] = {EQ, NE, '>', '<', LE, GE, CONC, | |
| 928 | − '+', '-', '*', '/', '^', 0}; | |
| 929 | − | |
| 930 | −static int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6}; | |
| 931 | − | |
| 932 | −static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP, | |
| 933 | − LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP}; | |
| 934 | − | |
| 935 | −#define MAXOPS 20 /* op's stack size (arbitrary limit) */ | |
| 936 | 545 | |
| 937 | −typedef struct stack_op { | |
| 938 | − int ops[MAXOPS]; | |
| 939 | − int top; | |
| 940 | −} stack_op; | |
| 941 | − | |
| 942 | − | |
| 943 | −static void exp1 (LexState *ls) { | |
| 944 | − vardesc v; | |
| 945 | − exp0(ls, &v); | |
| 946 | − lua_pushvar(ls, &v); | |
| 947 | − if (is_in(ls->token, expfollow) < 0) | |
| 948 | − luaX_error(ls, "ill-formed expression"); | |
| 546 | +static void constructor_part (LexState *ls, Constdesc *cd) { | |
| 547 | + switch (ls->t.token) { | |
| 548 | + case ';': case '}': { /* constructor_part -> empty */ | |
| 549 | + cd->n = 0; | |
| 550 | + cd->k = ls->t.token; | |
| 551 | + break; | |
| 552 | + } | |
| 553 | + case TK_NAME: { /* may be listfields or recfields */ | |
| 554 | + lookahead(ls); | |
| 555 | + if (ls->lookahead.token != '=') /* expression? */ | |
| 556 | + goto case_default; | |
| 557 | + /* else go through to recfields */ | |
| 558 | + } | |
| 559 | + case '[': { /* constructor_part -> recfields */ | |
| 560 | + cd->n = recfields(ls); | |
| 561 | + cd->k = 1; /* record */ | |
| 562 | + break; | |
| 563 | + } | |
| 564 | + default: { /* constructor_part -> listfields */ | |
| 565 | + case_default: | |
| 566 | + cd->n = listfields(ls); | |
| 567 | + cd->k = 0; /* list */ | |
| 568 | + break; | |
| 569 | + } | |
| 570 | + } | |
| 949 | 571 | } |
| 950 | 572 | |
| 951 | 573 | |
| 952 | −static void exp0 (LexState *ls, vardesc *v) { | |
| 953 | − /* exp0 -> exp2 {(AND | OR) exp2} */ | |
| 954 | − exp2(ls, v); | |
| 955 | − while (ls->token == AND || ls->token == OR) { | |
| 956 | − int op = (ls->token == AND) ? ONFJMP : ONTJMP; | |
| 957 | − int pc; | |
| 958 | − lua_pushvar(ls, v); | |
| 959 | − next(ls); | |
| 960 | − pc = SaveWordPop(ls); | |
| 961 | − exp2(ls, v); | |
| 962 | − lua_pushvar(ls, v); | |
| 963 | − fix_jump(ls, pc, op, ls->fs->pc); | |
| 574 | +static void constructor (LexState *ls) { | |
| 575 | + /* constructor -> '{' constructor_part [';' constructor_part] '}' */ | |
| 576 | + FuncState *fs = ls->fs; | |
| 577 | + int line = ls->linenumber; | |
| 578 | + int pc = luaK_code1(fs, OP_CREATETABLE, 0); | |
| 579 | + int nelems; | |
| 580 | + Constdesc cd; | |
| 581 | + check(ls, '{'); | |
| 582 | + constructor_part(ls, &cd); | |
| 583 | + nelems = cd.n; | |
| 584 | + if (optional(ls, ';')) { | |
| 585 | + Constdesc other_cd; | |
| 586 | + constructor_part(ls, &other_cd); | |
| 587 | + check_condition(ls, (cd.k != other_cd.k), "invalid constructor syntax"); | |
| 588 | + nelems += other_cd.n; | |
| 964 | 589 | } |
| 590 | + check_match(ls, '}', '{', line); | |
| 591 | + luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor"); | |
| 592 | + SETARG_U(fs->f->code[pc], nelems); /* set initial table size */ | |
| 965 | 593 | } |
| 966 | 594 | |
| 595 | +/* }====================================================================== */ | |
| 967 | 596 | |
| 968 | −static void push (LexState *ls, stack_op *s, int op) { | |
| 969 | − if (s->top >= MAXOPS) | |
| 970 | − luaX_error(ls, "expression too complex"); | |
| 971 | − s->ops[s->top++] = op; | |
| 972 | −} | |
| 973 | 597 | |
| 974 | 598 | |
| 975 | −static void pop_to (LexState *ls, stack_op *s, int prio) { | |
| 976 | − int op; | |
| 977 | − while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) { | |
| 978 | − code_opcode(ls, opcodes[op], op<FIRSTBIN?0:-1); | |
| 979 | − s->top--; | |
| 980 | − } | |
| 981 | −} | |
| 982 | 599 | |
| 983 | −static void simpleexp (LexState *ls, vardesc *v, stack_op *s) { | |
| 984 | − check_debugline(ls); | |
| 985 | − switch (ls->token) { | |
| 986 | − case NUMBER: { /* simpleexp -> NUMBER */ | |
| 987 | − real r = ls->seminfo.r; | |
| 600 | +/* | |
| 601 | +** {====================================================================== | |
| 602 | +** Expression parsing | |
| 603 | +** ======================================================================= | |
| 604 | +*/ | |
| 605 | + | |
| 606 | + | |
| 607 | +static void simpleexp (LexState *ls, expdesc *v) { | |
| 608 | + FuncState *fs = ls->fs; | |
| 609 | + switch (ls->t.token) { | |
| 610 | + case TK_NUMBER: { /* simpleexp -> NUMBER */ | |
| 611 | + Number r = ls->t.seminfo.r; | |
| 988 | 612 | next(ls); |
| 989 | − /* dirty trick: check whether it is a -NUMBER not followed by '^' */ | |
| 990 | − /* (because the priority of '^' is closer than '-'...) */ | |
| 991 | − if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') { | |
| 992 | − s->top--; /* remove '-' from stack */ | |
| 993 | − r = -r; | |
| 994 | − } | |
| 995 | − code_number(ls, r); | |
| 613 | + luaK_number(fs, r); | |
| 996 | 614 | break; |
| 997 | 615 | } |
| 998 | − | |
| 999 | − case STRING: /* simpleexp -> STRING */ | |
| 1000 | − code_string(ls, ls->seminfo.ts); /* must use 'seminfo' before "next" */ | |
| 616 | + case TK_STRING: { /* simpleexp -> STRING */ | |
| 617 | + code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ | |
| 1001 | 618 | next(ls); |
| 1002 | 619 | break; |
| 1003 | − | |
| 1004 | − case NIL: /* simpleexp -> NIL */ | |
| 1005 | − adjuststack(ls, -1); | |
| 620 | + } | |
| 621 | + case TK_NIL: { /* simpleexp -> NIL */ | |
| 622 | + luaK_adjuststack(fs, -1); | |
| 1006 | 623 | next(ls); |
| 1007 | 624 | break; |
| 1008 | − | |
| 1009 | − case '{': /* simpleexp -> constructor */ | |
| 625 | + } | |
| 626 | + case '{': { /* simpleexp -> constructor */ | |
| 1010 | 627 | constructor(ls); |
| 1011 | 628 | break; |
| 1012 | − | |
| 1013 | − case FUNCTION: /* simpleexp -> FUNCTION body */ | |
| 629 | + } | |
| 630 | + case TK_FUNCTION: { /* simpleexp -> FUNCTION body */ | |
| 1014 | 631 | next(ls); |
| 1015 | 632 | body(ls, 0, ls->linenumber); |
| 1016 | 633 | break; |
| 1017 | − | |
| 1018 | − case '(': /* simpleexp -> '(' exp0 ')' */ | |
| 634 | + } | |
| 635 | + case '(': { /* simpleexp -> '(' expr ')' */ | |
| 1019 | 636 | next(ls); |
| 1020 | − exp0(ls, v); | |
| 637 | + expr(ls, v); | |
| 1021 | 638 | check(ls, ')'); |
| 1022 | 639 | return; |
| 1023 | − | |
| 1024 | − case NAME: case '%': | |
| 640 | + } | |
| 641 | + case TK_NAME: case '%': { | |
| 1025 | 642 | var_or_func(ls, v); |
| 1026 | 643 | return; |
| 1027 | − | |
| 1028 | − default: | |
| 1029 | − luaX_error(ls, "<expression> expected"); | |
| 644 | + } | |
| 645 | + default: { | |
| 646 | + luaK_error(ls, "<expression> expected"); | |
| 1030 | 647 | return; |
| 648 | + } | |
| 1031 | 649 | } |
| 1032 | − v->k = VEXP; v->info = 0; | |
| 650 | + v->k = VEXP; | |
| 651 | + v->u.l.t = v->u.l.f = NO_JUMP; | |
| 1033 | 652 | } |
| 1034 | 653 | |
| 1035 | 654 | |
| 1036 | −static void prefixexp (LexState *ls, vardesc *v, stack_op *s) { | |
| 1037 | − /* prefixexp -> {NOT | '-'} simpleexp */ | |
| 1038 | − while (ls->token == NOT || ls->token == '-') { | |
| 1039 | − push(ls, s, (ls->token==NOT)?INDNOT:INDMINUS); | |
| 1040 | − next(ls); | |
| 1041 | − } | |
| 1042 | − simpleexp(ls, v, s); | |
| 655 | +static void exp1 (LexState *ls) { | |
| 656 | + expdesc v; | |
| 657 | + expr(ls, &v); | |
| 658 | + luaK_tostack(ls, &v, 1); | |
| 1043 | 659 | } |
| 1044 | 660 | |
| 1045 | 661 | |
| 1046 | −static void exp2 (LexState *ls, vardesc *v) { | |
| 1047 | − stack_op s; | |
| 1048 | − int op; | |
| 1049 | − s.top = 0; | |
| 1050 | − prefixexp(ls, v, &s); | |
| 1051 | − while ((op = is_in(ls->token, binop)) >= 0) { | |
| 1052 | − op += FIRSTBIN; | |
| 1053 | − lua_pushvar(ls, v); | |
| 1054 | − /* '^' is right associative, so must 'simulate' a higher priority */ | |
| 1055 | − pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); | |
| 1056 | − push(ls, &s, op); | |
| 1057 | − next(ls); | |
| 1058 | − prefixexp(ls, v, &s); | |
| 1059 | − lua_pushvar(ls, v); | |
| 1060 | − } | |
| 1061 | − if (s.top > 0) { | |
| 1062 | − lua_pushvar(ls, v); | |
| 1063 | − pop_to(ls, &s, 0); | |
| 662 | +static UnOpr getunopr (int op) { | |
| 663 | + switch (op) { | |
| 664 | + case TK_NOT: return OPR_NOT; | |
| 665 | + case '-': return OPR_MINUS; | |
| 666 | + default: return OPR_NOUNOPR; | |
| 1064 | 667 | } |
| 1065 | 668 | } |
| 1066 | 669 | |
| 1067 | 670 | |
| 1068 | −static void var_or_func (LexState *ls, vardesc *v) { | |
| 1069 | − /* var_or_func -> ['%'] NAME var_or_func_tail */ | |
| 1070 | − if (optional(ls, '%')) { /* upvalue? */ | |
| 1071 | − pushupvalue(ls, str_checkname(ls)); | |
| 1072 | − v->k = VEXP; | |
| 1073 | − v->info = 0; /* closed expression */ | |
| 671 | +static BinOpr getbinopr (int op) { | |
| 672 | + switch (op) { | |
| 673 | + case '+': return OPR_ADD; | |
| 674 | + case '-': return OPR_SUB; | |
| 675 | + case '*': return OPR_MULT; | |
| 676 | + case '/': return OPR_DIV; | |
| 677 | + case '^': return OPR_POW; | |
| 678 | + case TK_CONCAT: return OPR_CONCAT; | |
| 679 | + case TK_NE: return OPR_NE; | |
| 680 | + case TK_EQ: return OPR_EQ; | |
| 681 | + case '<': return OPR_LT; | |
| 682 | + case TK_LE: return OPR_LE; | |
| 683 | + case '>': return OPR_GT; | |
| 684 | + case TK_GE: return OPR_GE; | |
| 685 | + case TK_AND: return OPR_AND; | |
| 686 | + case TK_OR: return OPR_OR; | |
| 687 | + default: return OPR_NOBINOPR; | |
| 1074 | 688 | } |
| 1075 | − else /* variable name */ | |
| 1076 | − singlevar(ls, str_checkname(ls), v, 0); | |
| 1077 | − var_or_func_tail(ls, v); | |
| 1078 | 689 | } |
| 1079 | 690 | |
| 1080 | 691 | |
| 1081 | −static void var_or_func_tail (LexState *ls, vardesc *v) { | |
| 1082 | − for (;;) { | |
| 1083 | − switch (ls->token) { | |
| 1084 | − case '.': /* var_or_func_tail -> '.' NAME */ | |
| 1085 | − next(ls); | |
| 1086 | − lua_pushvar(ls, v); /* 'v' must be on stack */ | |
| 1087 | − v->k = VDOT; | |
| 1088 | − v->info = checkname(ls); | |
| 1089 | − break; | |
| 1090 | − | |
| 1091 | − case '[': /* var_or_func_tail -> '[' exp1 ']' */ | |
| 1092 | − next(ls); | |
| 1093 | − lua_pushvar(ls, v); /* 'v' must be on stack */ | |
| 1094 | − exp1(ls); | |
| 1095 | − check(ls, ']'); | |
| 1096 | − v->k = VINDEXED; | |
| 1097 | − break; | |
| 692 | +static const struct { | |
| 693 | + char left; /* left priority for each binary operator */ | |
| 694 | + char right; /* right priority */ | |
| 695 | +} priority[] = { /* ORDER OPR */ | |
| 696 | + {5, 5}, {5, 5}, {6, 6}, {6, 6}, /* arithmetic */ | |
| 697 | + {9, 8}, {4, 3}, /* power and concat (right associative) */ | |
| 698 | + {2, 2}, {2, 2}, /* equality */ | |
| 699 | + {2, 2}, {2, 2}, {2, 2}, {2, 2}, /* order */ | |
| 700 | + {1, 1}, {1, 1} /* logical */ | |
| 701 | +}; | |
| 1098 | 702 | |
| 1099 | − case ':': /* var_or_func_tail -> ':' NAME funcparams */ | |
| 1100 | − next(ls); | |
| 1101 | − lua_pushvar(ls, v); /* 'v' must be on stack */ | |
| 1102 | − code_oparg(ls, PUSHSELF, checkname(ls), 1); | |
| 1103 | − v->k = VEXP; | |
| 1104 | − v->info = funcparams(ls, 1); | |
| 1105 | − break; | |
| 703 | +#define UNARY_PRIORITY 7 /* priority for unary operators */ | |
| 1106 | 704 | |
| 1107 | − case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ | |
| 1108 | − lua_pushvar(ls, v); /* 'v' must be on stack */ | |
| 1109 | − v->k = VEXP; | |
| 1110 | − v->info = funcparams(ls, 0); | |
| 1111 | − break; | |
| 1112 | 705 | |
| 1113 | − default: return; /* should be follow... */ | |
| 1114 | − } | |
| 706 | +/* | |
| 707 | +** subexpr -> (simplexep | unop subexpr) { binop subexpr } | |
| 708 | +** where `binop' is any binary operator with a priority higher than `limit' | |
| 709 | +*/ | |
| 710 | +static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { | |
| 711 | + BinOpr op; | |
| 712 | + UnOpr uop = getunopr(ls->t.token); | |
| 713 | + if (uop != OPR_NOUNOPR) { | |
| 714 | + next(ls); | |
| 715 | + subexpr(ls, v, UNARY_PRIORITY); | |
| 716 | + luaK_prefix(ls, uop, v); | |
| 1115 | 717 | } |
| 718 | + else simpleexp(ls, v); | |
| 719 | + /* expand while operators have priorities higher than `limit' */ | |
| 720 | + op = getbinopr(ls->t.token); | |
| 721 | + while (op != OPR_NOBINOPR && priority[op].left > limit) { | |
| 722 | + expdesc v2; | |
| 723 | + BinOpr nextop; | |
| 724 | + next(ls); | |
| 725 | + luaK_infix(ls, op, v); | |
| 726 | + /* read sub-expression with higher priority */ | |
| 727 | + nextop = subexpr(ls, &v2, priority[op].right); | |
| 728 | + luaK_posfix(ls, op, v, &v2); | |
| 729 | + op = nextop; | |
| 730 | + } | |
| 731 | + return op; /* return first untreated operator */ | |
| 1116 | 732 | } |
| 1117 | 733 | |
| 1118 | −static int funcparams (LexState *ls, int slf) { | |
| 1119 | − FuncState *fs = ls->fs; | |
| 1120 | − int nparams = 1; /* in cases STRING and constructor */ | |
| 1121 | − switch (ls->token) { | |
| 1122 | − case '(': { /* funcparams -> '(' explist ')' */ | |
| 1123 | − int line = ls->linenumber; | |
| 1124 | − listdesc e; | |
| 1125 | − next(ls); | |
| 1126 | − explist(ls, &e); | |
| 1127 | − check_match(ls, ')', '(', line); | |
| 1128 | − close_exp(ls, e.pc, 1); | |
| 1129 | − nparams = e.n; | |
| 1130 | − break; | |
| 1131 | − } | |
| 1132 | 734 | |
| 1133 | − case '{': /* funcparams -> constructor */ | |
| 1134 | − constructor(ls); | |
| 1135 | − break; | |
| 735 | +static void expr (LexState *ls, expdesc *v) { | |
| 736 | + subexpr(ls, v, -1); | |
| 737 | +} | |
| 1136 | 738 | |
| 1137 | − case STRING: /* funcparams -> STRING */ | |
| 1138 | − code_string(ls, ls->seminfo.ts); /* must use 'seminfo' before "next" */ | |
| 1139 | − next(ls); | |
| 1140 | − break; | |
| 739 | +/* }==================================================================== */ | |
| 740 | + | |
| 741 | + | |
| 742 | +/* | |
| 743 | +** {====================================================================== | |
| 744 | +** Rules for Statements | |
| 745 | +** ======================================================================= | |
| 746 | +*/ | |
| 1141 | 747 | |
| 1142 | − default: | |
| 1143 | − luaX_error(ls, "function arguments expected"); | |
| 1144 | − break; | |
| 1145 | − } | |
| 1146 | − code_byte(fs, CALL); | |
| 1147 | − code_byte(fs, 0); /* save space for nresult */ | |
| 1148 | − code_byte(fs, (Byte)(nparams+slf)); | |
| 1149 | − return fs->pc-1; | |
| 1150 | −} | |
| 1151 | − | |
| 1152 | −static void explist (LexState *ls, listdesc *d) { | |
| 1153 | − switch (ls->token) { | |
| 1154 | − case ELSE: case ELSEIF: case END: case UNTIL: | |
| 1155 | − case EOS: case ';': case ')': | |
| 1156 | − d->pc = 0; | |
| 1157 | − d->n = 0; | |
| 1158 | − break; | |
| 1159 | 748 | |
| 1160 | − default: | |
| 1161 | − explist1(ls, d); | |
| 749 | +static int block_follow (int token) { | |
| 750 | + switch (token) { | |
| 751 | + case TK_ELSE: case TK_ELSEIF: case TK_END: | |
| 752 | + case TK_UNTIL: case TK_EOS: | |
| 753 | + return 1; | |
| 754 | + default: return 0; | |
| 1162 | 755 | } |
| 1163 | 756 | } |
| 1164 | 757 | |
| 1165 | −static void explist1 (LexState *ls, listdesc *d) { | |
| 1166 | − vardesc v; | |
| 1167 | − exp0(ls, &v); | |
| 1168 | − d->n = 1; | |
| 1169 | − while (ls->token == ',') { | |
| 1170 | − d->n++; | |
| 1171 | − lua_pushvar(ls, &v); | |
| 758 | + | |
| 759 | +static void block (LexState *ls) { | |
| 760 | + /* block -> chunk */ | |
| 761 | + FuncState *fs = ls->fs; | |
| 762 | + int nactloc = fs->nactloc; | |
| 763 | + chunk(ls); | |
| 764 | + luaK_adjuststack(fs, fs->nactloc - nactloc); /* remove local variables */ | |
| 765 | + removelocalvars(ls, fs->nactloc - nactloc); | |
| 766 | +} | |
| 767 | + | |
| 768 | + | |
| 769 | +static int assignment (LexState *ls, expdesc *v, int nvars) { | |
| 770 | + int left = 0; /* number of values left in the stack after assignment */ | |
| 771 | + luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); | |
| 772 | + if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ | |
| 773 | + expdesc nv; | |
| 1172 | 774 | next(ls); |
| 1173 | − exp0(ls, &v); | |
| 775 | + var_or_func(ls, &nv); | |
| 776 | + check_condition(ls, (nv.k != VEXP), "syntax error"); | |
| 777 | + left = assignment(ls, &nv, nvars+1); | |
| 778 | + } | |
| 779 | + else { /* assignment -> '=' explist1 */ | |
| 780 | + int nexps; | |
| 781 | + check(ls, '='); | |
| 782 | + nexps = explist1(ls); | |
| 783 | + adjust_mult_assign(ls, nvars, nexps); | |
| 1174 | 784 | } |
| 1175 | − if (v.k == VEXP) | |
| 1176 | − d->pc = v.info; | |
| 1177 | − else { | |
| 1178 | − lua_pushvar(ls, &v); | |
| 1179 | − d->pc = 0; | |
| 785 | + if (v->k != VINDEXED) | |
| 786 | + luaK_storevar(ls, v); | |
| 787 | + else { /* there may be garbage between table-index and value */ | |
| 788 | + luaK_code2(ls->fs, OP_SETTABLE, left+nvars+2, 1); | |
| 789 | + left += 2; | |
| 1180 | 790 | } |
| 791 | + return left; | |
| 1181 | 792 | } |
| 1182 | 793 | |
| 1183 | −static void parlist (LexState *ls) { | |
| 1184 | − int nparams = 0; | |
| 1185 | − int dots = 0; | |
| 1186 | − switch (ls->token) { | |
| 1187 | − case DOTS: /* parlist -> DOTS */ | |
| 1188 | − next(ls); | |
| 1189 | − dots = 1; | |
| 1190 | − break; | |
| 1191 | 794 | |
| 1192 | − case NAME: /* parlist, tailparlist -> NAME [',' tailparlist] */ | |
| 1193 | − init: | |
| 1194 | − store_localvar(ls, str_checkname(ls), nparams++); | |
| 1195 | − if (ls->token == ',') { | |
| 1196 | − next(ls); | |
| 1197 | − switch (ls->token) { | |
| 1198 | − case DOTS: /* tailparlist -> DOTS */ | |
| 1199 | − next(ls); | |
| 1200 | − dots = 1; | |
| 1201 | − break; | |
| 795 | +static void cond (LexState *ls, expdesc *v) { | |
| 796 | + /* cond -> exp */ | |
| 797 | + expr(ls, v); /* read condition */ | |
| 798 | + luaK_goiftrue(ls->fs, v, 0); | |
| 799 | +} | |
| 1202 | 800 | |
| 1203 | − case NAME: /* tailparlist -> NAME [',' tailparlist] */ | |
| 1204 | − goto init; | |
| 1205 | 801 | |
| 1206 | − default: luaX_error(ls, "NAME or `...' expected"); | |
| 1207 | − } | |
| 1208 | − } | |
| 1209 | − break; | |
| 802 | +static void whilestat (LexState *ls, int line) { | |
| 803 | + /* whilestat -> WHILE cond DO block END */ | |
| 804 | + FuncState *fs = ls->fs; | |
| 805 | + int while_init = luaK_getlabel(fs); | |
| 806 | + expdesc v; | |
| 807 | + Breaklabel bl; | |
| 808 | + enterbreak(fs, &bl); | |
| 809 | + next(ls); | |
| 810 | + cond(ls, &v); | |
| 811 | + check(ls, TK_DO); | |
| 812 | + block(ls); | |
| 813 | + luaK_patchlist(fs, luaK_jump(fs), while_init); | |
456 more lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 179 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 395 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 409 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 544 lines aren’t shown here.
This diff is large: its 341 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 404 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 225 lines aren’t shown here.
This diff is large: its 322 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 368 lines aren’t shown here.
This diff is large: its 288 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 254 lines aren’t shown here.
This diff is large: its 394 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 1184 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.