1
0
mirror of https://github.com/lua/lua synced 2026-06-08 15:34:49 +00:00

Compare commits

...

2580 Commits

Author SHA1 Message Date
Roberto Ierusalimschy 7fbbf1adc6 explicit macro to control use of _longjmp 2005-09-09 15:24:42 -03:00
Roberto Ierusalimschy 6dd3a73ca2 detail (macro evaluates twice its arguments) 2005-09-09 15:23:35 -03:00
Roberto Ierusalimschy 1e6a559b29 does not set isdst when undefined 2005-09-09 15:22:46 -03:00
Roberto Ierusalimschy 2d2f955763 detail 2005-09-09 15:16:28 -03:00
Roberto Ierusalimschy 669f6306be small corrections 2005-09-06 14:21:03 -03:00
Roberto Ierusalimschy 2bcbd3c725 avoid 'PathRemoveFileSpec' (not very portable) 2005-09-06 14:20:25 -03:00
Roberto Ierusalimschy 5fa6604f00 detail 2005-09-06 14:20:11 -03:00
Roberto Ierusalimschy ce67a9be31 avoid exporting undefined functions 2005-09-06 14:19:51 -03:00
Roberto Ierusalimschy 506c89cef8 just in case, flush all output 2005-09-06 14:19:33 -03:00
Roberto Ierusalimschy 8ead2ec358 wrong syntax for Windows-specific options 2005-09-02 16:53:25 -03:00
Roberto Ierusalimschy c3cc4de3fd small bug (zero is not error code) 2005-09-01 14:42:22 -03:00
Roberto Ierusalimschy 351f7dad6b default for 'module' is opaque (with option 'seeall') 2005-08-31 20:17:29 -03:00
Roberto Ierusalimschy 3b19af44b0 new method to handle tests without values (negative values) 2005-08-29 17:49:21 -03:00
Roberto Ierusalimschy 3390f9a35a detail 2005-08-26 14:36:32 -03:00
Roberto Ierusalimschy 9273fbd131 no more 'luaL_get/setfield' (replaced by more direct luaL_findtable) 2005-08-26 14:32:05 -03:00
Roberto Ierusalimschy be666a662b detail 2005-08-25 16:55:38 -03:00
Roberto Ierusalimschy 39cdbce23e no more '-w' option + new way to check module existence 2005-08-25 12:39:16 -03:00
Roberto Ierusalimschy 8974b59e40 no more compatibility for {;} and similar syntax 2005-08-24 14:41:10 -03:00
Roberto Ierusalimschy 4ff1e5b4e1 details 2005-08-24 14:06:36 -03:00
Roberto Ierusalimschy 98296f6b45 some bugs related to stack reallocation 2005-08-24 13:15:49 -03:00
Roberto Ierusalimschy 23b79c5945 small changes to facilitate external C coroutines 2005-08-22 16:58:29 -03:00
Roberto Ierusalimschy 6fcd334ca0 small improvements 2005-08-22 15:54:49 -03:00
Roberto Ierusalimschy 43ad0637ca small optimizations 2005-08-22 15:54:32 -03:00
Roberto Ierusalimschy 027e9e99ca simpler implementation for userdata types 2005-08-18 17:36:26 -03:00
Roberto Ierusalimschy 3b828d9e48 luaL_setfield does a non-raw set 2005-08-18 13:04:05 -03:00
Roberto Ierusalimschy 68548a02d3 fancier code ;) 2005-08-17 17:09:31 -03:00
Roberto Ierusalimschy 2f2b4a42a9 luaL_checkudata raises an error if value is not correct
(like other luaL_check functions)
2005-08-17 16:05:04 -03:00
Roberto Ierusalimschy 074352911f new coding for while and repeat (with new scoping for repeat) 2005-08-17 15:32:09 -03:00
Roberto Ierusalimschy 5e8a9e324c luaL_openlib -> luaL_register, luaL_putchar -> luaL_addchar 2005-08-15 11:12:32 -03:00
Roberto Ierusalimschy 16ddf86168 luaL_openlib -> luaL_register and new function luaL_loadstring 2005-08-15 11:12:32 -03:00
Roberto Ierusalimschy e4d369c9b7 comments 2005-08-12 10:34:15 -03:00
Roberto Ierusalimschy 42a662334a simpler implementation for unary minus 2005-08-10 17:20:13 -03:00
Roberto Ierusalimschy 39c0f391c6 detail 2005-08-10 15:47:09 -03:00
Roberto Ierusalimschy c7b4f44772 correct name to open package library 2005-08-10 15:06:58 -03:00
Roberto Ierusalimschy 44b19075c0 small changes (to easy integration with Coco) 2005-08-09 16:49:04 -03:00
Roberto Ierusalimschy ab3dfa5594 store some configuration information 2005-08-09 14:58:09 -03:00
Roberto Ierusalimschy 62f786e08c new version (and new copyright)... 2005-08-09 14:57:54 -03:00
Roberto Ierusalimschy bbfd28959d attempt to better control use of _longjmp 2005-08-09 14:57:29 -03:00
Roberto Ierusalimschy 894cd31c52 #string is primitive 2005-08-09 14:42:02 -03:00
Roberto Ierusalimschy f01a95d4a0 detail 2005-08-09 09:30:19 -03:00
Roberto Ierusalimschy 680fc88cc2 a small bug 2005-08-04 10:37:38 -03:00
Roberto Ierusalimschy d96f088a26 'lua_lock' and similars should be hard to use 2005-08-04 10:37:10 -03:00
Roberto Ierusalimschy d8be9a6326 small changes 2005-08-01 12:05:09 -03:00
Roberto Ierusalimschy 95f3eefa5b small optimization 2005-08-01 01:22:23 -03:00
Roberto Ierusalimschy e82bdb24f3 new loader for "all-in-one" C packages 2005-08-01 01:21:17 -03:00
Roberto Ierusalimschy 1a343814d8 details 2005-07-31 14:12:32 -03:00
Roberto Ierusalimschy 280f7becb8 "%0" stands for the whole pattern (in gsub) 2005-07-31 13:47:34 -03:00
Roberto Ierusalimschy d6ff5d9f46 searchpath is "private affair" of loadlib 2005-07-13 16:02:42 -03:00
Roberto Ierusalimschy a05190fa3b elimination of common code + better error message 2005-07-12 18:17:46 -03:00
Roberto Ierusalimschy a569099b70 no more path for loadfile + function lists sorted 2005-07-12 15:15:11 -03:00
Roberto Ierusalimschy 20131e54d3 no more "getc" when testing if file exists 2005-07-12 11:32:48 -03:00
Roberto Ierusalimschy 80ac5e83fd details (alphabetical order for list of functions) 2005-07-12 11:32:08 -03:00
Roberto Ierusalimschy 289b5dc67a details (function list in alphabetical order) 2005-07-11 20:58:35 -03:00
Roberto Ierusalimschy c2f065f405 detail 2005-07-11 15:48:02 -03:00
Roberto Ierusalimschy b261cd110f new macro for conversion double->int + small changes 2005-07-11 14:10:35 -03:00
Roberto Ierusalimschy e4324f54b9 ';;' in a path is replaced by default path + '!' (in Windows) is
replaced by executable's directory
2005-07-11 13:41:57 -03:00
Roberto Ierusalimschy 3d08aa591d details 2005-07-11 13:41:51 -03:00
Roberto Ierusalimschy 0f30d00c87 warnings from Visual C 2005-07-11 11:01:37 -03:00
Roberto Ierusalimschy e86dab2dae details 2005-07-11 11:01:28 -03:00
Roberto Ierusalimschy 64b57db377 new test function for conversion from num to int 2005-07-11 11:00:59 -03:00
Roberto Ierusalimschy 575637319e better recovery at panic 2005-07-11 11:00:31 -03:00
Roberto Ierusalimschy 87be01598b warnings Visual C 2005-07-11 10:59:03 -03:00
Roberto Ierusalimschy e84b11a494 avoid names starting with '_' 2005-07-09 10:22:34 -03:00
Roberto Ierusalimschy bbf2cea9a1 more "polite" way to change a thread's environment 2005-07-07 12:48:29 -03:00
Roberto Ierusalimschy b3f7a43019 lua_setfenv/lua_getfenv should also manipulate threads 2005-07-06 15:07:30 -03:00
Roberto Ierusalimschy 7f97ec286e parent modules are also imported toghether with the module itself 2005-07-05 16:29:03 -03:00
Roberto Ierusalimschy e82b41aac2 several small improvements 2005-07-05 11:31:45 -03:00
Roberto Ierusalimschy ee1edd5734 detail 2005-07-05 11:31:20 -03:00
Roberto Ierusalimschy 8efb44b5e0 changes in 'string.find' and 'string.gfind' (new 'string.match' and
'string.gmatch')
2005-07-05 11:30:38 -03:00
Roberto Ierusalimschy f7720bebe3 more precise way to check incomplete lines 2005-06-28 10:01:50 -03:00
Roberto Ierusalimschy 69cc0a12fe small bug 2005-06-28 10:01:31 -03:00
Roberto Ierusalimschy 2f0955b99b detail 2005-06-27 14:24:40 -03:00
Roberto Ierusalimschy 999d55d887 several updates 2005-06-13 18:20:28 -03:00
Roberto Ierusalimschy 1f9f97e3cf 'math.mod' -> 'math.fmod' 2005-06-13 18:20:14 -03:00
Roberto Ierusalimschy 34aac33c15 detail 2005-06-13 18:17:59 -03:00
Roberto Ierusalimschy 3c2cf9db67 some extra consistency checks 2005-06-13 11:39:19 -03:00
Roberto Ierusalimschy 0b71bfd6af syntax for length changed from '*' to '#' 2005-06-13 11:25:29 -03:00
Roberto Ierusalimschy 0d1685d751 bug: last tag is not the number of tags... 2005-06-13 11:19:00 -03:00
Roberto Ierusalimschy bf2b342ac1 better control for compatibility code for varargs 2005-06-13 11:15:54 -03:00
Roberto Ierusalimschy 5fa2bec1f0 bug: current line should work for call hook 2005-06-13 11:15:22 -03:00
Roberto Ierusalimschy 746a1d612b small bug (type error) 2005-06-07 15:53:45 -03:00
Roberto Ierusalimschy 3ad03b331d optional size for 'setvbuf' 2005-06-06 15:42:21 -03:00
Roberto Ierusalimschy 86add535d8 'popen' is back 2005-06-06 10:30:52 -03:00
Roberto Ierusalimschy d987cf1f81 new mark LUAI_DATA for extern data 2005-06-06 10:30:25 -03:00
Roberto Ierusalimschy eca9fa02d2 small improvement 2005-06-03 17:16:16 -03:00
Roberto Ierusalimschy e33d7bae45 __STRICT_ANSI__ -> LUA_ANSI (definition is independent of gcc) 2005-06-01 14:07:45 -03:00
Roberto Ierusalimschy d628795940 lua_objsize -> lua_objlen (more compatible with use of `len´ in other
places [opcode name, metamethod index, etc.])
2005-05-31 11:34:02 -03:00
Roberto Ierusalimschy 05348d834b better error message 2005-05-31 11:31:50 -03:00
Roberto Ierusalimschy 90de38bf1f warnings in VS .Net 2005-05-31 11:25:18 -03:00
Roberto Ierusalimschy e8a7ecb982 luaL_findstring -> luaL_checkoption 2005-05-25 10:21:26 -03:00
Roberto Ierusalimschy 38da9d568a better use defined/undefined as flag values for macros 2005-05-20 16:09:05 -03:00
Roberto Ierusalimschy f21e9c172f details 2005-05-20 12:53:42 -03:00
Roberto Ierusalimschy 67578ec51f several small details 2005-05-17 16:49:15 -03:00
Roberto Ierusalimschy c2bb9abcec better quotes for strings in error messages 2005-05-16 18:19:00 -03:00
Roberto Ierusalimschy da32450c3d new API function `lua_tolstring' 2005-05-16 16:21:11 -03:00
Roberto Ierusalimschy a2b78aad49 debug information for active lines 2005-05-16 15:45:15 -03:00
Roberto Ierusalimschy c6293a76cc LUA_DL_DLOPEN is for internal use; makefile should use LUA_USE_DLOPEN 2005-05-09 10:14:14 -03:00
Roberto Ierusalimschy 1ab2b93462 debug information for last line of a function definition 2005-05-05 17:47:02 -03:00
Roberto Ierusalimschy 6cf85dcc90 metatables for all types 2005-05-05 12:34:03 -03:00
Roberto Ierusalimschy 65f4a0f636 no more compatibility code for traversing tables 2005-05-04 17:42:28 -03:00
Roberto Ierusalimschy 12acca7bd8 comments 2005-05-04 13:36:23 -03:00
Roberto Ierusalimschy d5fd44d747 corrected definition of lua_number2int for Windows 2005-05-03 16:30:17 -03:00
Roberto Ierusalimschy b0abc2ca03 better control of local variables in luaV_execute 2005-05-03 16:01:17 -03:00
Roberto Ierusalimschy b320d37a80 better tests for correctness of `savedpc' 2005-05-03 16:01:17 -03:00
Roberto Ierusalimschy 9b8d136e1c `*' operator is primitive only for tables 2005-05-02 14:49:43 -03:00
Roberto Ierusalimschy 9832f6b186 small bug 2005-04-29 10:54:05 -03:00
Roberto Ierusalimschy 8e696dd14a detail 2005-04-29 10:53:59 -03:00
Roberto Ierusalimschy c3939f5786 comment 2005-04-29 09:43:47 -03:00
Roberto Ierusalimschy bcc4089a7d comment 2005-04-27 15:53:53 -03:00
Roberto Ierusalimschy cf5d1bdd76 nesting of long strings only in compatibility mode 2005-04-27 15:37:51 -03:00
Roberto Ierusalimschy 8718fda9b2 added LUAI_FUNC to functions not in the API 2005-04-25 16:24:10 -03:00
Roberto Ierusalimschy 8c3c3e7691 small bug for tail-recursive debugging 2005-04-14 10:30:47 -03:00
Roberto Ierusalimschy 04f657c7f8 new protocol to open standard libraries 2005-04-13 14:24:20 -03:00
Roberto Ierusalimschy 2873d4efff stack could overflow with too many command-line arguments 2005-04-11 15:01:35 -03:00
Roberto Ierusalimschy a7ea0c71e8 detail 2005-04-11 15:01:29 -03:00
Roberto Ierusalimschy b1957b1e8e detail for Windows (untested) 2005-04-07 10:52:45 -03:00
Roberto Ierusalimschy a17e1fe124 new organization using only one library 2005-04-07 10:52:19 -03:00
Roberto Ierusalimschy fabf5db237 C stack is the same for the parser and the interpreter, so depth
control should be unified in both parts.
2005-04-07 10:09:07 -03:00
Roberto Ierusalimschy de0bfe33b7 new definition for `lua_number2int' for Windows (not tested yet!) 2005-04-06 14:30:13 -03:00
Roberto Ierusalimschy 9768e2f681 detail 2005-04-05 12:57:59 -03:00
Roberto Ierusalimschy 71eb824036 details 2005-04-05 12:35:15 -03:00
Roberto Ierusalimschy 7b6c3b463e small optimizations 2005-04-05 10:41:29 -03:00
Roberto Ierusalimschy 0316308c0d removed dirt optimizations that gave small gains 2005-04-04 15:12:51 -03:00
Roberto Ierusalimschy 409ee99900 detail 2005-04-01 10:51:37 -03:00
Roberto Ierusalimschy 445eda7ead details 2005-03-30 16:50:29 -03:00
Roberto Ierusalimschy 092dc95b06 using require' to implement -l' 2005-03-29 13:47:48 -03:00
Roberto Ierusalimschy e6e543a534 better control for compatibility code 2005-03-29 13:20:48 -03:00
Roberto Ierusalimschy 1c9c886974 standard configuration should run out-of-the-box in "any" system 2005-03-29 11:30:16 -03:00
Roberto Ierusalimschy ade585bdf9 no more LUA_FIRSTINDEX 2005-03-28 14:17:53 -03:00
Roberto Ierusalimschy 04c41444e2 wrong comment corrected 2005-03-28 09:53:40 -03:00
Roberto Ierusalimschy 03fb3c39d4 change #ifdef' for #if defined' 2005-03-23 14:51:11 -03:00
Roberto Ierusalimschy 8af1ca02e0 LUA_USERCONFIG is no longer necessary 2005-03-23 14:50:49 -03:00
Roberto Ierusalimschy f1eb79fdf4 some line-edit facilities must free the line after its use 2005-03-22 13:55:35 -03:00
Roberto Ierusalimschy 408cb71795 avoid name conflict with some spurious included header files 2005-03-22 13:54:29 -03:00
Roberto Ierusalimschy 390256edf7 better name for GC pause 2005-03-22 13:04:29 -03:00
Roberto Ierusalimschy ad24cff0f1 lua_gc(STEP) returns whether collection cycle finished 2005-03-21 15:12:21 -03:00
Roberto Ierusalimschy 6d475731ca cleaner configuration for lua.c 2005-03-21 15:12:07 -03:00
Roberto Ierusalimschy f41fc0eb0e small bug: a GC step was not proportional to its "size" 2005-03-18 17:11:28 -03:00
Roberto Ierusalimschy d872090248 small errors in previous `ci' of luaconf.h. 2005-03-18 15:55:45 -03:00
Roberto Ierusalimschy fb0f95a2b7 call limit may be larger than shorts 2005-03-18 15:55:09 -03:00
Roberto Ierusalimschy d3a6d95b9a more cleaning on configurations 2005-03-18 15:02:04 -03:00
Roberto Ierusalimschy 47984a0cc2 internal definitions have prefix `luai_' 2005-03-18 15:01:37 -03:00
Roberto Ierusalimschy 086d6b09ce avoid name colision with `close' function 2005-03-18 15:01:14 -03:00
Roberto Ierusalimschy bfe2905618 avoid too much configuration options 2005-03-18 13:38:43 -03:00
Roberto Ierusalimschy 2cbd9eecfb try to avoid warnings 2005-03-18 13:38:02 -03:00
Roberto Ierusalimschy 4494094031 detail 2005-03-16 17:02:48 -03:00
Roberto Ierusalimschy 04bbd01171 new operation *t (for size of t) (may yet be removed...) 2005-03-16 13:59:21 -03:00
Roberto Ierusalimschy 9ffae705ee new "primitive" getn 2005-03-16 13:58:41 -03:00
Roberto Ierusalimschy 6bfef60e77 bug: rawset/rawget do not ignore extra arguments 2005-03-11 12:51:08 -03:00
Roberto Ierusalimschy 370d31a559 luac´ -> luai' (to avoid confusion with other luac stuff) 2005-03-09 13:28:07 -03:00
Roberto Ierusalimschy f8df21bd20 `luaconf.h´ exports all its definitions always (so all of them
must have a lua/LUA prefix).
2005-03-08 17:10:05 -03:00
Roberto Ierusalimschy d3902cfa81 entries `{[...] = ...}' need space too. 2005-03-08 15:16:45 -03:00
Roberto Ierusalimschy b5b230d95c fewer #include's in luaconf.h 2005-03-08 15:09:16 -03:00
Roberto Ierusalimschy 7d57ea70bc new mod' (%') operator 2005-03-08 15:00:16 -03:00
Roberto Ierusalimschy 2d5b923759 details 2005-03-08 10:37:55 -03:00
Roberto Ierusalimschy 192d185492 C module names may have an optional `l' prefix 2005-03-08 10:27:36 -03:00
Roberto Ierusalimschy e010ef8948 detail 2005-03-07 15:27:34 -03:00
Roberto Ierusalimschy 1e48b20ce0 loadlib' not global anymore (packaged inside package') 2005-03-07 15:07:34 -03:00
Roberto Ierusalimschy d1ed6e4c07 small bug: must use original (previous) base 2005-03-07 13:59:01 -03:00
Roberto Ierusalimschy b6a7983b65 USHRT_MAX may not fit in a (16-bit) int 2005-03-07 13:58:27 -03:00
Roberto Ierusalimschy 49f90ffdeb new functions (to complete math.h) 2005-03-04 15:57:03 -03:00
Roberto Ierusalimschy dcabf721f8 "coroutine.current" -> "running" (compatible with "running" status) 2005-02-28 14:24:41 -03:00
Roberto Ierusalimschy 5eeff89f32 comments 2005-02-28 12:59:11 -03:00
Roberto Ierusalimschy d6143b1d7b avoid access to undefined global variables 2005-02-28 12:58:48 -03:00
Roberto Ierusalimschy d55bb795fa details 2005-02-23 14:30:22 -03:00
Roberto Ierusalimschy d84cc9d2db small bug 2005-02-18 10:50:08 -02:00
Roberto Ierusalimschy 7d45a5f48f C functions and userdata also have environments 2005-02-18 10:40:02 -02:00
Roberto Ierusalimschy 73d7640244 more secure way to stop GC cycles during finalizers 2005-02-14 11:19:50 -02:00
Roberto Ierusalimschy a9af455b32 detail 2005-02-14 11:19:44 -02:00
Roberto Ierusalimschy 678d2fb2ac all collected userdata must go to the end of the list of finalizers 2005-02-11 18:03:35 -02:00
Roberto Ierusalimschy af39352632 LUA_PATH_SEP -> LUA_PATHSEP 2005-02-10 15:12:02 -02:00
Roberto Ierusalimschy 4df8800a01 cleaner way to free all objects 2005-02-10 11:25:02 -02:00
Roberto Ierusalimschy 0e60572606 values holded in open upvalues of suspended threads may be
incorrectly collected
2005-01-19 15:03:47 -02:00
Roberto Ierusalimschy 621ef9f767 better control over GC collors of upvalues 2005-01-19 13:54:26 -02:00
Roberto Ierusalimschy d89a56f869 small warning in C++ 2005-01-18 15:23:25 -02:00
Roberto Ierusalimschy 334ba8132b cleaner way to remark open upvalues 2005-01-18 15:18:09 -02:00
Roberto Ierusalimschy ac71a0891d detail 2005-01-17 21:50:55 -02:00
Roberto Ierusalimschy 8e346d875a auxiliar patch to monitor garbage collection 2005-01-14 12:21:16 -02:00
Roberto Ierusalimschy 5be517602e no more generational collector (and no more `noinc' mode) 2005-01-14 12:19:42 -02:00
Roberto Ierusalimschy d2bda8046c new implementation for loaders 2005-01-14 12:17:18 -02:00
Roberto Ierusalimschy a72fbf794d detail 2005-01-10 17:16:29 -02:00
Roberto Ierusalimschy 8ddfe3df29 macros for all arithmetic operations over lua_Numbers 2005-01-10 16:17:39 -02:00
Roberto Ierusalimschy 6eb68ba57a all function declarations surround name with parentheses 2005-01-10 15:31:50 -02:00
Roberto Ierusalimschy a27497aa03 debug.traceback' gets an optional initial level' parameter 2005-01-10 15:21:10 -02:00
Roberto Ierusalimschy 0480ea0886 gets `debug.traceback' current when error occurs 2005-01-10 15:21:10 -02:00
Roberto Ierusalimschy 162b66624d no more `lua_userinit' macro 2005-01-10 14:31:30 -02:00
Roberto Ierusalimschy e791f025c0 no more `_TRACEBACK' variable 2005-01-10 14:30:59 -02:00
Roberto Ierusalimschy f61d435a7d a^b calls `pow´ (from math.h) directly 2005-01-07 18:00:33 -02:00
Roberto Ierusalimschy 071b2ae0e1 details 2005-01-07 17:53:32 -02:00
Roberto Ierusalimschy e2498e079e change in hash algorithm so that it does not need empty slot
(tables can be 100% full)
2005-01-05 16:20:51 -02:00
Roberto Ierusalimschy 65726f3e2e cleaner interface to `ltable' 2005-01-04 13:55:12 -02:00
Roberto Ierusalimschy 9fe2d0266a better configuration for Windows 2005-01-04 10:46:04 -02:00
Roberto Ierusalimschy e22cdf7752 better error messages when require fails for C module 2004-12-29 16:56:34 -02:00
Roberto Ierusalimschy a5eb48a3e6 redesigned loadlib (Windows version not tested yet) 2004-12-27 13:58:15 -02:00
Roberto Ierusalimschy 49fe79e9fd small change 2004-12-27 13:58:15 -02:00
Roberto Ierusalimschy 96727c61b8 several improvements/corrections 2004-12-22 15:43:27 -02:00
Roberto Ierusalimschy d5ebc3ff6d small changes 2004-12-22 11:05:33 -02:00
Roberto Ierusalimschy 3d19aee78f `luac' may generate code without upvalue names 2004-12-20 13:50:00 -02:00
Roberto Ierusalimschy 4194de70e7 details 2004-12-20 11:47:29 -02:00
Roberto Ierusalimschy c6254dceff a different option for the GC 2004-12-13 10:15:11 -02:00
Roberto Ierusalimschy a56d889f72 corrections for `absent' implementation 2004-12-13 10:14:21 -02:00
Roberto Ierusalimschy 2ec4fc4295 simpler code for `print' 2004-12-07 16:31:34 -02:00
Roberto Ierusalimschy 70751dd27c details 2004-12-07 16:31:16 -02:00
Roberto Ierusalimschy 39a8082f50 more options for controling the GC 2004-12-06 15:53:42 -02:00
Roberto Ierusalimschy 531874f6ce better (correct?) way to handle `next' over removed keys 2004-12-04 16:10:22 -02:00
Roberto Ierusalimschy 61a888518f details 2004-12-03 18:54:12 -02:00
Roberto Ierusalimschy c78940f21a static names do not need `luaX_' prefix 2004-12-03 18:50:25 -02:00
Roberto Ierusalimschy 8b239eeba1 details 2004-12-03 18:44:19 -02:00
Roberto Ierusalimschy a5330b77f3 static names do not need `luaX_' prefix 2004-12-03 18:35:33 -02:00
Roberto Ierusalimschy e1c2fb6eed details 2004-12-02 10:59:10 -02:00
Roberto Ierusalimschy 12dacd3c0e added an `L' parameter to macros L_TRY & L_THROW (someone may need it). 2004-12-01 13:52:54 -02:00
Roberto Ierusalimschy 23b38176a7 `LUA_FIRSTINDEX' should not be configurable 2004-12-01 13:50:18 -02:00
Roberto Ierusalimschy 97e2dab1fb better control of overflows in size computations 2004-12-01 13:46:18 -02:00
Roberto Ierusalimschy 0ed8519127 detail 2004-12-01 13:46:06 -02:00
Roberto Ierusalimschy 0e002005b1 better names for `luaM_free...' macros 2004-11-24 17:20:21 -02:00
Roberto Ierusalimschy 1d99a7360b details 2004-11-24 17:16:03 -02:00
Roberto Ierusalimschy 2f82bf6fe9 better support for 64-bit machines 2004-11-24 16:55:56 -02:00
Roberto Ierusalimschy 087df82a61 detail 2004-11-24 16:55:42 -02:00
Roberto Ierusalimschy 10e48b9160 details 2004-11-19 14:59:08 -02:00
Roberto Ierusalimschy 6f1ea817f5 better control over memory-size overflows 2004-11-19 13:52:40 -02:00
Roberto Ierusalimschy cdcb236747 needs to include stdlib.h' to access getenv' 2004-11-19 13:52:12 -02:00
Roberto Ierusalimschy 9be5844713 first full implementation of new package system 2004-11-18 17:53:49 -02:00
Roberto Ierusalimschy 497f042fad detail 2004-11-17 10:02:41 -02:00
Roberto Ierusalimschy 2ed07ea8c1 towards "requiring" C libraries 2004-11-11 13:42:57 -02:00
Roberto Ierusalimschy cfd7bc478f better patch for buffer overflow error 2004-11-03 10:22:39 -02:00
Roberto Ierusalimschy 737ec947d3 better implementation for `floating-point bytes' 2004-11-01 12:06:50 -03:00
Roberto Ierusalimschy 45d566f676 small corrections (thanks to Mike Pall) 2004-11-01 11:33:33 -03:00
Roberto Ierusalimschy cfb79b1751 more secure way to compute final string length 2004-10-28 14:45:51 -03:00
Roberto Ierusalimschy 3e1a1f2836 better configuration for loadlib + tested Mac OS X version 2004-10-18 15:07:31 -03:00
Roberto Ierusalimschy b32e9a46d2 better configuration for loadlib 2004-10-18 15:07:31 -03:00
Roberto Ierusalimschy e5cfa7a367 use of parentheses around macro parameters in call lists, to avoid
problems with comma expressions
2004-10-18 09:51:44 -03:00
Roberto Ierusalimschy aae1612747 avoid name chash in `all.c' 2004-10-08 15:57:16 -03:00
Roberto Ierusalimschy 8050e75f9d bug: gc metamethod must disable GC steps (to avoid nested calls) 2004-10-08 13:00:34 -03:00
Roberto Ierusalimschy 3bec76abe3 first version of loadlib for Mac OS X (not tested yet!!) 2004-10-07 14:27:20 -03:00
Roberto Ierusalimschy 5cb6037d49 cannot jump to a setlist count 2004-10-07 14:27:00 -03:00
Roberto Ierusalimschy f1c2dd3aed detail 2004-10-06 15:34:47 -03:00
Roberto Ierusalimschy bd38017ddf small optimization for table size in machines with double allignment 2004-10-06 15:34:16 -03:00
Roberto Ierusalimschy 652f885c30 detail 2004-10-04 16:07:42 -03:00
Roberto Ierusalimschy f7e9465a0c new format for SETLIST opcode 2004-10-04 16:04:34 -03:00
Roberto Ierusalimschy 5ee87acd6b small optimization for boolean constants + new format for SETLIST opcode 2004-10-04 16:01:53 -03:00
Roberto Ierusalimschy 5d834bdf57 function constants may include boolean values 2004-10-04 16:01:12 -03:00
Roberto Ierusalimschy 67391a35da details 2004-09-29 18:03:42 -03:00
Roberto Ierusalimschy 36541dec9b towards new package system 2004-09-29 18:03:14 -03:00
Roberto Ierusalimschy cf2a194edc better API for luaL_getfield/setfield 2004-09-29 18:00:25 -03:00
Roberto Ierusalimschy 66845f415f small optimizations 2004-09-27 15:54:45 -03:00
Roberto Ierusalimschy b2820f39a2 long string delimiter changed from [*[' to [=[' 2004-09-22 11:02:00 -03:00
Roberto Ierusalimschy 8b5bb6056b removal of unused variable 2004-09-22 09:37:52 -03:00
Roberto Ierusalimschy 4973682294 small bug with coroutine tracebacks 2004-09-21 14:58:06 -03:00
Roberto Ierusalimschy 6acfb91c8d new auxiliary functions to implement new package system 2004-09-21 13:54:32 -03:00
Roberto Ierusalimschy 2419f2bf02 cleaner API for coroutines 2004-09-15 17:39:42 -03:00
Roberto Ierusalimschy 0e54d2be36 bug: barrier was wrong for generational phase 2004-09-15 17:38:15 -03:00
Roberto Ierusalimschy 226c57fec0 simpler configuration to turn on all asserts 2004-09-10 14:30:46 -03:00
Roberto Ierusalimschy 0de2065f4e tighter tests for stack overflow 2004-09-08 11:23:09 -03:00
Roberto Ierusalimschy ee165043ef two bugs related to varargs 2004-09-03 12:48:56 -03:00
Roberto Ierusalimschy 3c394b12f9 detail 2004-09-03 10:17:14 -03:00
Roberto Ierusalimschy 79fc7dea43 simpler implementation for generic reader 2004-09-03 10:16:48 -03:00
Roberto Ierusalimschy 9c34e23214 new libs loslib´ and linit´ 2004-09-01 10:49:20 -03:00
Roberto Ierusalimschy 2aba14b623 details 2004-09-01 10:47:31 -03:00
Roberto Ierusalimschy 1dd8c9b6b6 detail 2004-08-31 14:57:33 -03:00
Roberto Ierusalimschy 7d309480dd new way to handle _PATH (old LUA_PATH) 2004-08-30 15:35:14 -03:00
Roberto Ierusalimschy bcb2cb59ac select' returns all values after given n' 2004-08-30 12:28:32 -03:00
Roberto Ierusalimschy 0b06241483 better control for GC cycles 2004-08-30 10:44:44 -03:00
Roberto Ierusalimschy 857253cdfc detail 2004-08-30 10:44:04 -03:00
Roberto Ierusalimschy 5dcd908add detail 2004-08-26 11:19:55 -03:00
Roberto Ierusalimschy 32d4f304db first implementation of generational GC 2004-08-24 17:12:06 -03:00
Roberto Ierusalimschy 4b12eff801 small correction (less conservative write barrier for tables) 2004-08-24 17:09:11 -03:00
Roberto Ierusalimschy 271e05917f bug: lua_getupvalue and setupvalue do not check for index too small. 2004-08-17 14:45:45 -03:00
Roberto Ierusalimschy fe8c365281 default state (created by `luaL_newstate´) has a default panic function 2004-08-13 16:52:53 -03:00
Roberto Ierusalimschy 2d8b099274 better checking for read errors (with `ferror´) 2004-08-13 16:52:13 -03:00
Roberto Ierusalimschy ff4f8fe59a small bug: calls to upvalues were not correctly traced 2004-08-13 15:02:36 -03:00
Roberto Ierusalimschy a7c74c06b9 small bug: lua_gc(count) was falling through to next option 2004-08-12 14:02:51 -03:00
Roberto Ierusalimschy c7dda42c2f bug (due to new handling of varargs) 2004-08-12 11:19:51 -03:00
Roberto Ierusalimschy 26ae992129 less conservative write barrier for tables 2004-08-10 16:17:23 -03:00
Roberto Ierusalimschy f87057690b `io.lines' also can give the file name in its error message 2004-08-09 11:35:59 -03:00
Roberto Ierusalimschy 9e6aa878c9 string.byte truncates indices out of range 2004-08-09 10:30:33 -03:00
Roberto Ierusalimschy c0fdaf5842 string.byte may return multiple values 2004-08-06 14:35:38 -03:00
Roberto Ierusalimschy 2430d3cb28 small changes (due to Rici Lake) to allow testing non-supported OS functions 2004-08-05 16:30:37 -03:00
Roberto Ierusalimschy 6bddbbde7a details (opcode may not be the first field) 2004-08-04 17:18:13 -03:00
Roberto Ierusalimschy 31e48f26ed small bug 2004-07-16 10:30:53 -03:00
Roberto Ierusalimschy 0d9007b642 no more LUA_OPNAMES 2004-07-16 10:17:00 -03:00
Roberto Ierusalimschy 9609236fbb no more LUA_OPNAMES; it is simpler to "waste" 400 bytes 2004-07-16 10:15:32 -03:00
Roberto Ierusalimschy 942496d767 small bug 2004-07-13 17:11:32 -03:00
Roberto Ierusalimschy a535ad6fee several small changes (mainly function names) 2004-07-13 16:56:44 -03:00
Roberto Ierusalimschy 4206d7ed60 `lua_Chunkwriter' returns 0 in case of success 2004-07-09 15:24:41 -03:00
Roberto Ierusalimschy 7a796a0682 new macro `luaL_typename' 2004-07-09 15:23:17 -03:00
Roberto Ierusalimschy 76d8b8db06 lua_pushfstring' now supports %p' option too 2004-07-09 13:01:38 -03:00
Roberto Ierusalimschy ce455481ab separation between io lib and os lib 2004-07-09 12:47:48 -03:00
Roberto Ierusalimschy 85f1d70e68 OS lib (finally separated from io lib) 2004-07-09 12:47:48 -03:00
Roberto Ierusalimschy 31f6540fba back with an "open all libs" function 2004-07-09 11:29:29 -03:00
Roberto Ierusalimschy eab1965c05 bug: `lua_setfenv' needs a write barrier 2004-07-09 11:20:22 -03:00
Roberto Ierusalimschy 3d5187f6e5 require' uses its private reference to _LOADED' table 2004-07-02 15:09:11 -03:00
Roberto Ierusalimschy 80ec81926c `lua.c' also needs the default path, so auxlib should provide it 2004-07-01 11:26:28 -03:00
Roberto Ierusalimschy 96917ff42a "step" option in lua_gc also need to lock Lua. 2004-06-30 11:15:23 -03:00
Roberto Ierusalimschy a6179adf12 detail 2004-06-30 09:58:44 -03:00
Roberto Ierusalimschy 02a2c01ccd new way to code RK values 2004-06-29 15:49:02 -03:00
Roberto Ierusalimschy 23e08a68f5 detail 2004-06-29 14:05:00 -03:00
Roberto Ierusalimschy 0f5a497ed9 new interface for search-path function + small changes in require 2004-06-29 13:58:17 -03:00
Roberto Ierusalimschy 753625c3f3 new interface for search-path function 2004-06-29 13:57:56 -03:00
Roberto Ierusalimschy 42b74ccf1d libraries may want to use `lua_assert' too... 2004-06-23 12:57:29 -03:00
Roberto Ierusalimschy 0c49857c1a new scheme to search paths 2004-06-21 17:05:29 -03:00
Roberto Ierusalimschy 6b41e84da5 `assert' returns all its parameters (not only the first) 2004-06-21 13:45:09 -03:00
Roberto Ierusalimschy 359840c2f8 new coroutines inherit hook from creator 2004-06-17 11:25:31 -03:00
Roberto Ierusalimschy dba17070ac optional error for accesss to undefined variables/fields 2004-06-17 11:06:52 -03:00
Roberto Ierusalimschy 569eefbf73 detail 2004-06-16 17:22:43 -03:00
Roberto Ierusalimschy 5e4ea9a831 `setn' returns its "self" (the table) 2004-06-15 10:37:21 -03:00
Roberto Ierusalimschy 6311e3109f `setfenv' returns "self" 2004-06-15 10:31:30 -03:00
Roberto Ierusalimschy 9b854e6dbc BUG: string concatenation may cause arithmetic overflow, leading
to a buffer overflow.
2004-06-08 13:23:58 -03:00
Roberto Ierusalimschy 2b2d8ecd7a details 2004-06-08 11:31:15 -03:00
Roberto Ierusalimschy 75057dfced 2004-06-08 11:31:00 -03:00
Roberto Ierusalimschy 345379b5ff option for garbage-collector `step' 2004-06-04 12:30:53 -03:00
Roberto Ierusalimschy 118e471fa0 details 2004-06-02 16:09:36 -03:00
Roberto Ierusalimschy ba9878fcb8 lock stuff defined in `luaconf.h' 2004-06-02 16:09:21 -03:00
Roberto Ierusalimschy fa38421cea `testC' can operate on other states 2004-06-02 16:08:52 -03:00
Roberto Ierusalimschy e8d4fe7236 new macro lua_threadyield' + lock stuff in luaconf.h' + details 2004-06-02 16:07:55 -03:00
Roberto Ierusalimschy b8691f13a8 `getn' uses binary search if it has to count elements 2004-06-02 16:06:14 -03:00
Roberto Ierusalimschy f4718544de what is provided by lauxlib.c should be defined at lauxlib.h 2004-06-02 14:37:03 -03:00
Roberto Ierusalimschy 50f9cd201e no more `__fenv' 2004-06-02 11:20:08 -03:00
Roberto Ierusalimschy 9d8426bab4 better error messages for `loadfile' 2004-06-02 10:50:46 -03:00
Roberto Ierusalimschy 557f0009c4 clear definition for `lua_number2int' 2004-06-02 10:24:43 -03:00
Roberto Ierusalimschy 0dfd04eb60 lua_strlen' upgraded to lua_objsize' (which also works with userdata) 2004-05-31 16:41:52 -03:00
Roberto Ierusalimschy 1e0aaf2156 luaL_dofile' and luaL_dostring' are deprecated 2004-05-31 16:27:14 -03:00
Roberto Ierusalimschy 616438fe9a new way to use vararg' parameters (with ...') 2004-05-31 15:51:50 -03:00
Roberto Ierusalimschy 47eda6ebd8 main must return status from original main! 2004-05-31 15:50:48 -03:00
Roberto Ierusalimschy 0f49b3e62d new function `select' 2004-05-31 15:50:30 -03:00
Roberto Ierusalimschy 0733c83b8c other modules may need FILEHANDLE definition 2004-05-28 15:35:05 -03:00
Roberto Ierusalimschy e9844a4f1d `popen' is not ANSI and therefore was removed from the basic library 2004-05-28 15:32:51 -03:00
Roberto Ierusalimschy c61bb89dba details 2004-05-17 09:34:00 -03:00
Roberto Ierusalimschy 0bda88e6cd small steps towards yields in iterators and tag methods 2004-05-14 16:25:09 -03:00
Roberto Ierusalimschy 7966a4acae avoid name clashes among different files 2004-05-11 13:52:08 -03:00
Roberto Ierusalimschy 37cd986532 in time', uses default if isdst' is absent 2004-05-10 17:26:37 -03:00
Roberto Ierusalimschy a17dd24b34 no more USE_DEGREES option 2004-05-10 15:11:32 -03:00
Roberto Ierusalimschy b072e4ea0b tinsert' and tremove' also use LUA_FIRSTINDEX 2004-05-10 15:06:14 -03:00
Roberto Ierusalimschy 7e41612eb2 code parameterized by LUA_FIRSTINDEX (first index of an array) 2004-05-10 14:50:51 -03:00
Roberto Ierusalimschy b0f341ee52 LUAL_BUFFERSIZE is used in `lauxlib.h' and so everybody may need it 2004-05-10 10:58:26 -03:00
Roberto Ierusalimschy 1c459b881f accept `\r' as newline when looking for line end 2004-05-03 09:30:41 -03:00
Roberto Ierusalimschy 9629508a98 configuration file for Lua project 2004-05-03 09:28:43 -03:00
Roberto Ierusalimschy 763b8fba1b more stuff goes to configuration file 2004-05-03 09:28:43 -03:00
Roberto Ierusalimschy b4cd38ba6c new scheme for configuration through `luaconf.h' 2004-04-30 17:13:38 -03:00
Roberto Ierusalimschy 079facab40 ensures own top is corrected after calling function with multiple results 2004-04-05 11:43:17 -03:00
Roberto Ierusalimschy 4c5d7b2ddd small optimization for {f()} 2004-03-26 11:02:41 -03:00
Roberto Ierusalimschy d7cb622866 `unpack' has two optional arguments (to give a range) 2004-03-26 10:25:17 -03:00
Roberto Ierusalimschy 26a9b249db details 2004-03-24 12:46:49 -03:00
Roberto Ierusalimschy 227bddafe8 new copyright year 2004-03-24 10:55:46 -03:00
Roberto Ierusalimschy 5008e3d7d1 new states must use controlled malloc, too 2004-03-23 14:07:53 -03:00
Roberto Ierusalimschy 21bc05c920 write barrier for C upvalues 2004-03-23 14:07:34 -03:00
Roberto Ierusalimschy 29a13b4128 detail 2004-03-23 13:38:43 -03:00
Roberto Ierusalimschy ef8c0d7d90 better message for errors with upvalues 2004-03-23 10:10:16 -03:00
Roberto Ierusalimschy 178246062c reuse `sweeplist' for all lists 2004-03-23 09:57:12 -03:00
Roberto Ierusalimschy 24f2d1183c detail 2004-03-16 09:31:40 -03:00
Roberto Ierusalimschy 8e1f25e3f8 bug in `dofile' 2004-03-15 18:09:55 -03:00
Roberto Ierusalimschy 48a8d78102 new tests to check memory consistency (for incremental GC) 2004-03-15 18:04:54 -03:00
Roberto Ierusalimschy a4e1230f95 better way to control open upvalues 2004-03-15 18:04:33 -03:00
Roberto Ierusalimschy 9804467eeb detail 2004-03-13 10:32:09 -03:00
Roberto Ierusalimschy a003e89125 better error messages for some limits 2004-03-12 16:53:56 -03:00
Roberto Ierusalimschy b876ec61c0 new (temporary?) API for garbage collector 2004-03-09 14:34:35 -03:00
Roberto Ierusalimschy 898e8a6794 added include to stdarg.h (as it uses vararg facilities) 2004-02-20 13:01:05 -03:00
Roberto Ierusalimschy 1edea34666 details 2004-02-18 10:40:03 -03:00
Roberto Ierusalimschy 2aaf7394ad more and better tools (assertions & inspectors) to check incremental GC 2004-02-16 16:09:52 -03:00
Roberto Ierusalimschy b3ce450529 avoid calling `memcmp' with a NULL argument 2004-01-15 10:40:26 -02:00
Roberto Ierusalimschy 24434b59f7 '%' must be '%%' to avoid formatting problems 2004-01-02 09:54:14 -02:00
Roberto Ierusalimschy beb2aa5a46 atomic operations are not GC "states" 2003-12-12 16:29:34 -02:00
Roberto Ierusalimschy 47fc57a252 TObject' renamed to TValue' + other name changes and better assertions
for incremental garbage collection
2003-12-10 10:13:36 -02:00
Roberto Ierusalimschy 4d5fe1f54b detail 2003-12-10 09:04:54 -02:00
Roberto Ierusalimschy df429f163a First version of incremental GC 2003-12-09 14:56:11 -02:00
Roberto Ierusalimschy fe595a45c2 `grayagain' list 2003-12-04 16:52:23 -02:00
Roberto Ierusalimschy 9db1942bac sweep of strings also incremental 2003-12-04 15:22:42 -02:00
Roberto Ierusalimschy c6eac44a94 two different white flags (to distinguish dead elements from new ones) 2003-12-03 18:03:07 -02:00
Roberto Ierusalimschy 8878554b85 single list for all collectible objects, with udata separated at the
end of the list
2003-12-03 10:30:41 -02:00
Roberto Ierusalimschy af850484a9 default metatable can be NULL 2003-12-01 16:22:56 -02:00
Roberto Ierusalimschy 1d10acb355 incremental GC phases 2003-12-01 14:33:30 -02:00
Roberto Ierusalimschy da61624756 avoid overflow when doubling size 2003-11-27 16:18:37 -02:00
Roberto Ierusalimschy 8b97b072cd details 2003-11-27 16:05:14 -02:00
Roberto Ierusalimschy 5ee63257f9 macros for closure sizes are global 2003-11-24 16:50:36 -02:00
Roberto Ierusalimschy 8bc6c68021 details 2003-11-19 17:59:18 -02:00
Roberto Ierusalimschy 57b6ed6815 initial implementation of white/gray/black coloring 2003-11-19 17:41:57 -02:00
Roberto Ierusalimschy 9b9cdfee8b gclist for upvalues must be available even when upvalue is still open 2003-11-19 17:41:30 -02:00
Roberto Ierusalimschy 366e4af3c9 towards incremental GC 2003-11-18 12:55:11 -02:00
Roberto Ierusalimschy 53c7f86194 details 2003-11-18 08:44:53 -02:00
Roberto Ierusalimschy ab7d9bfd0c cleaner code for manipulation of `marked' field 2003-11-17 17:50:05 -02:00
Roberto Ierusalimschy 921b1723e2 comments 2003-11-11 14:34:17 -02:00
Roberto Ierusalimschy fa198197a0 lua_(set)getglobal are ok to use 2003-11-05 09:59:14 -02:00
Roberto Ierusalimschy 1e944de6cb towards a "stackless" call of metamethods (?) 2003-10-27 17:14:31 -02:00
Roberto Ierusalimschy 275c150b17 error()' (and error(nil)') generates errors with no error messages 2003-10-23 16:06:22 -02:00
Roberto Ierusalimschy d6d896b953 lua_set(get)global may use lua_set(get)field 2003-10-21 08:58:58 -02:00
Roberto Ierusalimschy 07201066bd core does not look for function name in globals (too particular) 2003-10-20 16:42:28 -02:00
Roberto Ierusalimschy 97b838d9ab new semantics for setn/getn (no more changes to `n') 2003-10-20 16:32:55 -02:00
Roberto Ierusalimschy c51bcf4796 it's ok to dump functions with upvalues 2003-10-20 15:42:41 -02:00
Roberto Ierusalimschy 03bab90303 new function `lua_getallocf' to retrieve allocation function and data 2003-10-20 10:25:23 -02:00
Roberto Ierusalimschy 8502331f69 `luaX_errorline' was used only in one place 2003-10-20 10:24:34 -02:00
Roberto Ierusalimschy 9914e1bcdd detail 2003-10-20 10:24:26 -02:00
Roberto Ierusalimschy 10de467c79 new function `lua_createtable' 2003-10-10 10:29:28 -03:00
Roberto Ierusalimschy 533737f26e new functions lua_getfield' and lua_setfield' 2003-10-10 09:57:55 -03:00
Roberto Ierusalimschy a41d60e1d1 debugger can only see `local function' after it has a meaningful value 2003-10-09 14:56:23 -03:00
Roberto Ierusalimschy f04fe526cd new functions `lua_tointeger' and lua_pushinteger' 2003-10-07 17:13:41 -03:00
Roberto Ierusalimschy 21947deddc new bug + correction in path for coroutine bug 2003-10-07 09:34:21 -03:00
Roberto Ierusalimschy 3087636c76 detail 2003-10-03 13:07:44 -03:00
Roberto Ierusalimschy 7b8504840f buffer should better use `size_t' for its size 2003-10-03 13:05:34 -03:00
Roberto Ierusalimschy 3a508b8bd7 avoid the use of `strlen' (strings are literals) 2003-10-03 13:04:24 -03:00
Roberto Ierusalimschy 6becdb3e70 details 2003-10-03 13:04:11 -03:00
Roberto Ierusalimschy b97fb932ec Lua kernel does not use malloc/free functions. 2003-10-02 17:31:17 -03:00
Roberto Ierusalimschy c7cf92e6f3 avoid unecessary includes of `stdlib' 2003-10-02 16:21:09 -03:00
Roberto Ierusalimschy a62d39aa1c detail: `luaL_where' does not use the name information 2003-10-01 13:50:53 -03:00
Roberto Ierusalimschy 5d4bf35ec9 bug: syntax `local function' does not increment stack size 2003-09-29 13:41:35 -03:00
Roberto Ierusalimschy 6063c5c61f bug: cannot invalidate a running coroutine 2003-09-05 11:30:59 -03:00
Roberto Ierusalimschy 2a70107581 detail 2003-09-05 11:00:27 -03:00
Roberto Ierusalimschy 7dae7899b1 main thread and global state are allocated in a single block 2003-09-04 17:19:07 -03:00
Roberto Ierusalimschy 30e51f09b9 some changes in error reporting 2003-09-04 17:00:28 -03:00
Roberto Ierusalimschy 994a37c8e8 IBM AS400 (OS400) has sizeof(void *)==16, and a `%p' may generate
up to 60 characters in a `printf'. That causes a buffer overflow in
`tostring'..
2003-08-29 13:50:02 -03:00
Roberto Ierusalimschy 0ff1596476 new form of long strings: `[***[...]***]' 2003-08-29 13:48:14 -03:00
Roberto Ierusalimschy b27664e0db simpler manipulation of buffer count in scanner 2003-08-28 11:38:46 -03:00
Roberto Ierusalimschy beb896b082 new function (generic) `load' 2003-08-27 18:02:08 -03:00
Roberto Ierusalimschy 8332d5c8a5 parser fully reentrant(!) 2003-08-27 18:01:44 -03:00
Roberto Ierusalimschy 885961be1d reader runs outside core Lua 2003-08-27 17:57:52 -03:00
Roberto Ierusalimschy b114142799 new auxiliary function `luaH_setstr' 2003-08-26 09:04:13 -03:00
Roberto Ierusalimschy 4b2e71ddb6 ZIO passes Lua state to chunk reader 2003-08-25 17:00:50 -03:00
Roberto Ierusalimschy 9fcc485176 zio does not keep "source" name (nobody uses it) 2003-08-25 16:51:54 -03:00
Roberto Ierusalimschy 64066359dd bug: IBM AS400 (OS400) has sizeof(void *)==16, and a `%p' may generate
up to 60 characters in a `printf'. That causes a buffer overflow in
`tostring'..
2003-08-25 16:49:47 -03:00
Roberto Ierusalimschy 97af24ea32 newlines can be \n', \r', \r\n', or \n\r' 2003-08-21 11:16:43 -03:00
Roberto Ierusalimschy 433cb1d13a no more checks for non-default compilation options + luaU_dump has
new option to strip debug info
2003-08-15 10:48:53 -03:00
Roberto Ierusalimschy d66198719d several bugs for Lua 5.0 + new format for bug entries 2003-07-29 16:27:46 -03:00
Roberto Ierusalimschy 91bf77534c no need for a maximum number of parameters (maximum number of locals
take care of that).
2003-07-29 16:26:34 -03:00
Roberto Ierusalimschy a0a384a6b1 bug: userdata to be collected still counts into new GC threshold,
increasing memory consumption
2003-07-29 16:25:37 -03:00
Roberto Ierusalimschy e89945aaa1 syntax ...=var' changed to var=...' 2003-07-29 15:51:00 -03:00
Roberto Ierusalimschy d407d3fe0e details 2003-07-28 15:31:20 -03:00
Roberto Ierusalimschy 522407e23a we do not need a default panic (that does nothing anyway...) 2003-07-16 17:51:47 -03:00
Roberto Ierusalimschy fa26d294ae new way to control `pc' of running functions 2003-07-16 17:49:02 -03:00
Roberto Ierusalimschy 5a761e3a15 opcode number may be invalid 2003-07-10 08:59:06 -03:00
Roberto Ierusalimschy 265530478b more changes to reduce stack usage by the parser 2003-07-09 17:11:30 -03:00
Roberto Ierusalimschy 00180bb133 small changes to reduce stack usage by the parser 2003-07-09 12:36:38 -03:00
Roberto Ierusalimschy 66ed154c89 details 2003-07-09 09:08:43 -03:00
Roberto Ierusalimschy f52f357a55 correct handling when a thread turns on line hooks in another thread 2003-07-07 10:37:56 -03:00
Roberto Ierusalimschy 79fee99024 `debug' library can operate over other threads 2003-07-07 10:37:08 -03:00
Roberto Ierusalimschy a73ded2153 Move nothing when there is nothing to move 2003-07-07 10:34:25 -03:00
Roberto Ierusalimschy 0ec4c473df bug: file:close cannot be called without a file. 2003-07-07 10:32:52 -03:00
Roberto Ierusalimschy 9e05503ffa bug: C functions also may have stacks larger than current top 2003-07-07 10:32:19 -03:00
Roberto Ierusalimschy 17f695157c define a `lua_isthread' for completeness 2003-07-07 10:30:57 -03:00
Roberto Ierusalimschy b93f67f2ce detail 2003-06-10 09:36:26 -03:00
Roberto Ierusalimschy 60aa01d8f7 fully-weak tables are more efficient 2003-05-16 15:59:08 -03:00
Roberto Ierusalimschy ecf5730c0c (much) smarter way to clear weak tables 2003-05-16 15:58:39 -03:00
Roberto Ierusalimschy b10bfd4934 comments 2003-05-15 16:46:03 -03:00
Roberto Ierusalimschy 176cd7d1a3 `#!' is detected by loadfile, not by the lexer 2003-05-15 09:20:24 -03:00
Roberto Ierusalimschy 859c7f7ce0 LUA_SIGNATURE is public 2003-05-15 09:20:04 -03:00
Roberto Ierusalimschy 56c5e749cc no more compatibility code (`lua_pushupvalues') 2003-05-14 18:10:07 -03:00
Roberto Ierusalimschy 9ec9a012e7 details 2003-05-14 18:09:53 -03:00
Roberto Ierusalimschy dae99205cf no more compatibility code 2003-05-14 18:06:56 -03:00
Roberto Ierusalimschy 9eb0f25a29 no more compatibility code for 4.0 2003-05-14 18:02:39 -03:00
Roberto Ierusalimschy f93051155c ok to use #elif' and #if defined()' 2003-05-14 18:01:53 -03:00
Roberto Ierusalimschy 524ae9fc3d new function `setvbuf' 2003-05-14 16:03:43 -03:00
Roberto Ierusalimschy 0ddedaee92 new function `string.reverse' 2003-05-14 11:35:54 -03:00
Roberto Ierusalimschy 5cc448386a new syntax: `... [= name]' 2003-05-14 09:32:46 -03:00
Roberto Ierusalimschy c116dcb92b better information about instruction behavior (use of arguments) 2003-05-14 09:09:12 -03:00
Roberto Ierusalimschy 6d268b0b00 new semantics for "for" local variables 2003-05-13 17:15:59 -03:00
Roberto Ierusalimschy c767747191 new (internal) macros for error handling 2003-05-13 16:22:19 -03:00
Roberto Ierusalimschy f966404ed6 simpler implementation for valid/acceptable indices 2003-05-09 17:16:54 -03:00
Roberto Ierusalimschy ee07ad346d `getn' doesn't need this field (values cannot be nil) 2003-05-07 13:02:16 -03:00
Roberto Ierusalimschy fee9e473f2 inlining of `luaV_gettable' were too complex (dirty) 2003-05-05 15:39:57 -03:00
Roberto Ierusalimschy 82dfacbcf7 detail 2003-04-30 17:24:38 -03:00
Roberto Ierusalimschy 26097b6c4b uses integers as keys to standard i/o files 2003-04-30 17:15:55 -03:00
Roberto Ierusalimschy f1f8f0ca22 simpler way to check maximum gc threshold 2003-04-28 16:58:06 -03:00
Roberto Ierusalimschy bcc5f1406b test function for lua_setgcthreshold 2003-04-28 16:58:06 -03:00
Roberto Ierusalimschy b1b752fb2b comments 2003-04-28 16:57:50 -03:00
Roberto Ierusalimschy 572a69df78 Lua does not need all those different types... 2003-04-28 16:26:16 -03:00
Roberto Ierusalimschy 943c82b376 avoid unnecessary call to log2 on too large indices 2003-04-28 10:31:46 -03:00
Roberto Ierusalimschy 17149b7d43 avoid warnings (Instruction' may not fit into an int') 2003-04-28 10:31:06 -03:00
Roberto Ierusalimschy 01b303c87e simpler log2 implementation 2003-04-28 10:30:14 -03:00
Roberto Ierusalimschy 762c737037 last changes by lhf 2003-04-10 14:39:41 -03:00
Roberto Ierusalimschy de57dc2653 new scheme to control `loadlib' configuration (default for dlopen
implementation is not to include it)
2003-04-07 17:11:53 -03:00
Roberto Ierusalimschy d1df829f8d lua_getmetatable must accept any acceptable index 2003-04-07 11:36:08 -03:00
Roberto Ierusalimschy 2ad947fe03 new test options for luaL_getn/setn 2003-04-07 11:35:00 -03:00
Roberto Ierusalimschy f0cc013afa luaL_getn/setn must operate correctly over negative indices 2003-04-07 11:35:00 -03:00
Roberto Ierusalimschy 0d88545b82 warnings from several compilers (mainly typecasts when lua_Number is float) 2003-04-03 10:35:34 -03:00
Roberto Ierusalimschy f84c5a5fc6 avoid conflicts in (re)definition of `isatty' 2003-04-03 10:34:42 -03:00
Roberto Ierusalimschy 05d35d8f3c comments 2003-04-02 10:09:14 -03:00
Roberto Ierusalimschy 3a6230ef7c error-message format 2003-04-01 14:52:31 -03:00
Roberto Ierusalimschy a424a112b5 clearance of debuging code (left by mistake) 2003-03-31 10:00:25 -03:00
Roberto Ierusalimschy b858161fbc new hash method for lua_Number (double) (due to a performance problem) 2003-03-24 11:18:42 -03:00
Roberto Ierusalimschy 80bac182db do not mix --help' with --' 2003-03-24 09:40:01 -03:00
Roberto Ierusalimschy 30a411ab3c chars from zio are always unsigned 2003-03-24 09:39:34 -03:00
Roberto Ierusalimschy 5bb5a1831d details 2003-03-20 17:26:33 -03:00
Roberto Ierusalimschy b518d14071 bug: zio mixes a 255 as first char in a buffer with EOZ 2003-03-20 13:00:56 -03:00
Roberto Ierusalimschy 15dbb53461 towards 5.0 final 2003-03-19 18:27:30 -03:00
Roberto Ierusalimschy abc304f9da avoid name colision (for alllua.c) 2003-03-19 18:24:04 -03:00
Roberto Ierusalimschy 1a553f9199 better error messages 2003-03-19 18:16:12 -03:00
Roberto Ierusalimschy 0ca225d33a better error message 2003-03-19 18:15:18 -03:00
Roberto Ierusalimschy 70e2b7ab86 name changes to avoid name collision between macros and variables 2003-03-19 18:14:53 -03:00
Roberto Ierusalimschy 5a144e891a __globals' -> __fenv' 2003-03-19 18:14:34 -03:00
Roberto Ierusalimschy b12776f29c `luaL_getmetafield' was leaving extra value on the stack 2003-03-18 15:48:31 -03:00
Roberto Ierusalimschy ab9e062928 name changes to avoid name collision between macros and variables 2003-03-18 09:50:04 -03:00
Roberto Ierusalimschy 81cdbabf09 detail (change place of a prototype) 2003-03-18 09:31:39 -03:00
Roberto Ierusalimschy 40cfb0691e new auxiliary functions for `type' manipulation 2003-03-18 09:25:32 -03:00
Roberto Ierusalimschy 9b7af7e45b tests for Windows version 2003-03-18 09:25:01 -03:00
Roberto Ierusalimschy 2e66248f8a unused argument 2003-03-18 09:24:38 -03:00
Roberto Ierusalimschy 79db75101e detail 2003-03-18 09:24:26 -03:00
Roberto Ierusalimschy b0c40e2405 first version of `loadlib' 2003-03-17 10:04:58 -03:00
Roberto Ierusalimschy 4734e2de05 `loadlib' now an official library 2003-03-17 10:01:48 -03:00
Roberto Ierusalimschy 7ea180af6e detail 2003-03-14 16:08:11 -03:00
Roberto Ierusalimschy 05d567d52e io.input'/io.output' always return current file 2003-03-14 16:00:16 -03:00
Roberto Ierusalimschy d8a3a00d84 `string.find' also accepts out-of-range indices 2003-03-14 15:59:53 -03:00
Roberto Ierusalimschy c9ea94ec92 out-of-bound upvalues (in C) are acceptable indices 2003-03-14 15:59:21 -03:00
Roberto Ierusalimschy fa4b4c1100 loadstring/loadfile use global environment + setfenv(0) changes
global environment
2003-03-11 15:17:43 -03:00
Roberto Ierusalimschy 4039bf457d ^ operator is defined by global `__pow' 2003-03-11 09:30:37 -03:00
Roberto Ierusalimschy 034de1fe73 new names for functions that open C libraries 2003-03-11 09:24:34 -03:00
Roberto Ierusalimschy 430d6db928 LUA_PATH components may have multiple interrogation marks 2003-03-11 09:08:13 -03:00
Roberto Ierusalimschy 7c3857cded comments 2003-03-07 10:21:31 -03:00
Roberto Ierusalimschy 8ce6f0b418 avoid including system headers after program headers 2003-03-06 16:37:42 -03:00
Roberto Ierusalimschy 572bddc0b0 LUA_USETMPNAME -> USE_TMPNAME 2003-03-06 16:36:44 -03:00
Roberto Ierusalimschy 3684f67771 details (text of an error message) 2003-03-06 16:36:16 -03:00
Roberto Ierusalimschy 69dd9461e5 bug: GC metamethod calls could mess C/Lua stack syncronization 2003-02-28 16:45:15 -03:00
Roberto Ierusalimschy 6b6bc532a4 better error message for (deprecated) "%global" 2003-02-28 14:19:47 -03:00
Roberto Ierusalimschy ea16ee41a8 no more attempt to optimize GC when parsing new modules (too complex) 2003-02-28 12:42:08 -03:00
Roberto Ierusalimschy 60d11ec316 by default, gcc does not get tmpname 2003-02-27 09:39:05 -03:00
Roberto Ierusalimschy e1a424e8a3 avoid the identifier index' (clashes with BSD index' function) 2003-02-27 09:33:07 -03:00
Roberto Ierusalimschy 59ce42dbd5 detail 2003-02-27 09:32:30 -03:00
Roberto Ierusalimschy 92f6e0c1bf no-nonsense debug information about tail calls 2003-02-27 08:52:30 -03:00
Roberto Ierusalimschy 5cd99b82b7 set/getenvtable' -> set/getfenv' 2003-02-24 13:54:20 -03:00
Roberto Ierusalimschy 07e210e655 `require' returns value returned by package 2003-02-24 13:50:41 -03:00
Roberto Ierusalimschy feb724c122 ULONG_MAX>>10 may not fit into an int (old bug) 2003-02-21 16:00:14 -03:00
Roberto Ierusalimschy 67f9a2a98f details 2003-02-20 17:12:39 -03:00
Roberto Ierusalimschy c4f9c887fc expressions too complex for an ARM compiler... 2003-02-19 07:28:58 -03:00
Roberto Ierusalimschy 9866fb0ef1 set/getglobals' -> set/getenvtable' 2003-02-18 13:13:15 -03:00
Roberto Ierusalimschy 60c83ded30 small optimization for sizes of array constructors 2003-02-18 13:02:56 -03:00
Roberto Ierusalimschy 07948c3181 restore _REQUIREDNAME after requiring a file 2003-02-18 13:02:13 -03:00
Roberto Ierusalimschy dce9a49a08 final version 2003-02-18 13:01:57 -03:00
Roberto Ierusalimschy 15db58a2f5 create arg table with correct size 2003-02-13 14:08:47 -02:00
Roberto Ierusalimschy d6826dbc80 simpler way to count uses 2003-02-13 14:08:32 -02:00
Roberto Ierusalimschy e75a6ae9ee `defaultmeta' is always empty, but registry needs some space for
names and numbers (references)
2003-02-13 14:07:57 -02:00
Roberto Ierusalimschy 2866fb2dd0 reset _REQUIREDNAME after loading module 2003-02-13 14:07:37 -02:00
Roberto Ierusalimschy 4b6f436d67 unpack' uses getn' to get table size 2003-02-12 07:11:01 -02:00
Roberto Ierusalimschy 8f105d6b59 string.byte returns nil if index is out-of-range 2003-02-12 07:10:41 -02:00
Roberto Ierusalimschy 2fef8c772b auxiliary function to check userdata with types 2003-02-11 13:32:31 -02:00
Roberto Ierusalimschy 7285fa393b use C names for C types 2003-02-11 13:31:50 -02:00
Roberto Ierusalimschy 5085f09ce5 small optimizations 2003-02-11 13:24:52 -02:00
Roberto Ierusalimschy d674626392 compatibility with '%' syntax is optional 2003-02-11 08:49:53 -02:00
Roberto Ierusalimschy 7a40cdbda0 different variables for number of upvalues and size of upvalue array
(makes code clearer)
2003-02-11 08:46:24 -02:00
Roberto Ierusalimschy 3cdeacbbfb reference system also uses getn/setn (plus small corrections) 2003-02-11 07:44:38 -02:00
Roberto Ierusalimschy 6f207b15fb resist errors in finalizers during lua_close 2003-02-10 15:32:50 -02:00
Roberto Ierusalimschy 3184314bf3 warning 2003-02-10 15:31:13 -02:00
Roberto Ierusalimschy 7964f7cbbd more complete information for coroutine errors 2003-02-10 08:21:31 -02:00
Roberto Ierusalimschy 383a6e88f9 argv[0] may be NULL 2003-01-29 11:23:45 -02:00
Roberto Ierusalimschy 871166d7db test for panic function 2003-01-29 08:27:53 -02:00
Roberto Ierusalimschy 592cf2334e "panic" cannot happen in lua.c, with lua_cpcall +
argv[0] may be empty
2003-01-29 08:27:07 -02:00
Roberto Ierusalimschy 0175f8d5d1 dump/undump of upvalue names 2003-01-27 13:52:57 -02:00
Roberto Ierusalimschy e79bf02f33 correct semantics for comparison metamethods (they are only valid
when both operands have the same metamethod).
2003-01-27 13:12:52 -02:00
Roberto Ierusalimschy 41ed3c4771 getn/setn in C moved to lauxlib 2003-01-27 11:46:16 -02:00
Roberto Ierusalimschy 635b7c707d details 2003-01-27 11:00:43 -02:00
Roberto Ierusalimschy 83f0d6ef1a DEPRECATED (new manual uses an independent format instead of LaTeX) 2003-01-24 14:38:18 -02:00
Roberto Ierusalimschy 3088ebd95b last changes before leaving Latex 2003-01-24 07:14:54 -02:00
Roberto Ierusalimschy 797d964df9 detail 2003-01-23 09:34:18 -02:00
Roberto Ierusalimschy e44e579dc1 bug: luaD_protectedparser must protect its garbage collection too 2003-01-23 09:31:38 -02:00
Roberto Ierusalimschy a153cafd8d starting translation to new format (@comand{...}). 2003-01-22 14:29:38 -02:00
Roberto Ierusalimschy 3b5158f2a1 corrections from Asko Kauppi 2003-01-21 15:45:11 -02:00
Roberto Ierusalimschy 60a8b94fd0 corrections/suggestions by Ed Ferguson 2003-01-20 09:03:05 -02:00
Roberto Ierusalimschy c499442e5f compatibility macros must be available by default 2003-01-17 13:28:09 -02:00
Roberto Ierusalimschy 9a5bab82ff use the more modern _POSIX_C_SOURCE instead of older _POSIX_SOURCE 2003-01-17 13:27:28 -02:00
Roberto Ierusalimschy 32fd039bb5 `openlib' functions return new module 2002-12-20 08:26:33 -02:00
Roberto Ierusalimschy 75f73172c4 bug: `resume' was checking the wrong value for stack overflow 2002-12-20 07:55:56 -02:00
Roberto Ierusalimschy 754c630754 details 2002-12-19 11:21:08 -02:00
Roberto Ierusalimschy dd8edecae1 new functions to manipulate upvales (get/setupvalue) 2002-12-19 09:11:55 -02:00
Roberto Ierusalimschy 28021c5c66 better explanation (+ example) for coroutines 2002-12-11 11:43:15 -02:00
Roberto Ierusalimschy 73517e86b0 OP_TFORLOOP uses extra stack space 2002-12-11 10:34:22 -02:00
Roberto Ierusalimschy 9e8face8d8 must move call results in the last iteration, too 2002-12-11 10:34:22 -02:00
Roberto Ierusalimschy 64864f094b new options for debugging Lua (HARDSTACKTESTS & EXTERNMEMCHECK) 2002-12-06 15:20:45 -02:00
Roberto Ierusalimschy 9bd3fc1039 TFORLOOP makes a call that affects all values above it on the stack 2002-12-06 15:15:35 -02:00
Roberto Ierusalimschy cc4a22ebe2 bug: scope of generic for variables is not sound 2002-12-06 15:09:00 -02:00
Roberto Ierusalimschy acf62ddfbe "load*" creates chunk with same global table than caller 2002-12-06 15:05:15 -02:00
Roberto Ierusalimschy 04f95ce879 hook counts are integers now 2002-12-05 15:50:10 -02:00
Roberto Ierusalimschy 27c6b4d422 each .c file defines its own name 2002-12-04 15:38:31 -02:00
Roberto Ierusalimschy 0bb8eb5151 new function `lua_cpcall' 2002-12-04 15:29:32 -02:00
Roberto Ierusalimschy 38da8c0d7d new facilities to test memory overflow in main.c 2002-12-04 15:29:05 -02:00
Roberto Ierusalimschy 76de732745 avoid non-raw accesses to globals when variable may not exist 2002-12-04 13:38:25 -02:00
Roberto Ierusalimschy 90d7892007 new function `io.type' 2002-12-04 13:27:17 -02:00
Roberto Ierusalimschy 041cb96992 small bug: `write' must return three values in case of errors 2002-12-04 13:17:36 -02:00
Roberto Ierusalimschy c75c3cfd19 avoid names `str...' (may conflict with string.h) 2002-12-02 10:06:10 -02:00
Roberto Ierusalimschy 24471525d7 details 2002-12-02 10:06:10 -02:00
Roberto Ierusalimschy 1f55dbc699 details 2002-11-26 10:53:29 -02:00
Roberto Ierusalimschy c194a46bc5 detail 2002-11-26 06:59:48 -02:00
Roberto Ierusalimschy 8954bdc706 new `coroutine.status' function 2002-11-26 06:45:36 -02:00
Roberto Ierusalimschy 5a228bb1d8 new function `lua_version' 2002-11-25 15:50:14 -02:00
Roberto Ierusalimschy 5f698f8b6f simpler interface to hooks + use of `int' to count hooks 2002-11-25 15:47:13 -02:00
Roberto Ierusalimschy 9b1c586b2f renaming stringdump' -> string.dump' 2002-11-25 15:33:33 -02:00
Roberto Ierusalimschy d9340154ac `__tostring' for files + small bug (could do invalid read inside
a userdata when it was not a file)
2002-11-25 13:05:39 -02:00
Roberto Ierusalimschy e47baca75a warnings from Visual C++ 2002-11-25 10:38:47 -02:00
Roberto Ierusalimschy b8a680c114 resets hook count even in case of errors 2002-11-25 09:20:29 -02:00
Roberto Ierusalimschy 709b27b456 ULONG_MAX>>10 may not fit into an int 2002-11-25 09:16:48 -02:00
Roberto Ierusalimschy dbc5451bea comments 2002-11-22 16:01:46 -02:00
Roberto Ierusalimschy 2d2d45976c separated control over C recursion level 2002-11-22 15:16:52 -02:00
Roberto Ierusalimschy 0050d983fc make more clear "primitive" recursive definitions 2002-11-22 14:42:53 -02:00
Roberto Ierusalimschy 04b143ddf9 avoid C stack overflow during parsing 2002-11-22 14:35:20 -02:00
Roberto Ierusalimschy 007f229568 detail 2002-11-22 11:59:04 -02:00
Roberto Ierusalimschy 84488c5670 small bug: previous call may change `base' 2002-11-21 15:19:42 -02:00
Roberto Ierusalimschy 5142e630bf new macro `condhardstacktests' to control hard stack tests 2002-11-21 15:19:11 -02:00
Roberto Ierusalimschy 010bbd9d9c simpler definition for incr_top 2002-11-21 14:46:16 -02:00
Roberto Ierusalimschy be00cd2a6b easier way to keep `base' correct 2002-11-21 13:46:44 -02:00
Roberto Ierusalimschy 2e4e888de0 Lua functions must have a frame or a saved pc. 2002-11-21 13:46:20 -02:00
Roberto Ierusalimschy ddc144e4d2 keep L->ci->base in L->base for faster access 2002-11-21 13:16:04 -02:00
Roberto Ierusalimschy b48c6e7680 no problem keeping some dead meat while doing collection 2002-11-21 12:18:01 -02:00
Roberto Ierusalimschy aff97fffc4 C functions cannot increase its top without filling the stack 2002-11-21 12:17:15 -02:00
Roberto Ierusalimschy 1648674653 must check GC every time it can create new objects 2002-11-21 12:16:52 -02:00
Roberto Ierusalimschy d404f0c276 global_State must be deallocated (and so allocated) with NULL also
(otherwise it trys to decrement inside itself after its own free)
2002-11-21 12:14:42 -02:00
Roberto Ierusalimschy 48e42261ac details 2002-11-19 15:42:32 -02:00
Roberto Ierusalimschy be762f38bd better organization of "malloc responsabilities" 2002-11-19 12:12:13 -02:00
Roberto Ierusalimschy c8a79057f7 option -l does a require', instead of dofile' 2002-11-19 11:49:43 -02:00
Roberto Ierusalimschy 642af82e81 small bugs (state could keep its CI_HASFRAME attribute after returning) 2002-11-19 06:50:56 -02:00
Roberto Ierusalimschy 636c629e56 new assertions 2002-11-18 16:45:38 -02:00
Roberto Ierusalimschy 96ba5d0bc2 include file name in error messages 2002-11-18 14:53:19 -02:00
Roberto Ierusalimschy f0185f7628 support for tests of yield inside hooks + better support for tests
with valgrind and other memory checkers
2002-11-18 13:24:27 -02:00
Roberto Ierusalimschy 9bab2cf55d support for yield inside hooks 2002-11-18 13:24:11 -02:00
Roberto Ierusalimschy c4ae00a3d1 details 2002-11-18 13:23:43 -02:00
Roberto Ierusalimschy f4d3bc52f4 towards 5.0 beta 2002-11-18 12:39:34 -02:00
Roberto Ierusalimschy 18765d900e messages 2002-11-18 09:20:01 -02:00
Roberto Ierusalimschy 43013b39cc new representation for hooks (to allow asynchronous calls to sethook) 2002-11-18 09:01:55 -02:00
Roberto Ierusalimschy 94912d99fc details 2002-11-14 14:59:16 -02:00
Roberto Ierusalimschy b40c9f7a3c better code to signal write barriers 2002-11-14 14:16:21 -02:00
Roberto Ierusalimschy 41fd639cab documentation for write barriers 2002-11-14 14:15:53 -02:00
Roberto Ierusalimschy a845a46cc8 C function may leave garbage on the stack (besides return values) 2002-11-14 13:42:05 -02:00
Roberto Ierusalimschy 097edd3884 better names for auxiliar functions 2002-11-14 13:41:38 -02:00
Roberto Ierusalimschy 5c5d9b2703 back to `__mode' metafield to specify weakness 2002-11-14 10:01:35 -02:00
Roberto Ierusalimschy 43d1a6af12 detail 2002-11-14 09:51:23 -02:00
Roberto Ierusalimschy 3010eb0536 all objects with several children (tables, closures, stacks, prototypes)
go to `gray' queue
2002-11-13 09:49:19 -02:00
Roberto Ierusalimschy 2f91f95d94 better control over GCObjects 2002-11-13 09:32:26 -02:00
Roberto Ierusalimschy 42dd080a2e details 2002-11-12 12:34:18 -02:00
Roberto Ierusalimschy 9957f7d598 better way to open libraries 2002-11-11 11:28:06 -02:00
Roberto Ierusalimschy ac27b7a842 avoid traversing extra elements when cleaning weak tables 2002-11-11 09:52:43 -02:00
Roberto Ierusalimschy 81e142fc14 detail (`key' is always on stack) 2002-11-07 14:03:33 -02:00
Roberto Ierusalimschy 63633c5b5f better name for `lua_movethread' 2002-11-07 13:39:23 -02:00
Roberto Ierusalimschy dff9be4224 new macros to distinguish different types of object moves (for future GC
evolution).
2002-11-07 13:37:10 -02:00
Roberto Ierusalimschy 118347d8c3 new API for coroutines 2002-11-06 17:08:00 -02:00
Roberto Ierusalimschy 6820da5096 detail 2002-11-04 10:31:44 -02:00
Roberto Ierusalimschy c3eb4675b9 new module, ldump.c 2002-10-25 18:38:17 -03:00
Roberto Ierusalimschy 7e0f880bc5 C++ demands cast from void to specific types 2002-10-25 18:36:54 -03:00
Roberto Ierusalimschy 118e9cd843 new facility for dumping chunks 2002-10-25 18:31:28 -03:00
Roberto Ierusalimschy de00d0d0ad module for dumping chunks 2002-10-25 18:31:28 -03:00
Roberto Ierusalimschy 1713b64065 Writer type must be public (so, in lua.h) 2002-10-25 18:30:49 -03:00
Roberto Ierusalimschy 671dc6eec2 new version (from lhf) 2002-10-25 18:30:41 -03:00
Roberto Ierusalimschy e356a43dc0 C needs "union" (unlike C++) 2002-10-25 18:30:00 -03:00
Roberto Ierusalimschy f36038e42a assertion must be always valid (not only in debug mode) 2002-10-25 18:29:20 -03:00
Roberto Ierusalimschy 96e15b8501 threads now are real Lua objects, subject to garbage collection 2002-10-25 17:05:28 -03:00
Roberto Ierusalimschy 0fd91b1b08 optional limits for table.concat 2002-10-23 16:08:23 -03:00
Roberto Ierusalimschy a2b353e044 details 2002-10-23 16:08:13 -03:00
Roberto Ierusalimschy 92a2ef9dca field `__globals' protect global tables 2002-10-22 16:41:08 -03:00
Roberto Ierusalimschy 4fb9110a6e tests for compatibility functions lua_dostring/lua_dofile 2002-10-22 15:07:55 -03:00
Roberto Ierusalimschy 11886dc7b0 print error on stderr when _ALERT is not defined 2002-10-22 15:07:55 -03:00
Roberto Ierusalimschy 81bc5711a8 only one instance of registry and default metatable per global state 2002-10-22 14:58:14 -03:00
Roberto Ierusalimschy 6a77a6b73f avoid too much precision when printing numbers 2002-10-22 14:21:25 -03:00
Roberto Ierusalimschy 84e0b1bc97 small changes in type configuration facilities 2002-10-22 14:18:28 -03:00
Roberto Ierusalimschy 6823a2f57f better tokens for error messages 2002-10-22 13:45:52 -03:00
Roberto Ierusalimschy 313b2fe902 detail 2002-10-21 17:43:38 -03:00
Roberto Ierusalimschy 425e5813b0 free prototype in (more or less) the same order it is created by
`undump'
2002-10-21 17:41:46 -03:00
Roberto Ierusalimschy 6505503b49 do not pretend that file is closed when close fails 2002-10-21 17:41:24 -03:00
Roberto Ierusalimschy ec748fcb0a correct handling of opened files in presence of memory allocation
errors
2002-10-16 17:41:35 -03:00
Roberto Ierusalimschy c196348717 in case of memory allocation errors, sizecode and sizelineinfo can
be different
2002-10-16 17:40:58 -03:00
Roberto Ierusalimschy 669129a6d8 io.lines() iterate over the standard input file 2002-10-11 17:40:32 -03:00
Roberto Ierusalimschy 46b063ef59 `undump' also uses private buffer 2002-10-09 10:42:01 -03:00
Roberto Ierusalimschy e1d5153a33 details 2002-10-09 10:00:08 -03:00
Roberto Ierusalimschy b3d0682fb9 use of different buffers for scanner and concatenation 2002-10-08 15:46:08 -03:00
Roberto Ierusalimschy 02afc892d5 new ANSI C does not assure that realloc(p,0) == free(p) 2002-10-08 15:45:07 -03:00
Roberto Ierusalimschy fa2f1ec7ba to avoid `strerror', define itself to something else;
nil has a special, fixed reference
2002-10-04 11:31:40 -03:00
Roberto Ierusalimschy 829befcc41 small optimization for object comparison 2002-10-04 11:31:03 -03:00
Roberto Ierusalimschy d477e4ffd6 detail 2002-10-04 11:30:31 -03:00
Roberto Ierusalimschy ce09af1e25 easier to define api_check' using assert' 2002-09-20 14:01:24 -03:00
Roberto Ierusalimschy 98d0b79613 EXIT_SUCCESS may be different from 0 2002-09-20 10:32:56 -03:00
Roberto Ierusalimschy e8f35fc4ff unification of __index & __gettable (and __newindex & __settable) 2002-09-19 17:12:47 -03:00
Roberto Ierusalimschy 6fb0fd5063 avoid `reclearing' weak tables 2002-09-19 16:54:22 -03:00
Roberto Ierusalimschy 565e6d74e1 state's buffer is used only for chars 2002-09-19 10:03:53 -03:00
Roberto Ierusalimschy f6bc7884be new generators for reading a file line by line 2002-09-17 17:35:54 -03:00
Roberto Ierusalimschy 32a5d96dfc `setmetatable' cannot change protected objects 2002-09-16 16:49:45 -03:00
Roberto Ierusalimschy 8dae071f42 details 2002-09-16 16:18:01 -03:00
Roberto Ierusalimschy afe1305b1a avoid luaS_resize (which may need extra memory) during `main' activities 2002-09-05 16:57:40 -03:00
Roberto Ierusalimschy 728fa167d2 cannot raise memory error when realloc to smaller block 2002-09-05 16:57:08 -03:00
Roberto Ierusalimschy 1bdde38bd2 no more newlines at the end of error messages 2002-09-05 16:45:42 -03:00
Roberto Ierusalimschy b2bc3b44b6 no more reserved word "global" 2002-09-03 08:57:38 -03:00
Roberto Ierusalimschy 7c0ccdfd61 avoid the use of "enum" in the API, as they do not have a fixed representation 2002-09-02 17:00:41 -03:00
Roberto Ierusalimschy 4964e7c8a0 details 2002-09-02 16:54:49 -03:00
Roberto Ierusalimschy 2c670baf24 avoid the use of "obvious" names in header files to avoid conflicts 2002-08-30 17:00:59 -03:00
Roberto Ierusalimschy fdafd4f4a8 new structure for collectable objects, sharing a common header 2002-08-30 16:09:21 -03:00
Roberto Ierusalimschy beeff4ccaf GC metamethod stored in a weak metatable being collected together with
userdata may not be cleared properly
2002-08-30 16:08:30 -03:00
Roberto Ierusalimschy 12c4e48506 `frontier' patterns 2002-08-23 16:45:24 -03:00
Roberto Ierusalimschy c78aaa9a70 better line number for function definitions 2002-08-22 16:51:08 -03:00
Roberto Ierusalimschy 4d7a554921 style for switch statements 2002-08-21 16:39:31 -03:00
Roberto Ierusalimschy fbc23d0245 details 2002-08-21 15:56:33 -03:00
Roberto Ierusalimschy 81a8845e4f detail 2002-08-21 11:57:48 -03:00
Roberto Ierusalimschy 6c283b2f4f new simetric format for ABC instructions, to avoid exchanging operands
for `commutative' operators
2002-08-20 17:03:05 -03:00
Roberto Ierusalimschy 576bded513 details 2002-08-16 17:02:13 -03:00
Roberto Ierusalimschy ecc7769de2 names... 2002-08-16 17:00:28 -03:00
Roberto Ierusalimschy da19c436cc cleaning the stage for generational collection 2002-08-16 11:45:55 -03:00
Roberto Ierusalimschy 0039feb9da warning from Visual C 2002-08-16 11:45:18 -03:00
Roberto Ierusalimschy aa5b15f271 detail 2002-08-14 17:10:33 -03:00
Roberto Ierusalimschy 653416d5c0 angles in radians(!) 2002-08-14 17:07:43 -03:00
Roberto Ierusalimschy 82a3be0671 some corrections + angles in radians 2002-08-14 17:07:25 -03:00
Roberto Ierusalimschy 94b5ad31f4 details 2002-08-13 17:00:51 -03:00
Roberto Ierusalimschy 90d26b9266 update of `debug' library (Lua binding) 2002-08-13 16:44:47 -03:00
Roberto Ierusalimschy a048d71ef3 new LUA_USERCONFIG to include user options 2002-08-13 12:04:59 -03:00
Roberto Ierusalimschy 27f8a4a69e towards 5.0 (one more step)... 2002-08-12 14:43:35 -03:00
Roberto Ierusalimschy 8e4ac679ff use a linear count for count hook 2002-08-12 14:23:12 -03:00
Roberto Ierusalimschy 221b5be7b7 use of `LoadState' struct (instead of several separate arguments) 2002-08-12 10:37:19 -03:00
Roberto Ierusalimschy b6791f5fa5 details 2002-08-12 10:37:19 -03:00
Roberto Ierusalimschy 3b058177af towards 5.0 alpha... 2002-08-09 18:03:19 -03:00
Roberto Ierusalimschy 586e510577 details 2002-08-08 17:08:41 -03:00
Roberto Ierusalimschy 9998082839 external messages add their own extra information 2002-08-08 17:08:41 -03:00
Roberto Ierusalimschy 08da48a73c detail 2002-08-07 17:55:00 -03:00
Roberto Ierusalimschy 00a40f4d6a ensure proper rounding 2002-08-07 17:54:38 -03:00
Roberto Ierusalimschy 3bb5079dd4 ensure fixed order for library initialization 2002-08-07 17:54:17 -03:00
Roberto Ierusalimschy 5016f43aa4 (much) cleaner way to control function states 2002-08-07 16:22:39 -03:00
Roberto Ierusalimschy c1c100a0c0 warnings in other compilers 2002-08-07 11:35:55 -03:00
Roberto Ierusalimschy b6e2f1a86e small bugs when stack is reallocated 2002-08-07 11:24:24 -03:00
Roberto Ierusalimschy 260e35f576 the usual... 2002-08-06 16:12:54 -03:00
Roberto Ierusalimschy a56e01a9a0 towards 5.0 alpha... 2002-08-06 16:10:44 -03:00
Roberto Ierusalimschy 4664f2e927 any Lua closure has a table of globals (not only active functions) 2002-08-06 15:54:18 -03:00
Roberto Ierusalimschy 2e38c6ae5a luadebug.h' content now is included in lua.h' 2002-08-06 15:01:50 -03:00
Roberto Ierusalimschy d3dd337fca lua_Chunkreader gets a lua_State, to avoid future incompatibilities 2002-08-06 14:26:45 -03:00
Roberto Ierusalimschy 634344d61f new API for weak mode 2002-08-06 14:06:56 -03:00
Roberto Ierusalimschy a2fa48a570 new (old?) error handling scheme 2002-08-06 12:32:22 -03:00
Roberto Ierusalimschy 8b2b8790b5 small bug: basic `ci' must have a valid func (base - 1) 2002-08-05 15:45:45 -03:00
Roberto Ierusalimschy 0b3d380f9f internal names 2002-08-05 15:45:02 -03:00
Roberto Ierusalimschy 4e23699aa6 new implementation for error handling 2002-08-05 14:36:24 -03:00
Roberto Ierusalimschy 1c0ac3c0f5 new implementation for tailcall 2002-08-05 14:35:45 -03:00
Roberto Ierusalimschy 4a4f243795 new API for error handling 2002-08-05 11:51:47 -03:00
Roberto Ierusalimschy 0417a4bb0b new implementation for tailcalls and error handling 2002-08-05 11:51:21 -03:00
Roberto Ierusalimschy 5037196f6f new macros `ttis*' 2002-08-05 11:50:39 -03:00
Roberto Ierusalimschy 9fb80bde3c tailcall is executed together with call 2002-08-05 11:46:43 -03:00
Roberto Ierusalimschy 2dcc31574f new function xpcall 2002-08-05 11:46:02 -03:00
Roberto Ierusalimschy 390fc99a5c xpcall now is builtin + new macros `ttis*' 2002-08-05 11:10:10 -03:00
Roberto Ierusalimschy 79c8edb6c4 new names for light userdata operations 2002-07-17 13:25:13 -03:00
Roberto Ierusalimschy e5146fb01f CallInfo has different fields for C functions and Lua functions 2002-07-16 11:26:56 -03:00
Roberto Ierusalimschy ce6b930464 `isdst' should be a boolean (and not 0/1!!) 2002-07-12 15:54:53 -03:00
Roberto Ierusalimschy ac7006d374 ^D in interactive mode finish interaction (no questions asked) 2002-07-10 17:49:01 -03:00
Roberto Ierusalimschy 12bee999dd new way to handle macros read_line/save_line 2002-07-10 17:44:34 -03:00
Roberto Ierusalimschy a8c9eec426 bug: chunk can end just after a '\' in a string 2002-07-10 17:43:53 -03:00
Roberto Ierusalimschy a885b826b3 LUA_ALERT is no longer used 2002-07-09 15:49:13 -03:00
Roberto Ierusalimschy a960e62c3e new options; no more _ALERT; no more getargs 2002-07-09 15:19:44 -03:00
Roberto Ierusalimschy c51aa6ee33 details 2002-07-09 15:19:19 -03:00
Roberto Ierusalimschy d88860131a new macro `lua_isudataval' (for completude) 2002-07-09 11:58:28 -03:00
Roberto Ierusalimschy 44752fc9ce hook count is quadratic 2002-07-08 17:22:08 -03:00
Roberto Ierusalimschy 39b2d58c39 new interface for debug hooks 2002-07-08 15:21:33 -03:00
Roberto Ierusalimschy d2d24f0971 details to allow compilation of Lua as a single file 2002-07-08 15:14:36 -03:00
Roberto Ierusalimschy 0436c96866 C++ warning 2002-07-08 13:51:20 -03:00
Roberto Ierusalimschy f8279f6cd8 optimizations for gettable (temporary) 2002-07-05 15:27:39 -03:00
Roberto Ierusalimschy 1fe280df72 new priority for and/or 2002-07-04 15:23:42 -03:00
Roberto Ierusalimschy 1ede98157d strings are always `strong' in weaktables 2002-07-04 14:58:02 -03:00
Roberto Ierusalimschy 3e52573c72 details (error messages) 2002-07-04 09:29:32 -03:00
Roberto Ierusalimschy 84ad1eea81 use of NaN as key breaks some invariants 2002-07-02 14:54:23 -03:00
Roberto Ierusalimschy b30ec2532c details 2002-07-02 13:43:28 -03:00
Roberto Ierusalimschy 68ee518e81 only tables need `lua_number2int' 2002-07-01 16:31:10 -03:00
Roberto Ierusalimschy 76a73cb2ee new getn' (and setn') 2002-07-01 16:25:28 -03:00
Roberto Ierusalimschy aa3da1605c `newproxy' uses its own weaktable 2002-07-01 16:23:58 -03:00
Roberto Ierusalimschy 9f4b5b5232 weak keys are removed only after finalization 2002-07-01 14:06:58 -03:00
Roberto Ierusalimschy 5fabed21a1 getglobals(0) is the C global table 2002-06-26 17:36:17 -03:00
Roberto Ierusalimschy f67ccfbdeb no more `lua_getn' function 2002-06-26 16:28:44 -03:00
Roberto Ierusalimschy cfcf200806 concat' goes to table' library 2002-06-26 16:28:08 -03:00
Roberto Ierusalimschy f32a8c0477 details (temporary?) 2002-06-26 13:37:39 -03:00
Roberto Ierusalimschy 88607acc2c details 2002-06-26 13:37:23 -03:00
Roberto Ierusalimschy 6de93e2932 two new bugs in 4.0 :-( (both were already corrected in 5.0 :-) 2002-06-25 16:23:55 -03:00
Roberto Ierusalimschy 25dc9b7faf new functions dofile' and pairs'; correct way to check proxies 2002-06-25 16:19:33 -03:00
Roberto Ierusalimschy 78c507b7b8 lua_upcall' -> lua_call' 2002-06-25 16:18:49 -03:00
Roberto Ierusalimschy 69906cb56f error message ends with `\n' (is already formatted) 2002-06-25 16:18:20 -03:00
Roberto Ierusalimschy 9d6556fd87 userdata are removed from weaktables before invoking their GC fallbacks 2002-06-25 16:17:42 -03:00
Roberto Ierusalimschy 35707e94f3 __weakmode' -> __mode' 2002-06-25 16:17:22 -03:00
Roberto Ierusalimschy 89b102bd1d new `luaL_weakregistry' function 2002-06-25 16:15:21 -03:00
Roberto Ierusalimschy fdfd5b44ee TM_GETTABLE/TM_SETTABLE don't need fast access anymore 2002-06-24 17:18:38 -03:00
Roberto Ierusalimschy 1a4c428d6d new function `newproxy' 2002-06-24 14:23:16 -03:00
Roberto Ierusalimschy 2394604d10 assertion may fail when closing a state 2002-06-24 14:19:43 -03:00
Roberto Ierusalimschy 922f36a05b details 2002-06-24 12:07:21 -03:00
Roberto Ierusalimschy ad41fc11eb details in arithmetic implementation 2002-06-24 11:11:14 -03:00
Roberto Ierusalimschy e182cf452f `^' operator is defined in registry.__pow 2002-06-24 10:54:13 -03:00
Roberto Ierusalimschy e34f282365 `luaV_gettable' returns element position 2002-06-24 10:08:45 -03:00
Roberto Ierusalimschy 3941af53ad first implementation of independent global table per function 2002-06-20 17:41:46 -03:00
Roberto Ierusalimschy 5610fdd776 avoid using obsolete lua_dostring 2002-06-20 17:40:38 -03:00
Roberto Ierusalimschy b449a5e574 more robust when printing error messages 2002-06-20 17:40:09 -03:00
Roberto Ierusalimschy e572dffa15 small bug building error messages 2002-06-20 17:39:44 -03:00
Roberto Ierusalimschy 5893fcb71a accept option arguments without spaces (e.g. "-eprint(a)") 2002-06-18 14:43:49 -03:00
Roberto Ierusalimschy eec0905173 better tests (assertions) for debug hooks 2002-06-18 14:42:52 -03:00
Roberto Ierusalimschy a44f37513b better treatment for error messages 2002-06-18 14:12:05 -03:00
Roberto Ierusalimschy 6ee2dbdfe9 traceback stops at first protected call 2002-06-18 14:10:43 -03:00
Roberto Ierusalimschy 1dbe708aa8 new protocol for error handling 2002-06-18 12:19:27 -03:00
Roberto Ierusalimschy 8f080fd683 `traceback' returns only the traceback 2002-06-18 12:17:58 -03:00
Roberto Ierusalimschy d8678edddc luaL_verror -> luaL_error 2002-06-18 12:16:18 -03:00
Roberto Ierusalimschy e812aa2002 avoid assignments to TObject access macros 2002-06-17 10:51:01 -03:00
Roberto Ierusalimschy c31494df26 avoid gotos when possible 2002-06-14 14:21:32 -03:00
Roberto Ierusalimschy 8fd0f6a82b new macro to check conditions on expression macros 2002-06-13 10:45:31 -03:00
Roberto Ierusalimschy eb3de8768a rawcall' -> upcall' (unprotected call) 2002-06-13 10:44:50 -03:00
Roberto Ierusalimschy 864c96f36c new fallback for equality `__eq' 2002-06-13 10:39:55 -03:00
Roberto Ierusalimschy 0052930ffe details 2002-06-12 16:16:00 -03:00
Roberto Ierusalimschy eeab473fc8 new fallback __le (less equal), for partial order 2002-06-12 11:56:22 -03:00
Roberto Ierusalimschy 6b8cdc9cdd Lua now uses only `realloc' for all its memory management 2002-06-11 13:26:12 -03:00
Roberto Ierusalimschy 000d081fd0 warnings from other compilers 2002-06-06 15:17:33 -03:00
Roberto Ierusalimschy 65d66ba275 new "local function" 2002-06-06 14:29:53 -03:00
Roberto Ierusalimschy cff22f57dd some refactoring 2002-06-06 10:52:37 -03:00
Roberto Ierusalimschy 168ea16acb details 2002-06-06 10:16:02 -03:00
Roberto Ierusalimschy dc6e6c48bb on the way to 5.0 2002-06-06 09:49:28 -03:00
Roberto Ierusalimschy e3cddc950c C is not C++... 2002-06-06 09:43:08 -03:00
Roberto Ierusalimschy 630acb2048 _ERRORMESSAGE `accepts' non-string arguments (at least for now...) 2002-06-06 09:40:36 -03:00
Roberto Ierusalimschy 16f4723398 names & names 2002-06-06 09:40:22 -03:00
Roberto Ierusalimschy f1c43bbe19 new function `xpcall' (at least for now...) 2002-06-06 09:39:48 -03:00
Roberto Ierusalimschy 5a8f383e60 io.close() closes standard output file; `close' now is method 2002-06-05 14:42:03 -03:00
Roberto Ierusalimschy 711b936849 new versions from lhf 2002-06-05 14:26:23 -03:00
Roberto Ierusalimschy 5b8ee9fa8d new names for standard libraries 2002-06-05 14:24:04 -03:00
Roberto Ierusalimschy 2cd6161060 don't need stdio 2002-06-05 13:59:52 -03:00
Roberto Ierusalimschy a102221a0b better error messages 2002-06-05 13:59:37 -03:00
Roberto Ierusalimschy 6dd0b6c62b details 2002-06-05 13:59:21 -03:00
Roberto Ierusalimschy fa23301251 defintions for lua_number2str and lua_str2number don't need to be public 2002-06-05 09:34:19 -03:00
Roberto Ierusalimschy 94c2449d25 undump may return LUA_ERRRUN 2002-06-03 17:12:50 -03:00
Roberto Ierusalimschy c398a02110 uses `isspace' to recognize space characters 2002-06-03 17:12:21 -03:00
Roberto Ierusalimschy ad7103ea3a lua_load* defined in auxlib (and so renamed to luaL_load*) 2002-06-03 17:11:41 -03:00
Roberto Ierusalimschy 0079e0f57c core tests whether file is binary 2002-06-03 17:11:07 -03:00
Roberto Ierusalimschy cfff013586 detail 2002-06-03 14:47:18 -03:00
Roberto Ierusalimschy 35a22ed1ab lua_load* replaced by a simple lua_load 2002-06-03 14:46:34 -03:00
Roberto Ierusalimschy ff91b355f4 no more use of stdio inside the core (except for `tostring'...) 2002-06-03 11:09:57 -03:00
Roberto Ierusalimschy 5094c37988 strconc' -> concat' 2002-06-03 11:08:43 -03:00
Roberto Ierusalimschy 46c471d7e9 new `__newindex' eventfield 2002-05-27 17:35:40 -03:00
Roberto Ierusalimschy 859ecf36b6 new copyright notice 2002-05-23 17:29:05 -03:00
Roberto Ierusalimschy a1700bbc50 details 2002-05-23 16:43:04 -03:00
Roberto Ierusalimschy 8876a1bf92 details 2002-05-20 16:51:06 -03:00
Roberto Ierusalimschy f53fd8d5f5 _ALERT is a private afair of lua.c 2002-05-16 16:09:19 -03:00
Roberto Ierusalimschy 955def0348 new names for string formating functions 2002-05-16 15:39:46 -03:00
Roberto Ierusalimschy 9c3b3f82fe new commands to test `load' 2002-05-16 11:59:49 -03:00
Roberto Ierusalimschy b7a0503c1d new format for error messages 2002-05-15 15:57:44 -03:00
Roberto Ierusalimschy 1c328a191a no more `global' declarations 2002-05-14 14:52:22 -03:00
Roberto Ierusalimschy 58bf77bc7f no more extra space when growing hash 2002-05-13 10:38:59 -03:00
Roberto Ierusalimschy 8da6fe62d8 `nexti' returns correct indices 2002-05-13 10:10:58 -03:00
Roberto Ierusalimschy c18fe57e54 quick-and-dirty function to print code (for debugging Lua) 2002-05-13 10:10:04 -03:00
Roberto Ierusalimschy af19d55635 generic for also coded to make test at the end of the loop 2002-05-13 10:09:00 -03:00
Roberto Ierusalimschy b55fded18c details about jump optimization 2002-05-13 10:07:48 -03:00
Roberto Ierusalimschy 2dadc81822 cleaner implementation of code generation for jumps 2002-05-10 16:22:11 -03:00
Roberto Ierusalimschy b487975344 optimization for `while' (first version) 2002-05-10 14:02:32 -03:00
Roberto Ierusalimschy 94e5545806 comment 2002-05-09 15:00:38 -03:00
Roberto Ierusalimschy 78b40bf57d `skip' instructions must be followed by a jump 2002-05-09 11:14:34 -03:00
Roberto Ierusalimschy 01f1ac36b1 `global' tables (registry, etc.) stored in proper place, not in the stack 2002-05-08 14:34:23 -03:00
Roberto Ierusalimschy a4d06736d4 correct implementation for arrays of size 1 2002-05-08 14:34:00 -03:00
Roberto Ierusalimschy dea6b6da94 new function lua_vpushstr' to replace uses of sprintf' 2002-05-07 14:36:56 -03:00
Roberto Ierusalimschy 71144e3ff0 errors `return' int, to avoid warnings
+ home-made `sprintf' (first version)
2002-05-06 16:05:10 -03:00
Roberto Ierusalimschy 0dbf0c5953 new format for test intructions (handle NaN correctly) 2002-05-06 12:51:41 -03:00
Roberto Ierusalimschy 85dcb411a8 all textual errors go through `luaL_verror' 2002-05-02 14:12:27 -03:00
Roberto Ierusalimschy 3c6a383d62 avoid limits in filename size 2002-05-02 13:55:55 -03:00
Roberto Ierusalimschy 9a0f0dcc77 precompiler may create functions without `lineinfo' 2002-05-02 10:06:20 -03:00
Roberto Ierusalimschy 751cd867d3 new way to handle errors 2002-05-01 17:48:12 -03:00
Roberto Ierusalimschy b36b2a061c new way to handle errors 2002-05-01 17:40:42 -03:00
Roberto Ierusalimschy ab52fc6097 new macro to `fix' strings 2002-04-30 10:01:48 -03:00
Roberto Ierusalimschy e68d0df1c6 function `zsopen' is not used 2002-04-29 09:37:41 -03:00
Roberto Ierusalimschy 9b38a696d5 avoid names that differ only in capitalization 2002-04-24 17:07:46 -03:00
Roberto Ierusalimschy 383e8b9e77 use of a common `dummynode' for all empty tables 2002-04-23 12:04:39 -03:00
Roberto Ierusalimschy f1a1bb23fe good stack limit to compute ack(8,3) 2002-04-23 11:59:35 -03:00
Roberto Ierusalimschy 151ba1cc7b details 2002-04-23 11:59:22 -03:00
Roberto Ierusalimschy ee4859b3e3 new way to handle errors (temporary version) 2002-04-22 11:40:50 -03:00
Roberto Ierusalimschy f388ee4a82 new way to handle errors 2002-04-22 11:40:23 -03:00
Roberto Ierusalimschy 30ad4c75db bug: 'local a,b; a,b = 1,f()' did not close f() 2002-04-22 11:38:52 -03:00
Roberto Ierusalimschy 3ee1efa7b2 some simplifications 2002-04-22 11:37:09 -03:00
Roberto Ierusalimschy c11d374c59 `panic' function configurable via API 2002-04-16 14:08:28 -03:00
Roberto Ierusalimschy 13230c451b details 2002-04-16 09:00:02 -03:00
Roberto Ierusalimschy 391c5459cb new implementation for `require' (with templates) 2002-04-15 17:54:41 -03:00
Roberto Ierusalimschy 62dd4cbe91 check for errors while loading file 2002-04-15 16:34:42 -03:00
Roberto Ierusalimschy ae5283dc36 co' library goes with basic library (and not with tab') 2002-04-12 16:57:29 -03:00
Roberto Ierusalimschy 1ce6cb6032 no more option `*u' in read (too complex) 2002-04-12 16:56:25 -03:00
Roberto Ierusalimschy 11c63bc3af error in calls signalled in first line (instead of last) 2002-04-10 16:14:45 -03:00
Roberto Ierusalimschy f1f271ae76 details 2002-04-10 15:05:08 -03:00
Roberto Ierusalimschy 6c7334a9ac line trace uses savedpc' to save last pc' seen 2002-04-10 09:11:07 -03:00
Roberto Ierusalimschy 8e1e618606 baselib' splited in baselib' and `tablib' 2002-04-09 17:19:06 -03:00
Roberto Ierusalimschy af4721f7a3 library with table manipulation functions 2002-04-09 17:19:06 -03:00
Roberto Ierusalimschy 018e50ad7f use addresses as keys to hooks 2002-04-09 16:48:08 -03:00
Roberto Ierusalimschy 7b65328c8e new semantics for `generic for' (with state) 2002-04-09 16:47:44 -03:00
Roberto Ierusalimschy d2e05589d7 bug: `resume' was returning its arguments, too 2002-04-09 16:46:56 -03:00
Roberto Ierusalimschy 237969724f support for light' userdata + simpler support for boxed' udata 2002-04-05 15:54:31 -03:00
Roberto Ierusalimschy f438d00ef3 correct #args for calls with self (a:foo(...)) 2002-04-04 17:25:55 -03:00
Roberto Ierusalimschy c3b90061ea new design for iolib (object style) 2002-04-04 17:24:56 -03:00
Roberto Ierusalimschy a2e414d679 `pow' must be global (as the implementation of '^') 2002-04-04 17:20:49 -03:00
Roberto Ierusalimschy 93bcb65a9b debug interface uses method' to describe calls like a:foo()' 2002-04-04 14:21:31 -03:00
Roberto Ierusalimschy 49c95648a0 getmetatable doesn't push nil when there is no metatable 2002-04-02 17:43:18 -03:00
Roberto Ierusalimschy 13ab5a6bb1 details 2002-04-02 17:43:08 -03:00
Roberto Ierusalimschy cd99bbcd0d better support for new libraries 2002-04-02 17:42:49 -03:00
Roberto Ierusalimschy 2cbbf7e95a tostring' uses __tostring' when available 2002-04-02 17:42:20 -03:00
Roberto Ierusalimschy e5919be1a7 bug: end of block may not be end of stat 2002-04-02 17:34:15 -03:00
Roberto Ierusalimschy b795d4b561 details 2002-04-01 11:42:33 -03:00
Roberto Ierusalimschy c371413530 small bug if LUA_USERINIT leaves garbage on the stack 2002-03-27 15:00:13 -03:00
Roberto Ierusalimschy d1f220217b when possible, library functions accept nil as none 2002-03-27 12:30:41 -03:00
Roberto Ierusalimschy 405e3a4597 metatable always return some value 2002-03-27 09:49:53 -03:00
Roberto Ierusalimschy 81215cd59f simpler way to control stack overflow 2002-03-26 17:46:10 -03:00
Roberto Ierusalimschy 0b9b53e21c details 2002-03-26 15:55:50 -03:00
Roberto Ierusalimschy 44a5484d73 small bug (L->ci->top may be larger than L->top...) 2002-03-25 16:45:06 -03:00
Roberto Ierusalimschy 801aaf37b1 simpler implementation for line information 2002-03-25 14:47:14 -03:00
Roberto Ierusalimschy 00af2faae7 first implementation of proper tail call 2002-03-22 13:54:31 -03:00
Roberto Ierusalimschy e9ef7ed2d3 first implementation for tail call 2002-03-21 17:32:22 -03:00
Roberto Ierusalimschy 2626708b72 details 2002-03-21 17:31:43 -03:00
Roberto Ierusalimschy 19ac0fadc9 don't need to mark the stacks twice ;-) 2002-03-20 15:54:29 -03:00
Roberto Ierusalimschy ca2ceef659 simpler solution for finalizing udata 2002-03-20 15:37:28 -03:00
Roberto Ierusalimschy 5023aaee0a reserve one more bit for GC 2002-03-20 15:37:13 -03:00
Roberto Ierusalimschy 88c9bf99de standard libraries in packages 2002-03-20 09:54:08 -03:00
Roberto Ierusalimschy 63a614e145 some improvements in stack control 2002-03-20 09:52:32 -03:00
Roberto Ierusalimschy 48e732e07d improvements in stack control 2002-03-20 09:51:29 -03:00
Roberto Ierusalimschy 938092489b erroneous objects may not live in the stack 2002-03-19 09:45:25 -03:00
Roberto Ierusalimschy 578d1da00d new names for tag methods 2002-03-18 17:24:14 -03:00
Roberto Ierusalimschy 24d6d0528d api.c only needs to check pushes when api_check is defined 2002-03-18 17:11:52 -03:00
Roberto Ierusalimschy 0b00e7f1a2 new macro to convert double->int 2002-03-18 15:18:35 -03:00
Roberto Ierusalimschy b7ed502dea configurable macros should live in llimits.h 2002-03-18 15:16:16 -03:00
Roberto Ierusalimschy 58badbab99 special treatment for 'global in nil' 2002-03-18 11:49:46 -03:00
Roberto Ierusalimschy da81845cd5 an error may call GC and find an incomplete `ci' 2002-03-15 14:17:16 -03:00
Roberto Ierusalimschy 9681ff09db small optimization when returning a single local value 2002-03-14 15:32:37 -03:00
Roberto Ierusalimschy 7ff21273d6 implementation of `global' statement 2002-03-14 15:01:52 -03:00
Roberto Ierusalimschy 207dad8606 comments 2002-03-14 13:50:06 -03:00
Roberto Ierusalimschy c97dc294a9 first implementation of `gfind' 2002-03-11 10:29:40 -03:00
Roberto Ierusalimschy 71c716e5a8 avoid C identifiers beginning with '_' 2002-03-11 09:45:00 -03:00
Roberto Ierusalimschy 51ad2f1162 error message 2002-03-08 16:25:24 -03:00
Roberto Ierusalimschy ecda9c1972 details 2002-03-08 16:17:59 -03:00
Roberto Ierusalimschy e19eba7219 cannot store `top' in local variables... 2002-03-08 16:11:03 -03:00
Roberto Ierusalimschy bd8b9c94b3 generic for (with any number of control variables) 2002-03-08 16:10:32 -03:00
Roberto Ierusalimschy 4db04555f0 implementation of long comments 2002-03-08 16:07:01 -03:00
Roberto Ierusalimschy c16a35d669 lua_stackspace' replaced by lua_checkstack' 2002-03-07 15:15:10 -03:00
Roberto Ierusalimschy 8f837e83b2 using `ci->top' to control acceptable indices in C calls 2002-03-07 15:14:29 -03:00
Roberto Ierusalimschy 6658b9588f details 2002-03-07 15:11:51 -03:00
Roberto Ierusalimschy 457d88eaaa configurable minimum size for the string table 2002-03-05 13:22:54 -03:00
Roberto Ierusalimschy 8a1a512c64 lu_byte is enough for those fields (maxstack < 256) 2002-03-05 09:42:47 -03:00
Roberto Ierusalimschy 6b0c38c2e7 `inline' of tonumber 2002-03-04 18:33:09 -03:00
Roberto Ierusalimschy 1a3f175640 small optimization 2002-03-04 18:32:34 -03:00
Roberto Ierusalimschy 88c7b574cb `luaA_index' is a local macro now 2002-03-04 18:29:41 -03:00
Roberto Ierusalimschy 51bf91a970 detail 2002-03-04 12:40:04 -03:00
Roberto Ierusalimschy 1b6315ba10 not all unfinished strings with "..." end in EOF 2002-03-04 12:27:14 -03:00
Roberto Ierusalimschy 3b001d9a9d more tests for boolean API 2002-03-04 12:26:56 -03:00
Roberto Ierusalimschy c36b5cc726 detail 2002-02-15 13:15:10 -02:00
Roberto Ierusalimschy 2c1eb62a08 get error messages from luaL_errstr 2002-02-14 20:23:43 -02:00
Roberto Ierusalimschy 63e2d92123 no more -DOLD_ANSI option + details 2002-02-14 19:49:33 -02:00
Roberto Ierusalimschy e966dd93be towards next version... 2002-02-14 19:48:32 -02:00
Roberto Ierusalimschy 2f8e3c5543 prints any results returned by chunk 2002-02-14 19:47:50 -02:00
Roberto Ierusalimschy b0a5e156b8 no more maximum stack size 2002-02-14 19:47:29 -02:00
Roberto Ierusalimschy ac178ee478 new constructor syntax + new generic `for' 2002-02-14 19:46:58 -02:00
Roberto Ierusalimschy 1e602a61b3 new generic `for' 2002-02-14 19:46:43 -02:00
Roberto Ierusalimschy 57fb51f975 luaH_next' works like next' 2002-02-14 19:46:13 -02:00
Roberto Ierusalimschy 1c423d2661 LFIELDS_PER_FLUSH is an opcode detail 2002-02-14 19:43:01 -02:00
Roberto Ierusalimschy b3ffaca638 details 2002-02-14 19:41:53 -02:00
Roberto Ierusalimschy bee86e23be luaH_next' works like next' + better hash for pointers 2002-02-14 19:41:08 -02:00
Roberto Ierusalimschy 0056ed4135 better(?) order for types (nil == 0) 2002-02-14 19:40:29 -02:00
Roberto Ierusalimschy e01f5e6809 better order of record fields for 64-bit machines 2002-02-08 20:42:41 -02:00
Roberto Ierusalimschy cbfc581990 details. 2002-02-08 20:41:50 -02:00
Roberto Ierusalimschy d3651c1d88 `getstr' now gives const char * 2002-02-08 20:41:09 -02:00
Roberto Ierusalimschy 57a7baafb9 error message compatible with incomplete lines of lua.c 2002-02-08 20:40:27 -02:00
Roberto Ierusalimschy 252e01e398 `setlocale' may be used to query the current locale 2002-02-08 20:39:56 -02:00
Roberto Ierusalimschy 87b0e3d477 no more `lua_istrue' function 2002-02-08 20:39:36 -02:00
Roberto Ierusalimschy cb50fcf42d incomplete lines (by lhf) 2002-02-07 15:27:12 -02:00
Roberto Ierusalimschy c6a108e012 test for lua_pushbool 2002-02-07 15:26:33 -02:00
Roberto Ierusalimschy d5ceb369b1 boolean type must be 0 or 1 2002-02-07 15:26:10 -02:00
Roberto Ierusalimschy 86a4de256e no more lua_[gs]etstr 2002-02-07 15:25:36 -02:00
Roberto Ierusalimschy 53aaee6ee6 comments 2002-02-07 15:25:12 -02:00
Roberto Ierusalimschy 67bda7e136 details. 2002-02-07 15:24:05 -02:00
Roberto Ierusalimschy 7c8f1823e7 bug: true 1 != true 2 + no more lua_getstr + some new macros 2002-02-07 15:22:53 -02:00
Roberto Ierusalimschy ca181f31e4 line number in listcode (and tests for replace) 2002-02-05 20:40:05 -02:00
Roberto Ierusalimschy 38b0e6128d simpler implementation for `for' loops 2002-02-05 20:39:12 -02:00
Roberto Ierusalimschy addbe8c8b0 protected execution of `resume' 2002-02-05 20:38:37 -02:00
Roberto Ierusalimschy 6bb5cb1cbd comments 2002-02-05 20:37:26 -02:00
Roberto Ierusalimschy d070506a25 new function luaL_errstr 2002-02-05 20:36:52 -02:00
Roberto Ierusalimschy 0a87d9d334 new function `lua_replace' 2002-02-05 20:35:58 -02:00
Roberto Ierusalimschy f856fdeabd details 2002-01-30 15:28:05 -02:00
Roberto Ierusalimschy 653977a0ac callhook can be static 2002-01-30 15:27:53 -02:00
Roberto Ierusalimschy d6fd33e76f eventtable' renamed to metatable' 2002-01-30 15:26:44 -02:00
Roberto Ierusalimschy 50e2952593 first version of dynamic stack 2002-01-25 20:14:54 -02:00
Roberto Ierusalimschy b217ae644e details 2002-01-25 20:14:09 -02:00
Roberto Ierusalimschy a048cc9676 nil is a `valid' eventtable 2002-01-25 19:55:41 -02:00
Roberto Ierusalimschy eb262bc617 2^15 does not fit in a 16-bit int 2002-01-25 19:51:33 -02:00
Roberto Ierusalimschy 74907fb71e OP_LOADINT can be done by OP_LOADK 2002-01-25 19:50:39 -02:00
Roberto Ierusalimschy b38e594ed7 small improvements 2002-01-18 15:39:40 -02:00
Roberto Ierusalimschy 448517e47e no more linehook field in CallInfo 2002-01-18 15:39:06 -02:00
Roberto Ierusalimschy 931ee346e3 legacy declaration 2002-01-18 15:38:13 -02:00
Roberto Ierusalimschy dea98702c9 preparations for stack reallocation 2002-01-16 20:04:50 -02:00
Roberto Ierusalimschy 7ab7703b53 cleaner semantics for test instructions (skips) 2002-01-16 20:03:57 -02:00
Roberto Ierusalimschy 566310fa04 small optimization 2002-01-16 20:02:46 -02:00
Roberto Ierusalimschy 6272c843de yield' passes its arguments to resume' 2002-01-11 18:27:41 -02:00
Roberto Ierusalimschy 5d14ce612b details 2002-01-11 18:27:11 -02:00
Roberto Ierusalimschy d56d4cf776 distinct functions to create/destroy states and threads 2002-01-11 18:26:52 -02:00
Roberto Ierusalimschy b7ae43d457 detail 2002-01-11 18:23:01 -02:00
Roberto Ierusalimschy f083812c02 first implementation of coroutines 2002-01-09 20:02:47 -02:00
Roberto Ierusalimschy 3533382a1e dependencies updated 2002-01-09 19:59:24 -02:00
Roberto Ierusalimschy ea2a75d19e new macro lua_userstateopen 2002-01-09 19:51:06 -02:00
Roberto Ierusalimschy b3bb0f132b new interface for weak modes 2002-01-09 19:50:35 -02:00
Roberto Ierusalimschy facfec0687 small optimizations 2002-01-03 15:42:57 -02:00
Roberto Ierusalimschy 34df9976a9 some compatibility macros 2002-01-03 15:28:58 -02:00
Roberto Ierusalimschy cfaa8fbf1d better check for option in `strfind' 2002-01-03 15:27:43 -02:00
Roberto Ierusalimschy f42cc90d2d some warnings 2001-12-21 15:31:35 -02:00
Roberto Ierusalimschy 9d2e454d6f BUG: seg. fault when rawget/rawset get extra arguments 2001-12-21 15:30:31 -02:00
Roberto Ierusalimschy 09e15692f3 rename of lua_isnull to lua_isnone 2001-12-20 19:27:12 -02:00
Roberto Ierusalimschy 42754c0f15 small optimizations 2001-12-20 19:26:52 -02:00
Roberto Ierusalimschy 18afb90349 first version of stackless Lua 2001-12-20 13:13:38 -02:00
Roberto Ierusalimschy 22dd271cbb another bug in next (when n is a power of 2) 2001-12-19 16:11:00 -02:00
Roberto Ierusalimschy e04f7ed450 first version of Lua "stackless" 2001-12-18 18:52:30 -02:00
Roberto Ierusalimschy 101cee3032 LUA_ERRERR also cannot generate error message 2001-12-13 16:11:02 -02:00
Roberto Ierusalimschy eb7312d9be comments 2001-12-13 16:10:55 -02:00
Roberto Ierusalimschy 21259a50e1 run GC tag methods in protected mod 2001-12-12 15:47:33 -02:00
Roberto Ierusalimschy 9aff171f3b new type `boolean' 2001-12-11 20:48:44 -02:00
Roberto Ierusalimschy ed9be5e1f0 reentrant implementation of garbage collection 2001-12-11 14:52:57 -02:00
Roberto Ierusalimschy 9d801f43d4 details 2001-12-10 20:12:08 -02:00
Roberto Ierusalimschy e043b72a55 simpler way to collect userdata 2001-12-10 20:11:23 -02:00
Roberto Ierusalimschy a4c35a3269 it doesn't pay to optimize absence when it is an error 2001-12-10 20:10:30 -02:00
Roberto Ierusalimschy 9cd36059ad new API functions lua_getstr/lua_setstr 2001-12-10 20:09:51 -02:00
Roberto Ierusalimschy 592a309177 tag system replaced by event tables 2001-12-05 18:15:18 -02:00
Roberto Ierusalimschy 413fc7334b new implementation for lua upvalues (sugested by E.T.): simpler and solves
a bug for multi-stacks
2001-11-29 18:22:22 -02:00
Roberto Ierusalimschy fca0a12e23 avoid clashing names between macros and fields 2001-11-29 18:21:46 -02:00
Roberto Ierusalimschy 72659a0605 no more explicit support for wide-chars; too much troble... 2001-11-28 18:13:13 -02:00
Roberto Ierusalimschy dfaf8c5291 details 2001-11-27 18:56:47 -02:00
Roberto Ierusalimschy 657f65211a bug: `next' did not work for numeric indices 2001-11-16 14:29:51 -02:00
Roberto Ierusalimschy 39395e1211 `luaX_syntaxerror' does not need to be public 2001-11-16 14:29:10 -02:00
Roberto Ierusalimschy 26bf2adace optimizations for space in LClosures and time cleanning weak tables 2001-11-06 19:41:53 -02:00
Roberto Ierusalimschy fd48dcc7c8 details. 2001-11-06 19:41:43 -02:00
Roberto Ierusalimschy 617008f552 field G renamed to _G to avoid problemas with bugged macro-systems
(there is a macro named G too)
2001-11-06 19:40:51 -02:00
Roberto Ierusalimschy ec9d8308b4 global table is also pseudo-index 2001-10-31 18:31:38 -02:00
Roberto Ierusalimschy af59848219 tables of globals accessible through pseudo-index in C API 2001-10-31 17:58:11 -02:00
Roberto Ierusalimschy 46347d768e `ref' support goes to auxlib 2001-10-31 17:40:14 -02:00
Roberto Ierusalimschy 36eb665859 no more refs, upvalues; lexical scoping;pseudo-indices 2001-10-31 16:06:05 -02:00
Roberto Ierusalimschy 070204300c more consistent names for auxlib functions 2001-10-26 15:33:30 -02:00
Roberto Ierusalimschy 21aa7e55f2 optimization for array part of a Table 2001-10-25 17:14:14 -02:00
Roberto Ierusalimschy fffb6f3814 no more MINPOWER2 2001-10-25 17:13:33 -02:00
Roberto Ierusalimschy 0b551a24f8 Hash' -> Table' 2001-10-25 17:12:21 -02:00
Roberto Ierusalimschy 8069f77ca4 C++ warning 2001-10-17 19:17:45 -02:00
Roberto Ierusalimschy 1e81da51ba new API for registry and C upvalues + new implementation for references 2001-10-17 19:12:57 -02:00
Roberto Ierusalimschy 7cd37142f4 details 2001-10-17 19:06:56 -02:00
Roberto Ierusalimschy e7c2eebd87 new function `concat' 2001-10-16 15:41:43 -02:00
Roberto Ierusalimschy 0c3ea96541 no more copytagmethod function 2001-10-11 18:41:21 -03:00
Roberto Ierusalimschy babaa96eab URL in indentification 2001-10-11 18:40:56 -03:00
Roberto Ierusalimschy 15462edb0f new definitions for closure structures 2001-10-02 13:45:03 -03:00
Roberto Ierusalimschy 6f936bc793 "compatibility module" no longer exists 2001-10-02 13:43:54 -03:00
Roberto Ierusalimschy b840a7518d details 2001-10-02 13:43:29 -03:00
Roberto Ierusalimschy f54cdb33a5 small bug in close x return 2001-09-28 13:48:16 -03:00
Roberto Ierusalimschy 8e9b1e4ae9 details 2001-09-25 14:08:46 -03:00
Roberto Ierusalimschy 328d53e77b restricted syntax for function call/table accesses prefixes 2001-09-25 14:06:48 -03:00
Roberto Ierusalimschy c04d9b9ecb small bug when closing closures in error conditions 2001-09-25 14:05:49 -03:00
Roberto Ierusalimschy c44c68450a changes by lhf 2001-09-24 12:54:36 -03:00
Roberto Ierusalimschy abdbe883a8 first implementation of unrestricted static scoping 2001-09-07 14:39:10 -03:00
Roberto Ierusalimschy 4d0935ec0f better definition for `luaM_freelem' 2001-09-07 14:30:16 -03:00
Roberto Ierusalimschy e1d072571e better syntax for type casts 2001-08-31 16:46:07 -03:00
Roberto Ierusalimschy 7651a5c6b2 start of new version 2001-08-31 16:46:07 -03:00
Roberto Ierusalimschy 8c8ad5f3ff better locality of assignment of table values 2001-08-30 17:56:43 -03:00
Roberto Ierusalimschy 34a09b65f3 some changes of arguments from char to int 2001-08-30 17:55:58 -03:00
Roberto Ierusalimschy 29d883b9bd avoid augmenting alignment of pointers 2001-08-30 17:55:22 -03:00
Roberto Ierusalimschy b0d5bd8c70 tinsert gets 3d argument instead of last one 2001-08-30 17:54:51 -03:00
Roberto Ierusalimschy 9fca43f5b0 details 2001-08-30 17:54:36 -03:00
Roberto Ierusalimschy 33d820d41d new syntax "= exp" to rpint exp + simplifications 2001-08-30 17:54:02 -03:00
Roberto Ierusalimschy c3d72096c4 use a table to find (and reuse) constants when parsing 2001-08-27 12:16:28 -03:00
Roberto Ierusalimschy 7afc74ff07 avoid some warnings from strange compilers 2001-08-27 12:14:57 -03:00
Roberto Ierusalimschy 022bf27202 extra parenteses to avoid warnings 2001-08-27 12:13:59 -03:00
Roberto Ierusalimschy fd40af92e4 the parser is not LL(1) 2001-08-10 17:53:03 -03:00
Roberto Ierusalimschy 0171543704 better optimization options 2001-07-24 19:40:08 -03:00
Roberto Ierusalimschy ebd1d1f82c no more deprecated code 2001-07-24 19:39:34 -03:00
Roberto Ierusalimschy 04320e04bf warnings from Visual C++ (plus small details) 2001-07-24 18:57:19 -03:00
Roberto Ierusalimschy 5d2d2b1752 the usual stuff 2001-07-24 14:25:30 -03:00
Roberto Ierusalimschy f34001faa9 details 2001-07-24 14:25:03 -03:00
Roberto Ierusalimschy 95988676d8 small bug when creating AsBc instructions in 16-bit machines 2001-07-24 14:19:07 -03:00
Roberto Ierusalimschy 767abdfdc0 `newtype' returns old tag when given an old name 2001-07-23 16:56:00 -03:00
Roberto Ierusalimschy 45b173cbf8 warnings/details 2001-07-21 21:59:36 -03:00
Roberto Ierusalimschy a94cba4b88 ready for 4.1 alpha? 2001-07-19 10:36:18 -03:00
Roberto Ierusalimschy f9f355221f version -> 4.1 alpha 2001-07-19 10:24:18 -03:00
Roberto Ierusalimschy b3dd9b1bb1 `format' can handle \0 in format string (why not?) 2001-07-17 15:46:49 -03:00
Roberto Ierusalimschy d8f37bf42a weakregistry has its keys weak, too 2001-07-17 14:54:46 -03:00
Roberto Ierusalimschy a598804a04 small bug in luaK_self (side effects) 2001-07-17 11:30:44 -03:00
Roberto Ierusalimschy 6c8e652aa6 use macros for 'getc' 2001-07-16 17:24:48 -03:00
Roberto Ierusalimschy 9f25df02d5 new definition for headers of binary files 2001-07-12 16:34:03 -03:00
Roberto Ierusalimschy ae1cf64348 better names for type-related functions 2001-07-12 15:11:58 -03:00
Roberto Ierusalimschy a264fd089e small bug in read_chars (fread x eof) 2001-07-12 11:59:14 -03:00
Roberto Ierusalimschy a3d03ff6b6 bug: error message for `%a' gave wrong line number 2001-07-10 17:02:22 -03:00
Roberto Ierusalimschy 654b16e83a better performance for table operations (mainly for integer indices) 2001-07-05 17:31:14 -03:00
Roberto Ierusalimschy dc4e0ecdaf new versions by lhf 2001-07-05 17:29:15 -03:00
Roberto Ierusalimschy 9924668931 LUA_MINSTACK has a fixed value 2001-07-05 16:32:42 -03:00
Roberto Ierusalimschy 89ef91a7fe `opmodes' table also generated automatically by mkprint 2001-07-03 14:02:02 -03:00
Roberto Ierusalimschy 00aaee0ae7 details 2001-07-03 14:01:34 -03:00
Roberto Ierusalimschy 18d3e82cfe check C is independent from check B 2001-07-03 14:01:34 -03:00
Roberto Ierusalimschy 2a4afb97c8 new module lopcodes.c for tables describing opcodes 2001-06-28 16:58:57 -03:00
Roberto Ierusalimschy 87a5fae453 tables describing opcodes 2001-06-28 16:58:57 -03:00
Roberto Ierusalimschy afed6c6864 missing an opcode name 2001-06-28 12:06:20 -03:00
Roberto Ierusalimschy 770954510f rename of kproto' to p' 2001-06-28 11:57:17 -03:00
Roberto Ierusalimschy b346834a09 new macros for changing numbers 2001-06-28 11:48:44 -03:00
Roberto Ierusalimschy 61a036eaa5 new macro to control format for `read"*n"' 2001-06-28 11:45:44 -03:00
Roberto Ierusalimschy 37f3a1c045 too much optimization to "break" keys in tables; keep them as TObjects... 2001-06-26 10:20:45 -03:00
Roberto Ierusalimschy 9559c111a3 new read' option *u' (read-until) + simpler implementation for `read' 2001-06-22 10:49:42 -03:00
Roberto Ierusalimschy 777061e441 resurect userdata before calling its GC tag method 2001-06-21 13:41:34 -03:00
Roberto Ierusalimschy fccadba4b5 new reserved words in' and global' 2001-06-20 18:07:57 -03:00
Roberto Ierusalimschy b940f09984 no more "compat mode" with 3.2 (deprecated functions) 2001-06-20 14:25:30 -03:00
Roberto Ierusalimschy 878979cef7 no more opnames in binary tag methods 2001-06-20 14:22:46 -03:00
Roberto Ierusalimschy 8e586c13fc cleaner way to ensure alignment for strings and userdata 2001-06-15 17:36:57 -03:00
Roberto Ierusalimschy eadf2aaaff small optimizations 2001-06-15 16:17:33 -03:00
Roberto Ierusalimschy ae19b2f51e more relaxed rules for syncronized access 2001-06-15 16:16:41 -03:00
Roberto Ierusalimschy a3fbf5f5fd details 2001-06-13 15:51:20 -03:00
Roberto Ierusalimschy 7fae1c17b1 detail 2001-06-13 11:25:49 -03:00
Roberto Ierusalimschy 89e8303f4e more robust treatment of GC tag methods (now they can create new
objects while running...)
2001-06-12 15:43:13 -03:00
Roberto Ierusalimschy 89c301d180 `(exp)' adjusts exp to 1 result 2001-06-12 11:36:48 -03:00
Roberto Ierusalimschy 186111dc01 unused definition 2001-06-11 11:57:17 -03:00
Roberto Ierusalimschy 0a1b1acdd3 details about opcode parameters 2001-06-11 11:56:42 -03:00
Roberto Ierusalimschy 79acf5ea60 details 2001-06-08 16:20:02 -03:00
Roberto Ierusalimschy cbc59592ff new definition for luaD_call' and luaD_adjusttop' 2001-06-08 16:01:38 -03:00
Roberto Ierusalimschy 4905fdd135 C++ warning 2001-06-08 13:48:32 -03:00
Roberto Ierusalimschy 0267168675 details. 2001-06-08 09:29:27 -03:00
Roberto Ierusalimschy ba11831d35 smaller structs for udata and for strings 2001-06-07 12:01:21 -03:00
Roberto Ierusalimschy 190ddd431d details (rests of debug code) 2001-06-07 11:44:51 -03:00
Roberto Ierusalimschy 65c289b046 details 2001-06-07 10:46:29 -03:00
Roberto Ierusalimschy d5b83ead90 new implementation for userdatas, without `keys' 2001-06-06 15:00:19 -03:00
Roberto Ierusalimschy da673d31aa user can define extra alignment requirements 2001-06-05 17:01:09 -03:00
Roberto Ierusalimschy 323da72577 weakmode' queries must have an explicit ?' 2001-06-05 16:41:31 -03:00
Roberto Ierusalimschy 943b8f5b18 details 2001-06-05 16:41:24 -03:00
Roberto Ierusalimschy 762d059a13 new implementation for the Virtual Machine 2001-06-05 15:17:01 -03:00
Roberto Ierusalimschy 572a69b6af name changes 2001-04-23 13:35:45 -03:00
Roberto Ierusalimschy beee01b170 re-implementation of refs through weak tables 2001-04-17 14:35:54 -03:00
Roberto Ierusalimschy 6473f965ca new API functions to load (parse?) a chunk without running it. 2001-04-11 15:39:37 -03:00
Roberto Ierusalimschy 0e0e4a480e first implementation for weak tables 2001-04-11 11:42:41 -03:00
Roberto Ierusalimschy 2a50188269 avoid use of l_char outside INTERNALs (use lua_char instead) 2001-04-06 18:17:37 -03:00
Roberto Ierusalimschy 9aedea6ec8 small bug (when parser fails, there is no function on the stack...) 2001-04-06 16:26:06 -03:00
Roberto Ierusalimschy a68635a919 list constructors do not adjust last expression 2001-04-06 15:25:00 -03:00
Roberto Ierusalimschy 2112142680 allow syntax << function (x) ... end (...) >> as a statement 2001-04-05 13:49:14 -03:00
Roberto Ierusalimschy dd3a63c205 new way to handle `profiles' 2001-03-26 11:31:49 -03:00
Roberto Ierusalimschy cb49b088b6 old signature for lua_open 2001-03-09 15:05:05 -03:00
Roberto Ierusalimschy c5a23cf01a details 2001-03-07 15:16:22 -03:00
Roberto Ierusalimschy 6048c4f74d better way to link callinfo's and stack 2001-03-07 15:09:25 -03:00
Roberto Ierusalimschy 5e870f86a2 optimization for tailcall does not seem to pay itself 2001-03-07 10:22:55 -03:00
Roberto Ierusalimschy f81b8adb3f string [[...]] ignores initial \n 2001-03-07 09:49:37 -03:00
Roberto Ierusalimschy 2b2267069b new functions pack' and unpack' 2001-03-07 09:43:52 -03:00
Roberto Ierusalimschy 72d3d155b0 detail 2001-03-07 09:27:06 -03:00
Roberto Ierusalimschy 6d4db86888 open functions are lua_Cfunctions 2001-03-06 17:09:38 -03:00
Roberto Ierusalimschy e9a3820370 sizeof(string) != strlen(string)+1 when sizeof(char) != 1 2001-03-06 11:46:54 -03:00
Roberto Ierusalimschy 9e8a46daa2 details (identation) 2001-03-02 14:40:08 -03:00
Roberto Ierusalimschy 7b84f9e65c lower-case for macros with arguments 2001-03-02 14:27:50 -03:00
Roberto Ierusalimschy 1e40b4dc61 buffer should be void *, as char now is not that neutral...
+ little bug in pointer arithmetic
2001-02-23 17:32:32 -03:00
Roberto Ierusalimschy dfd7ce74cf buffer should be void *, as char now is not that neutral... 2001-02-23 17:32:16 -03:00
Roberto Ierusalimschy 8399df5dcf detail 2001-02-23 17:31:37 -03:00
Roberto Ierusalimschy d2a64bb6d4 `llimits' may need definitions from LUA_USER_H 2001-02-23 17:28:56 -03:00
Roberto Ierusalimschy a90f06dcd8 `atoi' does not have a wide-char equivalent 2001-02-23 17:28:26 -03:00
Roberto Ierusalimschy 35023355f2 details for wchar 2001-02-23 14:28:12 -03:00
Roberto Ierusalimschy 39b7978329 first (big) step to support wide chars 2001-02-23 14:17:25 -03:00
Roberto Ierusalimschy d164e2294f _ERRORMESSAGE called through get global tag method 2001-02-23 10:38:56 -03:00
Roberto Ierusalimschy 2cc94ac81b avoid name clash with `sys/stat' 2001-02-23 10:38:56 -03:00
Roberto Ierusalimschy 5f37134e64 avoid '...' and "..." inside comments 2001-02-22 15:59:59 -03:00
Roberto Ierusalimschy 52ee91dd73 better encapsulation of some types 2001-02-22 14:15:18 -03:00
Roberto Ierusalimschy 191fd35f0a warnings from Visual C++ 2001-02-21 13:52:09 -03:00
Roberto Ierusalimschy d6978d03e1 small bug in testing (pushuserdata needs some memory to work...) 2001-02-21 13:51:25 -03:00
Roberto Ierusalimschy 68b08848d4 `dostring' now is safe to run binary code. 2001-02-20 15:29:54 -03:00
Roberto Ierusalimschy 888f91fa24 code check for upvalues 2001-02-20 15:28:11 -03:00
Roberto Ierusalimschy c1db0b2bf1 detail 2001-02-20 15:18:00 -03:00
Roberto Ierusalimschy 099442c41f better separation between basic types 2001-02-20 15:15:33 -03:00
Roberto Ierusalimschy 27600fe87a better strucuture for code checker 2001-02-16 15:58:27 -02:00
Roberto Ierusalimschy f8509668dc details. 2001-02-14 15:38:45 -02:00
Roberto Ierusalimschy 40f4e931f3 more liberal syntax for expressions 2001-02-14 15:19:28 -02:00
Roberto Ierusalimschy 29371ecfe8 better way to handle multi-line input (with concat) 2001-02-14 15:19:01 -02:00
Roberto Ierusalimschy 5d9b8b7cdc more secure definition for lua_concat 2001-02-14 15:04:11 -02:00
Roberto Ierusalimschy 1c2501fad4 tests for string alignment 2001-02-13 14:52:01 -02:00
Roberto Ierusalimschy a4ae1475e3 details (smaller code) 2001-02-13 14:17:53 -02:00
Roberto Ierusalimschy b3da4ee907 checking consistency of jumps. 2001-02-12 17:54:50 -02:00
Roberto Ierusalimschy 3c649ce123 checking consistency of jumps (and some other details) 2001-02-12 17:54:28 -02:00
Roberto Ierusalimschy 95da574dbc some compilers (wrongly) complain about that 2001-02-12 17:21:19 -02:00
Roberto Ierusalimschy 255052b6c6 better API checks 2001-02-12 13:42:44 -02:00
Roberto Ierusalimschy 1bdc156b52 details 2001-02-12 11:04:19 -02:00
Roberto Ierusalimschy 03d8a9bf0d details 2001-02-09 18:29:33 -02:00
Roberto Ierusalimschy d2e340f467 string pointers are always fully aligned 2001-02-09 18:22:29 -02:00
Roberto Ierusalimschy 6875fdc8be new semantics for pushuserdata (no more different userdatas with same value) 2001-02-09 17:53:16 -02:00
Roberto Ierusalimschy dc17a9cc24 new semantics for pushuserdata 2001-02-09 17:52:54 -02:00
Roberto Ierusalimschy 81e63f75c0 `tostring' uses type names (when available) 2001-02-09 17:52:24 -02:00
Roberto Ierusalimschy c81404cae5 first version of code verification 2001-02-09 16:37:33 -02:00
Roberto Ierusalimschy b6ce590433 details 2001-02-09 16:07:47 -02:00
Roberto Ierusalimschy e70e6a3b7a <read(0)> tests for EOF 2001-02-09 14:25:50 -02:00
Roberto Ierusalimschy 6548bf7462 warnings from Visual C 2001-02-08 09:19:10 -02:00
Roberto Ierusalimschy 7178a5e34a new way to handle top x L->top 2001-02-07 16:13:49 -02:00
Roberto Ierusalimschy 322b7b5fc5 easier to add new initialization functions 2001-02-06 16:18:58 -02:00
Roberto Ierusalimschy 1f917e709c better use of extra include files (both for tests and for old_ansi) 2001-02-06 14:01:29 -02:00
Roberto Ierusalimschy d444153dbe ESC (which starts precompiled code) in C is \33, not \27 2001-02-06 11:59:29 -02:00
Roberto Ierusalimschy a894499566 details 2001-02-05 17:08:01 -02:00
Roberto Ierusalimschy d1fc6244f0 extended syntax to allow function a.b.c (x) 2001-02-05 15:48:52 -02:00
Roberto Ierusalimschy 7e3d3e1f70 details 2001-02-02 17:02:40 -02:00
Roberto Ierusalimschy 1f9e3731d1 back to the basics (well-behaved variant record...) 2001-02-02 14:32:00 -02:00
Roberto Ierusalimschy 42224ca553 loop of 'dostring' may never reclaim memory 2001-02-02 14:23:20 -02:00
Roberto Ierusalimschy 426d3e43bd lock/unlock may use L + better structure for internal debug stuff 2001-02-02 13:13:05 -02:00
Roberto Ierusalimschy 8823f371a2 new header to put together debug-related declarations 2001-02-02 13:12:25 -02:00
Roberto Ierusalimschy e506b864cd no need for tags in boxed values :-( 2001-02-01 15:40:48 -02:00
Roberto Ierusalimschy 9a231afa97 top must be updated when there is any error 2001-02-01 15:39:55 -02:00
Roberto Ierusalimschy 4ab6acacdf better control of relationship top x L->top 2001-02-01 14:03:38 -02:00
Roberto Ierusalimschy 6858763994 bug in lua_pushuserdata(L, NULL) 2001-02-01 11:56:49 -02:00
Roberto Ierusalimschy b68fb7f62e `assert' returns its first argument 2001-01-31 17:53:01 -02:00
Roberto Ierusalimschy 60ff79451c detail in error message 2001-01-31 11:13:17 -02:00
Roberto Ierusalimschy 44a53df688 better to avoid dirty tricks 2001-01-30 17:48:37 -02:00
Roberto Ierusalimschy 63a822c8e1 all boxed types start with their tags 2001-01-29 17:34:02 -02:00
Roberto Ierusalimschy 09def5da44 small corrections 2001-01-29 17:33:55 -02:00
Roberto Ierusalimschy 6b71a9cfe5 smaller tables for machines with 8-bit alignment 2001-01-29 15:17:26 -02:00
Roberto Ierusalimschy fa8c44b510 avoid the use of "reopen" (not that standard) 2001-01-29 13:35:17 -02:00
Roberto Ierusalimschy 3b6f8bfbe6 simpler implementation of for loops 2001-01-29 13:26:40 -02:00
Roberto Ierusalimschy caf01b5bfa better implementation for list "for" 2001-01-29 11:14:49 -02:00
Roberto Ierusalimschy ca1f28b829 avoid side-effects on macros that may use twice their arguments 2001-01-26 16:43:22 -02:00
Roberto Ierusalimschy b82242d4c4 detail 2001-01-26 13:58:50 -02:00
Roberto Ierusalimschy ac390020e9 optimizations based on all types but number and nil are pointers 2001-01-26 12:16:35 -02:00
Roberto Ierusalimschy 9b45439860 details 2001-01-26 12:16:24 -02:00
Roberto Ierusalimschy 7959f3aebb easier way to erase 'dead' keys 2001-01-26 11:18:00 -02:00
Roberto Ierusalimschy bce6572579 new macros + new names to facilitate compilation of threaded version 2001-01-26 09:45:51 -02:00
Roberto Ierusalimschy a53d9b66ca first implementation for type names 2001-01-25 14:45:36 -02:00
Roberto Ierusalimschy c8559e3c8d a small optimization 2001-01-24 14:20:54 -02:00
Roberto Ierusalimschy 71ae4801d6 macros LUA_ENTRY/LUA_EXIT to control exclusive access to Lua core 2001-01-24 13:45:33 -02:00
Roberto Ierusalimschy 6fda6a5302 support for multiple stacks sharing the same global environment 2001-01-22 16:01:38 -02:00
Roberto Ierusalimschy 4ac58853dc thead-specific state separated from "global" state 2001-01-19 11:20:30 -02:00
Roberto Ierusalimschy f2c451d745 all accesses to TObjects done through macros 2001-01-18 13:59:09 -02:00
Roberto Ierusalimschy 619edfd9e4 details 2001-01-15 16:07:56 -02:00
Roberto Ierusalimschy a04de4f0ad no more END opcode 2001-01-15 14:13:24 -02:00
Roberto Ierusalimschy a653d93a43 string comparison only needs to test for "less than" 2001-01-11 16:59:32 -02:00
Roberto Ierusalimschy 321c7fb6f8 details 2001-01-11 16:59:20 -02:00
Roberto Ierusalimschy dabb19fc17 specialized versions for luaH_set (numbers and strings) 2001-01-10 16:56:11 -02:00
Roberto Ierusalimschy 08496eea8b small changes in lstring 2001-01-10 15:41:50 -02:00
Roberto Ierusalimschy 4ff5545709 new macro pushliteral 2001-01-10 14:58:11 -02:00
Roberto Ierusalimschy 595e449537 tighter size for error buffers 2001-01-10 14:40:56 -02:00
Roberto Ierusalimschy a907aeeb1e general corrections 2000-12-28 15:25:45 -02:00
Roberto Ierusalimschy 76f62fc5a1 correct size only after malloc success 2000-12-28 10:59:41 -02:00
Roberto Ierusalimschy 0183b8030c `free' gets size of the block: complete control over memory use 2000-12-28 10:55:41 -02:00
Roberto Ierusalimschy 8c49e19865 explicit control of size for growing vectors 2000-12-26 16:46:09 -02:00
Roberto Ierusalimschy 6af005ec20 bug: when `read' fails it must return nil (and not no value) 2000-12-22 15:32:28 -02:00
Roberto Ierusalimschy f8a0fd268e temporary version 2000-12-22 14:58:41 -02:00
Roberto Ierusalimschy 0066bbbb0b details 2000-12-22 14:57:46 -02:00
Roberto Ierusalimschy 1db05793a0 time' does not need to correct its table argument (use date' for that) 2000-12-22 14:57:13 -02:00
Roberto Ierusalimschy af97be026b new function for time and date 2000-12-18 11:42:19 -02:00
Roberto Ierusalimschy cce8ebd306 obsolete `format' option (d$). 2000-12-18 11:41:41 -02:00
Roberto Ierusalimschy 4894c27962 lua_Number defined in lua.h (1st version) 2000-12-04 16:33:40 -02:00
Roberto Ierusalimschy 10ac68c648 first implementation for position captures 2000-12-04 12:43:06 -02:00
Roberto Ierusalimschy 01b00cc292 better control over extensions of char/short to int 2000-11-30 16:50:47 -02:00
Roberto Ierusalimschy fc7b167ae0 BUG: parser does not accept a ;' after a return' 2000-11-29 09:57:42 -02:00
Roberto Ierusalimschy 96253ed8ce better support for 64-bit machines (avoid excessive use of longs) 2000-11-24 15:39:56 -02:00
Roberto Ierusalimschy 35d6b15057 some cleaning 2000-11-23 11:49:35 -02:00
Roberto Ierusalimschy 22914afab3 avoid the use of (non const) static data 2000-11-23 11:47:39 -02:00
Roberto Ierusalimschy 523c5d8e1c last changes by lhf. 2000-11-07 10:44:44 -02:00
Roberto Ierusalimschy 40a4c76773 setlinehook/setcallhook return old hook 2000-11-06 15:58:38 -02:00
Roberto Ierusalimschy 1385d81d20 2000-11-06 11:45:18 -02:00
Roberto Ierusalimschy 906d5dcc41 details 2000-11-06 11:45:18 -02:00
Roberto Ierusalimschy 93a5649d40 hooks may call `error' to break a chunk. 2000-11-06 11:19:08 -02:00
Roberto Ierusalimschy df416661cc many changes 2000-10-31 16:20:01 -02:00
Roberto Ierusalimschy 67c1afff59 lua_settagmethod does not return old tag method 2000-10-31 11:10:24 -02:00
Roberto Ierusalimschy 03770ecfc9 comments 2000-10-31 10:44:07 -02:00
Roberto Ierusalimschy 7409678b5d DEBUG renamed to LUA_DEBUG 2000-10-30 15:50:00 -02:00
Roberto Ierusalimschy d1c689af40 subtelties in layout of TString 2000-10-30 15:49:19 -02:00
Roberto Ierusalimschy 37e9c2e744 macro DEBUG renamed to LUA_DEBUG 2000-10-30 14:29:59 -02:00
Roberto Ierusalimschy e42a219eeb `lua_typename' accepts LUA_TNONE 2000-10-30 11:07:48 -02:00
Roberto Ierusalimschy b3959d58ff 2000-10-30 10:50:09 -02:00
Roberto Ierusalimschy f379d06e24 all API functions are declared in a single line (to facilitate pre-processing). 2000-10-30 10:38:50 -02:00
Roberto Ierusalimschy 728ff20701 details 2000-10-30 10:20:29 -02:00
Roberto Ierusalimschy 2cbbf3933a new macro LUALIB_API (so the lib can be a separate DLL) 2000-10-27 14:15:53 -02:00
Roberto Ierusalimschy e2b6b7de1b details 2000-10-27 09:39:52 -02:00
Roberto Ierusalimschy 563b1f5704 new way to ensure uniqueness of registry keys 2000-10-26 17:04:22 -02:00
Roberto Ierusalimschy 4670476584 details. 2000-10-26 16:44:26 -02:00
Roberto Ierusalimschy 89f98c0995 in function `read_file', realloc() doesn't free the buffer if it can't
allocate new memory
2000-10-26 10:53:55 -02:00
Roberto Ierusalimschy b892f0a877 new API function `createuserdata' 2000-10-26 10:47:05 -02:00
Roberto Ierusalimschy aadc35449e lua_settag does not pop its argument 2000-10-24 17:19:15 -02:00
Roberto Ierusalimschy cdc8139e29 registry mechanism 2000-10-24 17:12:06 -02:00
Roberto Ierusalimschy e833bd47c9 comments 2000-10-24 14:05:59 -02:00
Roberto Ierusalimschy b7ffb128cb it is unsafe to allow Lua to get gc tag methods 2000-10-20 14:57:42 -02:00
Roberto Ierusalimschy 64eecc0b82 new macro LUA_API 2000-10-20 14:39:03 -02:00
Roberto Ierusalimschy 8b88ab07f7 more controled use of `sprintf' 2000-10-20 14:36:32 -02:00
Roberto Ierusalimschy 2779ceeb12 ((n)-1) may be negative (-1), and so it is not wise to keep it as unsigned 2000-10-18 15:19:09 -02:00
Roberto Ierusalimschy e93c4547fe no more USERINIT (macro) 2000-10-17 11:36:24 -02:00
Roberto Ierusalimschy 0ffc676ce7 details 2000-10-11 14:47:50 -02:00
Roberto Ierusalimschy 18fb3ddb89 details. 2000-10-10 17:52:58 -02:00
Roberto Ierusalimschy 2bddbe6603 cannot change filename' before eventual call to freopen' 2000-10-10 17:51:39 -02:00
Roberto Ierusalimschy e323338fd0 `nlineinfo' must include end flag. 2000-10-10 17:51:15 -02:00
Roberto Ierusalimschy 46b543ebef better treatment for errors inside _ERRORMETHOD 2000-10-09 13:46:43 -02:00
Roberto Ierusalimschy 79909a92e1 details 2000-10-09 11:47:46 -02:00
Roberto Ierusalimschy d6232a0b2e better treatment for source names 2000-10-09 11:47:32 -02:00
Roberto Ierusalimschy ae63a0e692 new implementation for some API functions 2000-10-06 16:29:26 -03:00
Roberto Ierusalimschy cd3d446957 detail 2000-10-06 16:28:47 -03:00
Roberto Ierusalimschy f01e6c6f1d small optimization in `sort' 2000-10-06 16:13:29 -03:00
Roberto Ierusalimschy ad3816d0d1 luaD_call is more uniform 2000-10-06 09:45:25 -03:00
Roberto Ierusalimschy 046a3d6173 tag methods are always functions, so don't need to store a whole object 2000-10-05 10:00:17 -03:00
Roberto Ierusalimschy 001f2bdd0e new definition for types-tags 2000-10-05 09:14:08 -03:00
Roberto Ierusalimschy cd2ddaded9 call hooks can only be called when `pc' is active (that is, inside
`execute'...)
2000-10-04 09:16:08 -03:00
Roberto Ierusalimschy d68209e822 details. 2000-10-03 11:27:44 -03:00
Roberto Ierusalimschy 1088cde03c easier way to change type Number 2000-10-03 11:03:21 -03:00
Roberto Ierusalimschy 6759f3ec5e no more `proprietary' convertion algorithm (too complex) 2000-10-03 11:03:21 -03:00
Roberto Ierusalimschy f6834f4393 new API function `lua_type' + new type lua_Type 2000-10-02 17:10:55 -03:00
Roberto Ierusalimschy 78bc8e553d new API for garbage collector 2000-10-02 11:47:43 -03:00
Roberto Ierusalimschy dad808a73a new way to count `nblocks' for GC (try to count bytes). 2000-09-29 09:42:13 -03:00
Roberto Ierusalimschy ca7fd50a4e small optimizations 2000-09-29 09:40:56 -03:00
Roberto Ierusalimschy 282ab366f4 bug: parser overwrites semantic information when looking ahead 2000-09-27 14:41:58 -03:00
Roberto Ierusalimschy 444d6a106b lua_tag should return LUA_NOTAG for non-valid indices 2000-09-27 09:51:39 -03:00
Roberto Ierusalimschy 13635f7de7 new version of protected execution 2000-09-25 13:22:42 -03:00
Roberto Ierusalimschy d8a442206d lua_state (now called `L') should not be global 2000-09-25 13:15:52 -03:00
Roberto Ierusalimschy c9c6f9747c GC may crash when checking C closures 2000-09-25 11:52:10 -03:00
Roberto Ierusalimschy c2aa7bd72d bug: lua_gettable does not get key from stack top 2000-09-25 11:48:42 -03:00
Roberto Ierusalimschy f9dd50cefc `read("*w")' should return nil at EOF 2000-09-22 15:14:06 -03:00
Roberto Ierusalimschy dbde9f8817 wrong assert 2000-09-21 11:41:25 -03:00
Roberto Ierusalimschy 857a1204d8 by lhf 2000-09-21 11:18:43 -03:00
Roberto Ierusalimschy d742b88fa1 final version (by lhf) 2000-09-20 15:43:54 -03:00
Roberto Ierusalimschy eb822c314a macros to do jumps 2000-09-20 14:57:08 -03:00
Roberto Ierusalimschy ab7aceb980 Tochange 2000-09-20 14:21:20 -03:00
Roberto Ierusalimschy 72b12e0956 error messages in lower case. 2000-09-20 09:54:17 -03:00
Roberto Ierusalimschy 5ed3bcd4ea warnings in Solaris 2000-09-19 05:42:35 -03:00
Roberto Ierusalimschy 7508fed673 final version for 4.0 beta 2000-09-18 16:46:37 -03:00
Roberto Ierusalimschy aab4fde468 changes by lhf 2000-09-18 16:42:05 -03:00
Roberto Ierusalimschy 6ec4a0ef76 updates by lhf 2000-09-18 16:41:16 -03:00
Roberto Ierusalimschy 42ca3105ac small "by 1" bug 2000-09-18 16:39:49 -03:00
Roberto Ierusalimschy 6030d5fed4 avoid assignment to local structure 2000-09-18 16:39:26 -03:00
Roberto Ierusalimschy 91c003dcc2 details 2000-09-18 16:39:18 -03:00
Roberto Ierusalimschy 620d22f2a0 new API function lua_rawget 2000-09-14 11:09:31 -03:00
Roberto Ierusalimschy f45cba42b5 details for OLD_ANSI 2000-09-13 17:12:14 -03:00
Roberto Ierusalimschy 2628a42480 re-implementation of deprecated functions (wiht compiler option) 2000-09-13 16:52:39 -03:00
Roberto Ierusalimschy 0b3b6850c9 `back-up' definition for ERRORMESSAGE 2000-09-12 15:42:32 -03:00
Roberto Ierusalimschy 5d033f33eb details in ERRORMESSAGE 2000-09-12 15:41:55 -03:00
Roberto Ierusalimschy e143fed484 better standard error messages 2000-09-12 15:41:43 -03:00
Roberto Ierusalimschy 01ce1ce48c field short_src 2000-09-12 15:38:25 -03:00
Roberto Ierusalimschy 024ed4218f better name for source_id (short_src) 2000-09-12 15:38:02 -03:00
Roberto Ierusalimschy c1f725ba4a read patterns (deprecated) use new auxlib's buffer system 2000-09-12 10:58:37 -03:00
Roberto Ierusalimschy 5d69960734 error codes as strings for dofile and dostring 2000-09-12 10:49:05 -03:00
Roberto Ierusalimschy d1c351857d ERRORMESSAGE uses auxlib's buffer to build message string 2000-09-12 10:48:34 -03:00
Roberto Ierusalimschy 4ef14ba280 new function `luaL_addstring' 2000-09-12 10:48:22 -03:00
Roberto Ierusalimschy b8d57092eb topointer handles only types that have no other "to" function 2000-09-12 10:47:46 -03:00
Roberto Ierusalimschy 0f59e3d7a7 details 2000-09-12 10:47:39 -03:00
Roberto Ierusalimschy 55c3bc2bcb _ALERT is used (and assumed) only by the libs 2000-09-12 10:46:59 -03:00
Roberto Ierusalimschy 8060193702 `lauxlib' is now part of the libraries (not used by core Lua) 2000-09-11 17:29:27 -03:00
Roberto Ierusalimschy 2779e81fbb API functions check stack overflow 2000-09-11 16:45:27 -03:00
Roberto Ierusalimschy 30f6e658d2 lua_newstate' renamed to lua_open' 2000-09-11 16:42:57 -03:00
Roberto Ierusalimschy 787a78f83e new scheme for buffers 2000-09-11 14:38:42 -03:00
Roberto Ierusalimschy 70c8a31092 obsolete module 2000-09-11 11:44:38 -03:00
Roberto Ierusalimschy 2018380e9f late `lbuiltin.c', now implemented through the official API (and
therefore distributed as a regular library).
2000-09-05 16:33:56 -03:00
Roberto Ierusalimschy 6e80c1cde1 new version for API 2000-09-05 16:33:32 -03:00
Roberto Ierusalimschy f67f324377 deprecated files 2000-09-05 16:28:46 -03:00
Roberto Ierusalimschy eebc9729e4 new versions by lhf 2000-09-04 15:53:41 -03:00
Roberto Ierusalimschy 6990b06467 finish with parse data before doing main chunk. 2000-09-04 15:52:51 -03:00
Roberto Ierusalimschy cad91499dd no more support for single state 2000-09-04 15:27:32 -03:00
Roberto Ierusalimschy ebdd4e8451 `call' doesn't use pack anymore 2000-08-31 18:02:55 -03:00
Roberto Ierusalimschy 9a21e81907 more builtin functions using official API 2000-08-31 18:01:43 -03:00
Roberto Ierusalimschy f0b3cd1d6f new API functions pop', insert', and `move' 2000-08-31 17:23:40 -03:00
Roberto Ierusalimschy fb5e6d5ac4 more functions implemented through the official API 2000-08-31 13:52:06 -03:00
Roberto Ierusalimschy d63afba9d3 negative stack sizes are invalid, too. 2000-08-31 11:28:17 -03:00
Roberto Ierusalimschy 100bfec39a new implementation for `next' 2000-08-31 11:08:27 -03:00
Roberto Ierusalimschy a290b84c67 dohook' to abstract callhook' and `linehook' 2000-08-31 10:31:44 -03:00
Roberto Ierusalimschy 1022b3c85e minimum size for stack 2000-08-31 10:30:39 -03:00
Roberto Ierusalimschy a1d3e001b9 comments 2000-08-31 10:30:22 -03:00
Roberto Ierusalimschy 10b4799ce5 details 2000-08-31 10:30:10 -03:00
Roberto Ierusalimschy a0de89d62a simpler tests for simpler API 2000-08-31 10:29:47 -03:00
Roberto Ierusalimschy 21dc77b2af errors may happen before function start running (with pc=-1) 2000-08-31 10:29:12 -03:00
Roberto Ierusalimschy 2d3ebba537 last version before new API 2000-08-30 15:58:46 -03:00
Roberto Ierusalimschy a97f29f154 explicit stack control in the API 2000-08-29 17:43:28 -03:00
Roberto Ierusalimschy 4135f4f586 new API does not need tests that complex 2000-08-29 16:05:11 -03:00
Roberto Ierusalimschy 808525e417 new asserts for hooks 2000-08-29 16:01:34 -03:00
Roberto Ierusalimschy 48a968e6b5 gc tag method for nil could call line hook 2000-08-29 16:00:57 -03:00
Roberto Ierusalimschy 58adbde216 details 2000-08-29 11:57:23 -03:00
Roberto Ierusalimschy 9e74ca62d7 tests for lua_is* 2000-08-29 11:57:10 -03:00
Roberto Ierusalimschy d396562b5e lua_equal also accepts out-of-range indices 2000-08-29 11:52:27 -03:00
Roberto Ierusalimschy 9d60598260 better definitions for MULTRET 2000-08-29 11:48:16 -03:00
Roberto Ierusalimschy 4e56c0d514 better implementation for luaV_pack 2000-08-29 11:41:56 -03:00
Roberto Ierusalimschy ac12f4db4b C upvalues are the last arguments to a function 2000-08-29 11:33:31 -03:00
Roberto Ierusalimschy b691d4344b L is not unused. 2000-08-28 17:22:21 -03:00
Roberto Ierusalimschy 9fdf73bc9a first version for new API 2000-08-28 14:57:04 -03:00
Roberto Ierusalimschy f1fd9b5c2c intermediate version (only to avoid compiler errors) 2000-08-24 11:19:39 -03:00
Roberto Ierusalimschy 3723d790ae checkstack needs a correct stack 2000-08-22 17:53:30 -03:00
Roberto Ierusalimschy b800c38b69 simpler code for settable and gettable 2000-08-22 17:49:29 -03:00
Roberto Ierusalimschy 5c0e79847c pragmas are no longer supported 2000-08-22 17:07:56 -03:00
Roberto Ierusalimschy e662e0f1cd simpler way to access _INPUT and _OUTPUT 2000-08-22 14:47:17 -03:00
Roberto Ierusalimschy c85162be27 new way to store local-variable information. 2000-08-22 14:44:17 -03:00
Roberto Ierusalimschy bd39db46ed details 2000-08-21 11:34:43 -03:00
Roberto Ierusalimschy 90fb2e18e8 pushref' is more efficient (and probably more useful) than getref'. 2000-08-17 10:18:01 -03:00
Roberto Ierusalimschy 4365c31c89 new name for globaltable. 2000-08-15 17:14:27 -03:00
Roberto Ierusalimschy 44eb7d91ac comments 2000-08-15 15:28:48 -03:00
Roberto Ierusalimschy ddc8d94a08 new name for `lua_[sg]etglobaltable' 2000-08-14 16:18:14 -03:00
Roberto Ierusalimschy 5d9cbdadfb cannot run symbolic execution for non-active functions 2000-08-14 14:59:20 -03:00
Roberto Ierusalimschy 58453dc1e1 small bug in symbolic execution 2000-08-14 14:46:27 -03:00
Roberto Ierusalimschy f555e493f0 lua_state may not exist 2000-08-14 14:46:07 -03:00
Roberto Ierusalimschy d1ffd1a1c5 details 2000-08-14 14:45:59 -03:00
Roberto Ierusalimschy 9e84bf18db still more debug information 2000-08-11 13:17:28 -03:00
Roberto Ierusalimschy daf09c476f still better error messages 2000-08-10 16:50:47 -03:00
Roberto Ierusalimschy e238efc536 default now is multi-state 2000-08-09 16:16:57 -03:00
Roberto Ierusalimschy fdd04e7a7f first version of manual for 4.0 beta 2000-08-09 16:09:20 -03:00
Roberto Ierusalimschy fb55c96706 obsolete module; not part of the oficial distribution 2000-08-09 11:50:13 -03:00
Roberto Ierusalimschy c39bec81dc bug: lastpc was not initialized 2000-08-09 11:49:41 -03:00
Roberto Ierusalimschy 5f22f8961c better code for unary/binary operators 2000-08-09 11:49:13 -03:00
Roberto Ierusalimschy a7c1390ffa syntax "function foo (...)" can be nested 2000-08-08 17:48:55 -03:00
Roberto Ierusalimschy 0802a9df9e no more options for debug information: it is always on 2000-08-08 17:42:07 -03:00
Roberto Ierusalimschy f90bc248b3 new structure for line information 2000-08-08 15:26:05 -03:00
Roberto Ierusalimschy d9e61e8cea new algorithm for traversing in GC to avoid deep recursion calls 2000-08-07 17:21:34 -03:00
Roberto Ierusalimschy 397905ef86 (much) better handling of memory alloction errors 2000-08-07 15:39:16 -03:00
Roberto Ierusalimschy 435f587ed0 (much) better handling of memory alloction errors 2000-08-04 16:38:35 -03:00
Roberto Ierusalimschy ae55f3eead no varargs in Lua API 2000-06-30 16:17:08 -03:00
Roberto Ierusalimschy cfba572076 remove dummy argument in LUA_ASSERT 2000-06-30 11:35:17 -03:00
Roberto Ierusalimschy aa01d2568d symbolic execution must handle return and tailcall 2000-06-30 11:29:35 -03:00
Roberto Ierusalimschy 014a09c509 better error messages 2000-06-28 17:21:06 -03:00
Roberto Ierusalimschy b622282973 local is valid only after adjust 2000-06-28 14:06:07 -03:00
Roberto Ierusalimschy 7f867eb0b9 tests for locals and line numbers 2000-06-28 14:06:07 -03:00
Roberto Ierusalimschy 5362426ffa error message 2000-06-28 14:03:56 -03:00
Roberto Ierusalimschy 906434011f better (?) treatment for 16-bit machines 2000-06-28 14:03:32 -03:00
Roberto Ierusalimschy c07cebbbf6 details 2000-06-27 16:00:36 -03:00
Roberto Ierusalimschy afef009fce new version of debug system 2000-06-26 16:28:31 -03:00
Roberto Ierusalimschy b69e712713 new way to generate SETLINEs 2000-06-21 15:13:56 -03:00
Roberto Ierusalimschy f517759507 details 2000-06-21 14:05:49 -03:00
Roberto Ierusalimschy 52062684e1 better control over use of `errno' 2000-06-20 14:13:21 -03:00
Roberto Ierusalimschy 83e3ec0117 no more labels 2000-06-19 15:26:23 -03:00
Roberto Ierusalimschy feb2083730 better control of source name 2000-06-19 15:05:14 -03:00
Roberto Ierusalimschy 8d2baf719c comment 2000-06-19 15:04:41 -03:00
Roberto Ierusalimschy 88657809ac details 2000-06-19 10:15:15 -03:00
Roberto Ierusalimschy 2e1b32d873 optimizations for "while 1", "until nil", and the like 2000-06-16 14:51:40 -03:00
Roberto Ierusalimschy 89a3ec08f3 function lua_userinit is used only in single-state mode (by lua.c) 2000-06-16 14:22:43 -03:00
Roberto Ierusalimschy e3ea307434 small changes to allow redefinition of some buffer sizes. 2000-06-16 14:16:34 -03:00
Roberto Ierusalimschy 18b0e8270d 32 characteres are more than enough for a good hash 2000-06-15 14:01:12 -03:00
Roberto Ierusalimschy 094880ef9e details 2000-06-12 11:37:18 -03:00
Roberto Ierusalimschy 1de5587184 `lua.h' is included before any other Lua header file 2000-06-12 10:52:05 -03:00
Roberto Ierusalimschy 8ca9534d04 access to `values' in TObject always through macros 2000-06-08 15:27:13 -03:00
Roberto Ierusalimschy 8bcf622876 new signature for `luaH_set' 2000-06-06 13:31:41 -03:00
Roberto Ierusalimschy dbbf6c073b 0 (in MAX_SIZET) may be shorter than size_t 2000-06-06 13:27:11 -03:00
Roberto Ierusalimschy 292c953018 new auxiliar function `luaH_setstr' 2000-06-05 17:15:33 -03:00
Roberto Ierusalimschy c542aac0b9 collect dead indices in tables 2000-06-05 17:07:53 -03:00
Roberto Ierusalimschy dbfb810267 cleansing of lparser.c 2000-06-05 11:56:18 -03:00
Roberto Ierusalimschy 9c14b5e416 new test function to list strings from a function 2000-06-02 16:10:01 -03:00
Roberto Ierusalimschy 6b9bf49265 better to keep foreach' and foreachi'. 2000-06-02 16:08:56 -03:00
Roberto Ierusalimschy 989ad7232a changed to test macros for single-state use 2000-06-02 14:06:42 -03:00
Roberto Ierusalimschy 190c3be739 details 2000-05-31 13:53:30 -03:00
Roberto Ierusalimschy 7e30900def better field name 2000-05-30 16:00:31 -03:00
Roberto Ierusalimschy f63d7753b8 files are closed when collected (again) 2000-05-30 15:55:16 -03:00
Roberto Ierusalimschy 50a82ec1b9 gc tag methods for udata are called in (reverse) tag order 2000-05-30 15:54:49 -03:00
Roberto Ierusalimschy ed1751bc32 details 2000-05-29 11:48:03 -03:00
Roberto Ierusalimschy 8e617985fa functions for...' and raw...' are obsolete now 2000-05-26 16:17:57 -03:00
Roberto Ierusalimschy c39345fba3 no more pragmas 2000-05-26 11:04:04 -03:00
Roberto Ierusalimschy ed94a85f0c type details 2000-05-25 16:02:21 -03:00
Roberto Ierusalimschy 58fbdc76d5 better implementation for looh-ahead 2000-05-25 15:59:59 -03:00
Roberto Ierusalimschy a301304612 accepts `$debug' in the middle of a function. 2000-05-25 15:26:42 -03:00
Roberto Ierusalimschy 677313da32 bug: record-constructor starting with an upvalue name gets an error 2000-05-24 15:04:17 -03:00
Roberto Ierusalimschy ef62b340e0 code cleaner for 16 bits. 2000-05-24 10:54:49 -03:00
Roberto Ierusalimschy 5c2dd7a9e0 array `luaK_opproperties' keeps delta stack and mode for each opcode 2000-05-22 15:44:46 -03:00
Roberto Ierusalimschy 93d93a0bfb first implementation of `for' over tables 2000-05-15 16:48:04 -03:00
Roberto Ierusalimschy 9e1f94fc1c cannot change value of private locals (used to implement `for') 2000-05-15 16:30:41 -03:00
Roberto Ierusalimschy 8714cc02d6 `getinfo' gets information about non-active functions, too. 2000-05-12 16:49:18 -03:00
Roberto Ierusalimschy 69b45bb4e9 changes by lhf 2000-05-12 16:19:18 -03:00
Roberto Ierusalimschy 843f84f4ce first element in a list constructor is not adjusted to one value. 2000-05-12 15:12:04 -03:00
Roberto Ierusalimschy b803c0600e details 2000-05-11 15:57:19 -03:00
Roberto Ierusalimschy 8ac0bbf64b new option `-c' to close lua. 2000-05-10 14:00:21 -03:00
Roberto Ierusalimschy dc1e4f5073 missing define for `lua_dobuffer' single-state 2000-05-10 13:35:18 -03:00
Roberto Ierusalimschy 330e51bed3 string hash uses one single hash table 2000-05-10 13:33:20 -03:00
Roberto Ierusalimschy 44b71ca816 defines for _ERRORMESSAGE and _ALERT 2000-05-09 11:50:16 -03:00
Roberto Ierusalimschy bad6365540 details 2000-05-08 17:49:05 -03:00
Roberto Ierusalimschy 91f34fb05c lua.h should not use names without prefix lua_ (`TObject', for instance) 2000-05-08 16:37:10 -03:00
Roberto Ierusalimschy 11a7022067 global variables are stored in a Lua table 2000-05-08 16:32:53 -03:00
Roberto Ierusalimschy 35a6ed2838 detail (error message) 2000-05-08 15:46:34 -03:00
Roberto Ierusalimschy cfe6ca819b default for `getstack' is to get everything 2000-05-08 10:21:35 -03:00
Roberto Ierusalimschy fe5c37ae95 BUG: `strfind' gets wrong subject length when there is an offset 2000-05-02 15:32:22 -03:00
Roberto Ierusalimschy c31f02948f [C++ Warning] lparser.c(326): W8066 Unreachable code.
[C++ Warning] lparser.c(486): W8004 'nargs' is assigned a value that is never used.
2000-04-27 14:39:56 -03:00
Roberto Ierusalimschy c9f91c6fe3 [C++ Warning]: W8084 Suggest parentheses to clarify precedence. 2000-04-27 14:39:15 -03:00
Roberto Ierusalimschy 66d620674c IntPoint does not need L 2000-04-26 10:43:25 -03:00
Roberto Ierusalimschy 84790bb953 "conceptual" bug 2000-04-26 10:43:10 -03:00
Roberto Ierusalimschy 534c3a64d3 small optimizations for table access 2000-04-25 13:55:09 -03:00
Roberto Ierusalimschy b9c98cd4d9 entry for new version (4.0a) 2000-04-25 13:45:39 -03:00
Roberto Ierusalimschy 0e8855e171 final version (by lhf) 2000-04-25 13:44:31 -03:00
Roberto Ierusalimschy 2ae9c856cf more uniform names 2000-04-24 18:05:11 -03:00
Roberto Ierusalimschy c4409f69ab details 2000-04-19 10:41:37 -03:00
Roberto Ierusalimschy 89a9c36281 no more `register' declarations: leave it to the compiler. 2000-04-19 10:36:25 -03:00
Roberto Ierusalimschy 8f2fba5877 using new constructs (for & break) in the examples and code fragments 2000-04-17 16:23:48 -03:00
Roberto Ierusalimschy 62824137d6 no more `seterrormethod' function 2000-04-17 16:23:12 -03:00
Roberto Ierusalimschy 71219ccc39 simpler version of `luaK_tostack' 2000-04-17 11:05:34 -03:00
Roberto Ierusalimschy 870f61d299 code redistribution 2000-04-14 15:12:35 -03:00
Roberto Ierusalimschy c845ec777a new order for modules (better locality??) 2000-04-14 14:52:09 -03:00
Roberto Ierusalimschy e408cf61a2 new version number 2000-04-14 14:48:20 -03:00
Roberto Ierusalimschy 4e90768635 lots of changes (almost ready for 4.0) 2000-04-14 14:47:55 -03:00
Roberto Ierusalimschy c1666a13e3 better code organization 2000-04-14 14:47:24 -03:00
Roberto Ierusalimschy e02750ec60 new type for CFunction (for "pure" C) 2000-04-14 14:46:37 -03:00
Roberto Ierusalimschy 0b56646baf new function `getargs' 2000-04-14 14:46:29 -03:00
Roberto Ierusalimschy 634c3d57e9 optimization for SETLOCAL was too specific. 2000-04-14 14:46:15 -03:00
Roberto Ierusalimschy 4aa9ad6514 functions must return explicit `nil' on failure 2000-04-14 14:44:20 -03:00
Roberto Ierusalimschy d76b1a0eef base' for tonumber' must be >= 2. 2000-04-13 15:08:18 -03:00
Roberto Ierusalimschy e7c8393682 optimization INCLOCAL is not necessary, with `for' 2000-04-13 13:51:01 -03:00
Roberto Ierusalimschy ceaa97ff5b tonumber must return `nil' when convertion fails. 2000-04-13 13:46:43 -03:00
Roberto Ierusalimschy 2bb77cdaed keep opcodes in the right order 2000-04-12 16:56:50 -03:00
Roberto Ierusalimschy f9cf402fbd first implementation of FOR 2000-04-12 15:57:19 -03:00
Roberto Ierusalimschy 0c3fe2c44b comment 2000-04-12 15:47:03 -03:00
Roberto Ierusalimschy 0433e42023 no more repeat ... end. 2000-04-11 15:37:18 -03:00
Roberto Ierusalimschy 0810bc707f new syntax: |label| 2000-04-10 16:21:14 -03:00
Roberto Ierusalimschy c3b73cbeb8 comments (detail) 2000-04-10 16:20:24 -03:00
Roberto Ierusalimschy 1eabd0549e comments 2000-04-07 16:35:31 -03:00
Roberto Ierusalimschy 54dd5cc7fd reorganization of lcode.c 2000-04-07 16:35:20 -03:00
Roberto Ierusalimschy 031978798c more optimizations 2000-04-07 10:13:11 -03:00
Roberto Ierusalimschy 14251c5a56 name changes + new operation - old operation 2000-04-07 10:12:50 -03:00
Roberto Ierusalimschy 42130ed712 name changes 2000-04-07 10:11:49 -03:00
Roberto Ierusalimschy d615e78e08 new optimization: jumps to jumps 2000-04-06 14:36:52 -03:00
Roberto Ierusalimschy c6965ce551 new functions: disassembler and get limit. 2000-04-06 14:35:23 -03:00
Roberto Ierusalimschy 22329e4cdf implementation of BREAK 2000-04-05 14:51:58 -03:00
Roberto Ierusalimschy 9f734094f9 `nil' is optional for next and nextvar (and is not for tonumber & tag). 2000-04-04 17:49:32 -03:00
Roberto Ierusalimschy 4e7e9e8de5 new opcode INCLOCAL. 2000-04-04 17:48:44 -03:00
Roberto Ierusalimschy 3e45496295 syntactical details 2000-04-03 10:44:55 -03:00
Roberto Ierusalimschy e30327728c BUG: tostring() without arguments gives seg. fault. 2000-04-03 10:20:33 -03:00
Roberto Ierusalimschy 36e1390631 details. 2000-03-31 13:28:45 -03:00
Roberto Ierusalimschy 8f0f54ec38 name change 2000-03-30 17:55:50 -03:00
Roberto Ierusalimschy 556a89e537 new names for debug types 2000-03-30 14:19:48 -03:00
Roberto Ierusalimschy e2c60eda16 `luaT_validevent' is exported, because compatibility module for fallbacks
uses it.
2000-03-30 13:41:51 -03:00
Roberto Ierusalimschy a69356e9e0 no more special cases for closures with 0 upvalues (performance is the same,
memory use a little higher, code much simpler).
2000-03-29 17:19:20 -03:00
Roberto Ierusalimschy b53dc0c485 TAG_ARRAY -> TAG_TABLE 2000-03-27 17:10:21 -03:00
Roberto Ierusalimschy 63e230a16b comments 2000-03-27 17:08:33 -03:00
Roberto Ierusalimschy 102a1be615 no more support for gc TM for tables 2000-03-27 17:08:02 -03:00
Roberto Ierusalimschy 4c03196697 lua_setstate makes no sense with explicit multiple states 2000-03-27 11:00:35 -03:00
Roberto Ierusalimschy 54633d7c7d new name for llimits.h 2000-03-24 16:49:23 -03:00
Roberto Ierusalimschy 13578517c7 new file to keep all limits and instalation-dependent definitions 2000-03-24 14:26:08 -03:00
Roberto Ierusalimschy 213e9febc8 limits now are in `llims.n' 2000-03-24 14:26:08 -03:00
Roberto Ierusalimschy 47b4bf5964 small refactoring. 2000-03-24 09:18:30 -03:00
Roberto Ierusalimschy 415ee1a24f SETLINEs for reserved words, too. 2000-03-24 09:17:53 -03:00
Roberto Ierusalimschy 5f3c5ace95 message detail 2000-03-22 13:24:13 -03:00
Roberto Ierusalimschy 441469f803 new option `-s' + argv ends with NULL (so we don't need argc). 2000-03-20 17:27:32 -03:00
Roberto Ierusalimschy 1157c2a7e4 better(?) treatment for SETLINE + while optimization is too complex for
only 3% of maximum improvement.
2000-03-20 16:15:37 -03:00
Roberto Ierusalimschy 374cc888f4 better(?) treatment for SETLINE 2000-03-20 16:15:37 -03:00
Roberto Ierusalimschy bb9605bbc9 tags can be positive values 2000-03-20 16:14:54 -03:00
Roberto Ierusalimschy 6759299880 new implementation for handling I/O tags + setglobal TM for tracing
changes in _INPUT/_OUTPUT
2000-03-20 16:13:45 -03:00
Roberto Ierusalimschy da7eb34cd6 optimization for "while 1" and "repeat until nil" 2000-03-17 11:46:04 -03:00
Roberto Ierusalimschy 2c8e28d75a small changes 2000-03-17 10:09:46 -03:00
Roberto Ierusalimschy 4fb8e93c36 small optimization for i..'' 2000-03-17 10:09:12 -03:00
Roberto Ierusalimschy 7f77431950 detail 2000-03-16 18:06:16 -03:00
Roberto Ierusalimschy 87367e97f3 more information about memory use 2000-03-16 17:35:07 -03:00
Roberto Ierusalimschy 06f08f5634 small problems with limits and jumps 2000-03-16 15:03:09 -03:00
Roberto Ierusalimschy 3860c5934e details. 2000-03-15 17:50:33 -03:00
Roberto Ierusalimschy f0b697e01c details 2000-03-13 17:37:16 -03:00
Roberto Ierusalimschy 73aa465a8e some name changes 2000-03-10 15:37:44 -03:00
Roberto Ierusalimschy 3d0577f4b9 small optimizations. 2000-03-10 11:38:10 -03:00
Roberto Ierusalimschy 977b8f65f0 comment detail. 2000-03-10 11:01:05 -03:00
Roberto Ierusalimschy e3cf93ddb6 first implementation of "threaded code" for boolean operations 2000-03-09 10:57:37 -03:00
Roberto Ierusalimschy 88b306f495 some optimizations 2000-03-08 21:19:22 -03:00
Roberto Ierusalimschy 563de491be a better way to control optimizations. 2000-03-04 17:18:15 -03:00
Roberto Ierusalimschy 29e0193425 details 2000-03-03 17:30:47 -03:00
Roberto Ierusalimschy 61f97a8ace maybe a concat right associative allows some optimizations... 2000-03-03 17:29:25 -03:00
Roberto Ierusalimschy d1ea38580a change of code generation design (independent functions for each opcode) 2000-03-03 15:53:17 -03:00
Roberto Ierusalimschy 3c9d999424 many details (most by lhf). 2000-03-03 11:58:26 -03:00
Roberto Ierusalimschy f7840a3e0b new algorithm to parse expressions + distribution of code between lparser
and lcode.
2000-03-03 09:33:59 -03:00
Roberto Ierusalimschy 1780e2c977 lua_settable should check stack space (it could call a T.M.) 2000-03-02 09:44:29 -03:00
Roberto Ierusalimschy fa14cbf8e8 comments 2000-03-02 09:32:53 -03:00
Roberto Ierusalimschy 4d4e6f07c0 all order operators use a single tag method (<) 2000-02-22 16:12:46 -02:00
Roberto Ierusalimschy 5cecf0ea9f it is better to control stack space where it is needed. 2000-02-22 15:54:16 -02:00
Roberto Ierusalimschy 3bc925138e first version of code optimizer 2000-02-22 11:31:43 -02:00
Roberto Ierusalimschy 39e1f079bd code generator (and optimizer) for Lua 2000-02-22 11:31:19 -02:00
Roberto Ierusalimschy 075da266e5 there is no need to use shorts... 2000-02-21 16:33:26 -02:00
Roberto Ierusalimschy 228a62f799 details 2000-02-21 16:30:42 -02:00
Roberto Ierusalimschy 7c2fb15bec need "string.h" to use "strchr". 2000-02-21 16:30:06 -02:00
Roberto Ierusalimschy 1f01998516 nobody uses memmove any more. 2000-02-17 16:30:36 -02:00
Roberto Ierusalimschy c929376d59 must include a definition for NULL 2000-02-17 16:30:36 -02:00
Roberto Ierusalimschy 3afe85b2ce new version for INSTRUCTION formats 2000-02-14 14:51:08 -02:00
Roberto Ierusalimschy 52aad0ab59 removing implementation for better error messages (must rethink it...) 2000-02-11 14:52:54 -02:00
Roberto Ierusalimschy 74f1c3d025 small changes for "clean C" 2000-02-08 14:39:42 -02:00
Roberto Ierusalimschy 1f691a4fcd renaming of some opcodes and fields 2000-01-28 14:53:00 -02:00
Roberto Ierusalimschy d6b9f49aaf only need to reset buffer for strings, numbers, and names. 2000-01-26 16:51:49 -02:00
Roberto Ierusalimschy d83c2a8455 performance details. 2000-01-25 16:44:21 -02:00
Roberto Ierusalimschy d11e5adf55 `const' array in protos breaked in 3 arrays (for strings, numbers, and
prototypes).
2000-01-25 11:57:18 -02:00
Roberto Ierusalimschy 99e340b2ba keep `top' in registers when running basic tasks (settable, getglobal, ...) 2000-01-24 18:14:07 -02:00
Roberto Ierusalimschy 9744255ae9 error in call must be propagated 2000-01-24 18:11:26 -02:00
Roberto Ierusalimschy 512b15b601 small optimizations (relational operators) 2000-01-19 14:50:30 -02:00
Roberto Ierusalimschy 33d3504889 new debug API 2000-01-19 14:50:14 -02:00
Roberto Ierusalimschy 2877bad4c2 new debug API (first version) 2000-01-19 10:00:45 -02:00
Roberto Ierusalimschy 27163f032e Auxiliary functions from Debug Interface module 2000-01-14 15:15:44 -02:00
Roberto Ierusalimschy eab57ed6fd details 2000-01-13 14:30:47 -02:00
Roberto Ierusalimschy ea45f3eb28 better separation between debug code and regular code 2000-01-13 14:30:47 -02:00
Roberto Ierusalimschy 46ec57cbc6 little change when calling tag methods 2000-01-13 13:56:03 -02:00
Roberto Ierusalimschy 62787f1b1f `exp' is "reserved word" in Visual-C++ ;-) 2000-01-12 14:24:39 -02:00
Roberto Ierusalimschy dcb7bb514e details (error messages) 2000-01-10 15:34:38 -02:00
Roberto Ierusalimschy b3aaa048b0 bug: cannot reopen stdin (for binary mode) 1999-12-30 16:40:57 -02:00
Roberto Ierusalimschy aee07c6599 details 1999-12-30 16:29:46 -02:00
Roberto Ierusalimschy bcdbdaccc3 more debug information (still with bug for tag methods...) 1999-12-30 16:28:40 -02:00
Roberto Ierusalimschy 5cafe5af02 tag method must be a function 1999-12-30 16:27:03 -02:00
Roberto Ierusalimschy 607012ece1 tag method must be a function
+ error message must be a string
1999-12-30 16:27:03 -02:00
Roberto Ierusalimschy 0652906e7a details. 1999-12-30 10:40:29 -02:00
Roberto Ierusalimschy 4d1b815b60 return gives wrong line in debug information. 1999-12-29 16:07:10 -02:00
Roberto Ierusalimschy 4ebc183e56 bug: return gives wrong line in debug information. 1999-12-29 16:07:10 -02:00
Roberto Ierusalimschy 298d0abff7 first version of extra debug information (NAME) 1999-12-29 14:31:15 -02:00
Roberto Ierusalimschy 4fbe775154 details 1999-12-29 14:24:03 -02:00
Roberto Ierusalimschy aabefe9d68 details. 1999-12-28 17:23:41 -02:00
Roberto Ierusalimschy fb60283974 better error messages 1999-12-28 09:52:49 -02:00
Roberto Ierusalimschy acdb0b741e comments. 1999-12-27 15:33:22 -02:00
Roberto Ierusalimschy 5b08fcd5a1 no more "lua" in error messages 1999-12-27 11:04:53 -02:00
Roberto Ierusalimschy b1b0c219f5 new ttypes to distinguish between C closures and Lua closures. 1999-12-23 16:19:57 -02:00
Roberto Ierusalimschy be3212de78 details 1999-12-22 14:58:36 -02:00
Roberto Ierusalimschy 2eaf9a00ae little bug: `1ea' got a wrong token at the error message 1999-12-22 14:58:36 -02:00
Roberto Ierusalimschy 6c79a0a80d new way to control hooks inside hooks (now the control is done inside Lua) 1999-12-21 16:04:41 -02:00
Roberto Ierusalimschy 3daeabb606 new way to pass arguments: with option `-f' 1999-12-21 15:34:23 -02:00
Roberto Ierusalimschy cfdebfbc53 debug information for parameters use line 0 for them (as they are
always visible).
1999-12-21 15:31:28 -02:00
Roberto Ierusalimschy d61d5bef9d details 1999-12-20 11:10:38 -02:00
Roberto Ierusalimschy 4450efc97e new chunkid for C functions (`luaL_chunkid') 1999-12-20 11:09:45 -02:00
Roberto Ierusalimschy de65253f2d new way to handle _PROMPT 1999-12-20 11:03:20 -02:00
Roberto Ierusalimschy 12b45c2df2 luaS_newfixedstring renamed to luaS_newfixed 1999-12-14 16:42:57 -02:00
Roberto Ierusalimschy 1b15206cf9 many details + code redistribution 1999-12-14 16:33:29 -02:00
Roberto Ierusalimschy e6d56cd2d8 module for internal use only, with functions for internal tests 1999-12-14 16:31:20 -02:00
Roberto Ierusalimschy c16c63cc59 new module with the debug API functions 1999-12-14 16:31:20 -02:00
Roberto Ierusalimschy dea54a7c71 comments 1999-12-09 18:01:48 -02:00
Roberto Ierusalimschy 544eeb1f9c details 1999-12-07 10:05:34 -02:00
Roberto Ierusalimschy b3fe203c36 keep it simple 1999-12-07 10:05:34 -02:00
Roberto Ierusalimschy 9c142740c1 stack may not be empty after a correct run... 1999-12-07 09:42:54 -02:00
Roberto Ierusalimschy 7621cc2aa5 for the future... 1999-12-07 09:36:16 -02:00
Roberto Ierusalimschy ba1f504970 `optimization' doesn't seem to make any difference... 1999-12-06 17:30:53 -02:00
Roberto Ierusalimschy 617be66015 better control (and error recovery) for begin/end blocks 1999-12-06 10:03:45 -02:00
Roberto Ierusalimschy f356eb010b configurable stack size + some corrections in error recovery in
`protectedrun'
1999-12-06 09:43:58 -02:00
Roberto Ierusalimschy 3e38fd2463 `lua_setfallback' leaves things on the stack, so it is better to protect
it.
1999-12-06 09:43:09 -02:00
Roberto Ierusalimschy 533beedad2 new tests for begin/end blocks and multi-state 1999-12-06 09:42:18 -02:00
Roberto Ierusalimschy 968ad49da6 `lua_newstate' gets the inital stack size and other arguments 1999-12-06 09:41:28 -02:00
Roberto Ierusalimschy 1fdb445e7d details. 1999-12-06 09:40:55 -02:00
Roberto Ierusalimschy c7119a93f0 new language for testC (debugging facility) 1999-12-03 16:02:54 -02:00
Roberto Ierusalimschy 3c9e29f56d details 1999-12-03 09:26:23 -02:00
Roberto Ierusalimschy 72afb6debb modifications by lhf 1999-12-02 17:11:51 -02:00
Roberto Ierusalimschy b097076678 missing include 1999-12-02 14:41:29 -02:00
Roberto Ierusalimschy 8223ff473f lua_Object is a pointer to the stack (because now the stack doen't move) 1999-12-02 14:24:45 -02:00
Roberto Ierusalimschy fe237ad808 fixed stack; first version. 1999-12-01 17:50:08 -02:00
Roberto Ierusalimschy 3181dfefee details 1999-11-30 11:06:50 -02:00
Roberto Ierusalimschy 764e095d7f object' and string' are very busy names... 1999-11-29 17:31:29 -02:00
Roberto Ierusalimschy 2b3ea61342 mistake in change for multi-state (gc threshold was not corrected) 1999-11-29 17:12:07 -02:00
Roberto Ierusalimschy 49af08e3e7 new name for lua_equal(obj); LUA_NOOBJECT is equal to LUA_NOOBJECT 1999-11-29 17:11:36 -02:00
Roberto Ierusalimschy c5fa0895e9 table sizes don't need to be primes; power of 2 gives the same performance. 1999-11-29 14:38:48 -02:00
Roberto Ierusalimschy d015f1fc02 table sizes don't need to be primes; power of 2 gives the same performance. 1999-11-26 16:59:20 -02:00
Roberto Ierusalimschy 790690a223 new way to keep function arguments (with StkId instead of copy) 1999-11-26 16:53:03 -02:00
Roberto Ierusalimschy 33b8a01032 new way to code CALLs + passing multiple arguments between function calls 1999-11-25 16:59:43 -02:00
Roberto Ierusalimschy d29ce75737 new signature for function luaD_call (old luaD_calln) 1999-11-25 16:58:51 -02:00
Roberto Ierusalimschy 878ef96127 comment 1999-11-25 16:44:02 -02:00
Roberto Ierusalimschy e5743adb21 macros key', val', and `node' don't need the state 1999-11-23 11:58:02 -02:00
Roberto Ierusalimschy 514783de9d simpler without `init_hash' 1999-11-22 16:24:50 -02:00
Roberto Ierusalimschy 7d1499ba88 new macro luaL_openl 1999-11-22 15:39:51 -02:00
Roberto Ierusalimschy 29ede6aa13 first implementation of multiple states (reentrant code). 1999-11-22 11:12:07 -02:00
Roberto Ierusalimschy 951897c093 last warnings in Visual C 1999-11-16 10:50:48 -02:00
Roberto Ierusalimschy a34677e4f4 details 1999-11-12 11:54:44 -02:00
Roberto Ierusalimschy 573372665a new API function `lua_equalobj' 1999-11-11 15:02:40 -02:00
Roberto Ierusalimschy a6755e2f1a BUG: `strfind' does not handle \0 in plain search. 1999-11-11 14:45:04 -02:00
Roberto Ierusalimschy a4628a02cf better ways to test lock mechanism 1999-11-10 13:41:11 -02:00
Roberto Ierusalimschy 0c725b2492 buffer can shrink when too big 1999-11-10 13:40:46 -02:00
Roberto Ierusalimschy d915cf4f9d ways to measure number of `blocks' for GC + details 1999-11-10 13:39:35 -02:00
Roberto Ierusalimschy 53fb65d394 better implementation of `lua_ref' (much better...) 1999-11-10 13:37:50 -02:00
Roberto Ierusalimschy a7fa7bafc8 new warnings with option "-W" (gcc) 1999-11-09 15:59:35 -02:00
Roberto Ierusalimschy cde179b369 new implementation for global variable values (separated from strings) 1999-11-04 15:23:12 -02:00
Roberto Ierusalimschy 80b39d83c3 default `success' for exit is more useful. 1999-10-26 09:00:12 -02:00
Roberto Ierusalimschy 5a48255c9f invariant tests over tables performed externally, through a built-in
function (when DEBUG is ion).
1999-10-26 08:53:40 -02:00
Roberto Ierusalimschy bbab974717 details (comments) 1999-10-25 11:35:44 -02:00
Roberto Ierusalimschy 910836fb53 warnings from Visual C++ 1999-10-19 11:33:22 -02:00
Roberto Ierusalimschy 8e7451512f some more `const's 1999-10-14 17:46:57 -02:00
Roberto Ierusalimschy 4e9f2d13d5 new implementation of hash tables. 1999-10-14 17:13:31 -02:00
Roberto Ierusalimschy b6ebbb2fee better assertions. 1999-10-14 15:53:35 -02:00
Roberto Ierusalimschy c5fee7615e new implementation for string hashing, with chaining. 1999-10-11 14:13:42 -02:00
Roberto Ierusalimschy cca78b5c71 Visual C++ warning 1999-10-11 14:06:01 -02:00
Roberto Ierusalimschy d435b7acd8 read patterns are deprecated; new option `read(n)' to read n bytes. 1999-10-07 17:18:36 -02:00
Roberto Ierusalimschy 63ccf42397 new API function 'lua_type'. 1999-10-07 17:04:30 -02:00
Roberto Ierusalimschy 1942b58609 details 1999-10-05 16:33:43 -02:00
Roberto Ierusalimschy 4343420d4d simplified version of `gc' tag method (only for userdata now). 1999-10-04 15:51:04 -02:00
Roberto Ierusalimschy 1f7103e05d implementation of lua_ref (previously in module `lmem'). 1999-10-04 15:50:24 -02:00
Roberto Ierusalimschy dcc10accea temporary version 1999-09-29 09:56:22 -03:00
Roberto Ierusalimschy e2fc5aa684 checks table size only when element is a new one 1999-09-28 09:27:06 -03:00
Roberto Ierusalimschy d53e2d2386 details 1999-09-27 15:00:25 -03:00
Roberto Ierusalimschy cf9a22396c "luaH_set" only needs to check size when key is new 1999-09-22 11:38:45 -03:00
Roberto Ierusalimschy 17374d2daa `put_luaObjectonTop' must be public (to be used by lfback.c), and so
it must have a "public" name: `luaA_putObjectOnTop'
1999-09-21 13:10:13 -03:00
Roberto Ierusalimschy 04265655a8 compatibility with old fallback system now provided by external module 1999-09-20 11:57:29 -03:00
Roberto Ierusalimschy e10788b2ff reorganization of `stat' function. 1999-09-20 11:15:18 -03:00
Roberto Ierusalimschy 7eb2f18621 remove of some useless #includes 1999-09-17 13:53:54 -03:00
Roberto Ierusalimschy a8a75fb7ab details 1999-09-13 16:42:02 -03:00
Roberto Ierusalimschy ae3ecc2d4a tonumber'e1' and tonumber(' ', x), for x!=10, gave 0 instead of nil. 1999-09-08 17:45:18 -03:00
Roberto Ierusalimschy 2e13cd77ab new interface for `luaO_strtod', which now checks signal, too. 1999-09-06 17:34:18 -03:00
Roberto Ierusalimschy ff9c0da783 test first the most common case. 1999-09-06 17:19:22 -03:00
Roberto Ierusalimschy f7fe04d4b7 details. 1999-09-06 12:24:46 -03:00
Roberto Ierusalimschy 82699d0c4f new interface for `luaO_strtod', which now checks signal, too. 1999-09-06 10:55:09 -03:00
Roberto Ierusalimschy 88866208f0 luaL_arg_check' always has an extramsg'. 1999-09-06 10:13:03 -03:00
Roberto Ierusalimschy 7d365a5c7a in the (old) expression << ls->fs->f->consts[checkname(ls)] >>, checkname
could realloc f->consts.
1999-09-02 10:13:22 -03:00
Roberto Ierusalimschy 52a206366d bug: in the (old) expression << ls->fs->f->consts[checkname(ls)] >>, checkname
could realloc f->consts.
1999-09-02 10:13:22 -03:00
Roberto Ierusalimschy b2c89ed2d2 new mechanism to access argv from a script 1999-08-18 14:40:54 -03:00
Roberto Ierusalimschy 2a03170ebd random(0) and random(x,0) are wrong (0 is read as no argument!). 1999-08-18 11:40:51 -03:00
Roberto Ierusalimschy 05f55cc062 more warning checking (mainly related to const strings). 1999-08-17 17:21:52 -03:00
Roberto Ierusalimschy c787dccd9b "const" !!! 1999-08-16 17:52:00 -03:00
Roberto Ierusalimschy b44e35b773 new constants LUA_NOREF and LUA_REFNIL. 1999-08-11 14:00:59 -03:00
Roberto Ierusalimschy 21843f022a writeto, readfrom, and closefile must return an error code when
closing a file.
1999-08-10 10:05:16 -03:00
Roberto Ierusalimschy 900257e814 char-set may contain '%]' 1999-08-10 09:55:56 -03:00
Roberto Ierusalimschy a82c8185bc details 1999-08-10 09:55:47 -03:00
Roberto Ierusalimschy 4bbe0679a8 variables _INPUT and _OUTPUT should be read as rawglobal. 1999-07-22 16:35:50 -03:00
Roberto Ierusalimschy 438598aeea details. 1999-07-22 16:35:41 -03:00
Roberto Ierusalimschy e9a670695a details 1999-07-22 16:29:42 -03:00
Roberto Ierusalimschy 16024861bd new format for numbers in precompiled code (as strings) 1999-07-08 09:43:23 -03:00
Roberto Ierusalimschy 3f43aaa23f new RedHat defines PI :-( 1999-07-07 14:54:08 -03:00
Roberto Ierusalimschy 3b4c831ca9 some systems do not reset signal handlers when a signal happens 1999-07-02 15:22:38 -03:00
Roberto Ierusalimschy 3fdab3981b no more automatic setlocale. 1999-06-24 16:42:02 -03:00
Roberto Ierusalimschy 88b65da4d7 simplifications. 1999-06-23 10:48:39 -03:00
Roberto Ierusalimschy 521b38532a better interfaces for luaD_calln (x luaD_call) 1999-06-22 17:37:23 -03:00
Roberto Ierusalimschy 36b6fe8d17 better treatment for arbitrary limits 1999-06-17 14:04:03 -03:00
Roberto Ierusalimschy d4dce57f5c cannot assign to unlimited variables, because it causes overflow in
the number of returns of a function.
1999-06-16 10:35:01 -03:00
Roberto Ierusalimschy 5c19ed2a13 bigger limit for number of local variables and upvalues 1999-06-16 10:22:04 -03:00
Roberto Ierusalimschy 5caf7f4a33 tremove erases its previous last element (to avoid locking potential
garbagge).
1999-05-27 17:21:03 -03:00
Roberto Ierusalimschy 3b533ea7c7 foreach, foreachi, foreachvar points to function in stack when stack
can be reallocated.
1999-05-24 14:53:49 -03:00
Roberto Ierusalimschy 995775e1cb tighter control on the stack when debugging 1999-05-24 14:53:03 -03:00
Roberto Ierusalimschy abfc885079 when debugging, move and erase old blocks to realloc. 1999-05-24 14:51:05 -03:00
Roberto Ierusalimschy 613b60c156 detail 1999-05-21 16:54:06 -03:00
Roberto Ierusalimschy cdd0fe9946 some C compilers cannot initialize a local struct 1999-05-21 16:41:49 -03:00
Roberto Ierusalimschy bc8619342a better control of stack size (only for DEBUG). 1999-05-21 14:23:15 -03:00
Roberto Ierusalimschy 48326500d0 longer marks when controling memory leaks 1999-05-20 17:43:06 -03:00
Roberto Ierusalimschy c8d219798a lhf 1999-05-17 11:12:01 -03:00
Roberto Ierusalimschy 34695d4f4a details (message text) 1999-05-14 09:24:20 -03:00
Roberto Ierusalimschy 924bbe020b bigger limits 1999-05-14 09:24:04 -03:00
Roberto Ierusalimschy 3aa500b524 new pattern item '+' 1999-05-11 17:46:28 -03:00
Roberto Ierusalimschy f1861ee210 no more beta 1999-05-11 17:29:19 -03:00
Roberto Ierusalimschy 705eae9fe4 there is no need for a size for Cblocks 1999-05-11 17:08:20 -03:00
Roberto Ierusalimschy 6eb1399a1c array Cblocks should grow dynamically 1999-05-11 11:19:32 -03:00
Roberto Ierusalimschy c390f73e3b block must always have a power-of-2 size (even at the limit) 1999-05-11 11:18:40 -03:00
Roberto Ierusalimschy 73308c7605 warnings by clinio 1999-05-10 10:54:01 -03:00
Roberto Ierusalimschy 288fa05602 opcodes with LONGARG do not use byte variants. 1999-05-06 11:41:41 -03:00
Roberto Ierusalimschy 7808ea3a5f new implementation for '*' in patterns + new option '+' 1999-05-05 16:23:11 -03:00
Roberto Ierusalimschy 732741b62f cannot use (i=i+1) 1999-05-05 16:21:57 -03:00
Roberto Ierusalimschy cc0f635ef7 '$' at end of pattern was matching regular '$', too. 1999-04-30 11:12:05 -03:00
Roberto Ierusalimschy e64dbc390a new version is beta. 1999-04-15 09:33:19 -03:00
Roberto Ierusalimschy a0fd8d1787 manual for 3.2 beta should be the same one that for 3.2. 1999-04-14 17:47:12 -03:00
Roberto Ierusalimschy d9d04a9274 "read_pattern" could lock when reading a lookahead from stdin. 1999-04-14 17:40:32 -03:00
Roberto Ierusalimschy b4ad600b93 numbers are stored in ascii format for better portability and simplicity 1999-04-13 17:16:37 -03:00
Roberto Ierusalimschy cb7f027380 IMtable must be initialized (and IMtable_size is not needed any more) due
to new way to handle growing vectors (previous modification).
1999-04-13 16:30:51 -03:00
Roberto Ierusalimschy 0bbd96bd5f details. 1999-04-13 16:28:49 -03:00
Roberto Ierusalimschy 4eb67aa710 changes from lhf. 1999-04-07 13:40:04 -03:00
Roberto Ierusalimschy 0133610315 format for function prototypes. 1999-04-07 12:37:02 -03:00
Roberto Ierusalimschy de04533dc0 better the old way, using upvalues to keep iotag. 1999-04-05 16:47:05 -03:00
Roberto Ierusalimschy 7c9aee64c2 new version by lhf. 1999-03-30 17:29:34 -03:00
Roberto Ierusalimschy e0ff4e5d22 first version about Lua debug library. 1999-03-29 11:21:37 -03:00
Roberto Ierusalimschy bf7f85d609 GC of files is tricky when Lua is being closed... 1999-03-26 10:48:26 -03:00
Roberto Ierusalimschy a775a2d81a check first whether function is global. 1999-03-26 10:14:00 -03:00
Roberto Ierusalimschy e9aa98d594 do not generate SETLINE after main (it will be after last line) 1999-03-25 18:06:57 -03:00
Roberto Ierusalimschy 3e9c6a8a24 details 1999-03-25 18:05:05 -03:00
Roberto Ierusalimschy 1f4e2ba7b2 more precise debug information about local variables 1999-03-23 16:58:37 -03:00
Roberto Ierusalimschy d6ff06751a new functions openfile and closefile;
new way to keep file handle tags.
1999-03-16 17:07:54 -03:00
Roberto Ierusalimschy 7a11c7f8e4 details 1999-03-16 13:43:27 -03:00
Roberto Ierusalimschy c454dc7bdd no more if expressions. 1999-03-11 16:00:12 -03:00
Roberto Ierusalimschy 82ad0d5770 details 1999-03-11 15:59:19 -03:00
Roberto Ierusalimschy 256d1bea08 missing #include 1999-03-10 11:23:07 -03:00
Roberto Ierusalimschy f2d35bdc78 format for file source is independent of "ldo". 1999-03-10 11:19:41 -03:00
Roberto Ierusalimschy 2679461637 no more assignment expressions (they don't fit in Lua...) 1999-03-10 11:09:45 -03:00
Roberto Ierusalimschy 0870a2d1d8 new opcode TAILCALL 1999-03-05 18:16:07 -03:00
Roberto Ierusalimschy 78edc241e9 details about debug info. 1999-03-05 17:45:01 -03:00
Roberto Ierusalimschy e907c711c0 "feof" may be a macro. 1999-03-05 10:15:50 -03:00
Roberto Ierusalimschy 5a8bb00df4 storing chunk "sources" instead of "filenames". 1999-03-04 18:23:39 -03:00
Roberto Ierusalimschy 677188de8a details. 1999-03-04 18:15:50 -03:00
Roberto Ierusalimschy 6233d21c9d file stream cannot call fread after EOF. 1999-03-04 11:50:26 -03:00
Roberto Ierusalimschy ab8ea5c38a warnings 1999-03-01 17:22:16 -03:00
Roberto Ierusalimschy ae9fd122fa vector do not need to grow until MINSIZE 1999-03-01 14:49:13 -03:00
Roberto Ierusalimschy da18ec5d54 warnings... 1999-03-01 14:49:04 -03:00
Roberto Ierusalimschy 038848eccd better control of vector when DEBUGing 1999-02-26 12:50:10 -03:00
Roberto Ierusalimschy b678e465a1 warnings in Solaris 1999-02-26 12:49:53 -03:00
Roberto Ierusalimschy 72d675aba7 macros "growvector" and "reallocvector" more compact 1999-02-26 12:48:55 -03:00
Roberto Ierusalimschy ba57f7d946 details 1999-02-26 12:48:30 -03:00
Roberto Ierusalimschy e63b542c9b comments 1999-02-26 12:19:54 -03:00
Roberto Ierusalimschy 6a853fcb8b details (from lhf) 1999-02-25 18:07:26 -03:00
Roberto Ierusalimschy 31bea2190b small correction 1999-02-25 16:20:40 -03:00
Roberto Ierusalimschy 4b954e9b2e details (from lhf) 1999-02-25 16:13:56 -03:00
Roberto Ierusalimschy 055823c04d "L->Mbuffbase" is better kept as offset instead of pointer 1999-02-25 12:17:01 -03:00
Roberto Ierusalimschy 26d1e21c89 new way to handle "growing" vectors 1999-02-25 12:16:26 -03:00
Roberto Ierusalimschy 24a2c08145 details 1999-02-24 18:31:03 -03:00
Roberto Ierusalimschy 9d7bae0b6a better instrumentation for internal debugging 1999-02-24 14:55:51 -03:00
Roberto Ierusalimschy 082aded149 warnings 1999-02-24 12:37:19 -03:00
Roberto Ierusalimschy aa9c75c06e no more EXTRALIBS (and new dependencies) 1999-02-23 12:01:29 -03:00
Roberto Ierusalimschy f04c83e075 new function "lua_next" (+ new implementation for "next") 1999-02-23 11:57:28 -03:00
Roberto Ierusalimschy c364e9f97e LONGARGW (for completeness). 1999-02-23 10:38:38 -03:00
Roberto Ierusalimschy e3a02e6a9c comments 1999-02-22 16:23:36 -03:00
Roberto Ierusalimschy d5feffdb60 new function lua_nextvar 1999-02-22 16:13:12 -03:00
Roberto Ierusalimschy bb5627f3a4 better control over calls to _ALERT and _ERRORMESSAGE (to avoid error
loops)
1999-02-22 11:17:24 -03:00
Roberto Ierusalimschy 21107d7c2c debug state is restored after a dofile/dostring 1999-02-22 10:51:44 -03:00
Roberto Ierusalimschy b5cd7d426f details 1999-02-19 15:33:35 -02:00
Roberto Ierusalimschy bf6d2ccf92 details 1999-02-12 17:23:02 -02:00
Roberto Ierusalimschy b82ff713e3 new name for opcode 1999-02-09 16:01:55 -02:00
Roberto Ierusalimschy 77113ee02f new year for Copyright. 1999-02-09 13:59:22 -02:00
Roberto Ierusalimschy ad6c7b0dd4 small corrections in opcodes. 1999-02-09 13:59:10 -02:00
Roberto Ierusalimschy 8b2d97d187 assignment expression may be multiple 1999-02-08 16:54:19 -02:00
Roberto Ierusalimschy fb1cf6ab2d clearer way to set tables. 1999-02-08 15:07:59 -02:00
Roberto Ierusalimschy 19ca2087de another (silly) debuging function. 1999-02-08 14:29:35 -02:00
Roberto Ierusalimschy 7bdbd833b5 userdata and strings are kept in separate stringtables 1999-02-08 14:28:48 -02:00
Roberto Ierusalimschy b22baf386d Lua cannot have static variables. 1999-02-05 13:22:43 -02:00
Roberto Ierusalimschy 8fdd06ba3c lots of new stuff from 3.2 1999-02-05 10:15:07 -02:00
Roberto Ierusalimschy 028ec00ab9 details 1999-02-05 09:22:58 -02:00
Roberto Ierusalimschy 1dcf1c9cbd format "%s" may break limit of "sprintf" on some machines. 1999-02-04 17:29:51 -02:00
Roberto Ierusalimschy 76179a1014 compile option EXTRALIB for builtin functions that can be written in Lua. 1999-02-04 17:12:35 -02:00
Roberto Ierusalimschy bdfab46c22 "errorim" now is _ERRORMESSAGE. 1999-02-04 16:59:31 -02:00
Roberto Ierusalimschy 5687949560 "lua_debug", "lua_callhook" and "lua_linehook" must be inside "lua_state". 1999-02-04 15:47:59 -02:00
Roberto Ierusalimschy 19de5b2205 new dependencies 1999-02-04 14:37:41 -02:00
Roberto Ierusalimschy cbc58af260 new opcode for "long" arguments (3 bytes) 1999-02-04 14:36:16 -02:00
Roberto Ierusalimschy 80001ab0eb getlocal cannot return the local itself, since lua_isstring and
lua_isnumber can modify it.
1999-02-03 14:42:42 -02:00
Roberto Ierusalimschy ae29ab9858 only parser uses MAX_WORD 1999-02-03 11:53:48 -02:00
Roberto Ierusalimschy 27407fc1f5 new syntax: assignment expressions + better order for opcodes 1999-02-02 17:41:17 -02:00
Roberto Ierusalimschy 1a17da2ff9 opcodes with builtin parameters are too complicated for very little extra
performance.
1999-02-02 15:57:49 -02:00
Roberto Ierusalimschy 50248e440a "if" expression leaves only one of its expressions on the stack 1999-02-02 11:47:31 -02:00
Roberto Ierusalimschy 0f0079f394 "if" expressions. 1999-02-01 16:52:05 -02:00
Roberto Ierusalimschy 68267ed878 negative numerals do not need a MINUSOPeration; go directly to contant
table.
1999-01-29 11:48:58 -02:00
Roberto Ierusalimschy fd25d4ad85 no need to define functions for macros... 1999-01-26 13:38:01 -02:00
Roberto Ierusalimschy 2431534f10 details 1999-01-26 09:50:58 -02:00
Roberto Ierusalimschy fd7d0774e5 luaH_set does the set and protect its value; luaH_move can then be a
macro.
New algorithm for double hashing (does not use "%").
1999-01-25 15:41:19 -02:00
Roberto Ierusalimschy 57ffc3f009 luaH_set does the set, and protects its value, so luaH_move can be a
macro.
1999-01-25 15:40:10 -02:00
Roberto Ierusalimschy 4a13f513f8 luaH_set does the set! 1999-01-25 15:39:28 -02:00
Roberto Ierusalimschy 13ad46b67d uses the same double hashing that is used for tables 1999-01-25 15:38:04 -02:00
Roberto Ierusalimschy 1b45e967b4 table entries with ref=null always have val=null too. 1999-01-25 10:30:11 -02:00
Roberto Ierusalimschy 933bead92e small optimizations(?) 1999-01-22 16:47:23 -02:00
Roberto Ierusalimschy 3314f49ec4 C cannot initialize a struct. 1999-01-22 16:46:11 -02:00
Roberto Ierusalimschy bc930aa5ff "free" usually handles NULL; handle non ANSI case separately. 1999-01-22 16:08:57 -02:00
Roberto Ierusalimschy 67b44c9493 local names are all in the constant pool, so they do not need to be
marked in GC.
1999-01-22 16:08:03 -02:00
Roberto Ierusalimschy 758a381644 "realloc" usually implements "malloc"; handle non ANSI case separately. 1999-01-22 15:28:00 -02:00
Roberto Ierusalimschy eec31aaca5 <string.h> is needed because of "memcpy". 1999-01-21 16:38:39 -02:00
Roberto Ierusalimschy 595738f6fe small optimizations 1999-01-20 18:22:06 -02:00
Roberto Ierusalimschy b5eb4f3126 small optimization in getglobal 1999-01-15 11:14:24 -02:00
Roberto Ierusalimschy 3fecf187ff names... 1999-01-15 11:11:57 -02:00
Roberto Ierusalimschy 54840fb256 new functions to manipulate C global variables 1999-01-15 11:11:22 -02:00
Roberto Ierusalimschy e87fddf1ad GC can be called during parsing, if needed. 1999-01-15 09:38:33 -02:00
Roberto Ierusalimschy dea400bc1d "getstack" returns func, too. 1999-01-15 09:36:28 -02:00
Roberto Ierusalimschy fb663f768d "%.16g" already formats integers as integers, so we do not need an
alternative "%ld" convertion in "tostring".
1999-01-13 17:09:04 -02:00
Roberto Ierusalimschy e03767b3eb details (comments) 1999-01-13 17:08:37 -02:00
Roberto Ierusalimschy 8396027516 better precision when converting numbers to strings. 1999-01-12 16:38:35 -02:00
Roberto Ierusalimschy e24f7fd2d2 details 1999-01-11 18:23:54 -02:00
Roberto Ierusalimschy 8081f39dab header missing. 1999-01-11 16:57:35 -02:00
Roberto Ierusalimschy 3cc4ca821e initialization module (to load libraries) 1999-01-08 14:49:32 -02:00
Roberto Ierusalimschy 01772cefa5 new library for debbuging 1999-01-08 14:47:44 -02:00
Roberto Ierusalimschy dc90d4bce3 when handling signals (^C), deep old hook values. 1999-01-06 11:12:41 -02:00
Roberto Ierusalimschy f5bc671030 "goto" for tail recursion changed to "while" 1999-01-04 15:34:49 -02:00
Roberto Ierusalimschy d7294c6de8 double hashing for string tables. 1999-01-04 11:37:29 -02:00
Roberto Ierusalimschy 63a752f961 small improvements. 1999-01-04 11:37:07 -02:00
Roberto Ierusalimschy 03d38b66fd new sort algorithm. 1999-01-04 10:55:09 -02:00
Roberto Ierusalimschy b9c9ccfbb4 function "move" for tables is better implemented with some "inside
information".
1999-01-04 10:54:33 -02:00
Roberto Ierusalimschy b94110a68f bug: "format" does not check size of format item (such as "%00000...00000d"). 1999-01-04 10:53:24 -02:00
Roberto Ierusalimschy 8278468041 comments 1999-01-04 10:41:12 -02:00
Roberto Ierusalimschy 4fbb2531b3 don´t need the "+1", the "%" is enough to garantee r<1. 1998-12-30 19:23:26 -02:00
Roberto Ierusalimschy 59f8e6fb77 details ("settable") 1998-12-30 15:26:49 -02:00
Roberto Ierusalimschy 05d89b5c05 new option for function "random": random(a,b) returns a<=x<=b 1998-12-30 15:22:17 -02:00
Roberto Ierusalimschy fe5c41fb8a new functions "tinsert" and "tremove" 1998-12-30 11:16:50 -02:00
Roberto Ierusalimschy 9a45543841 tables are better manipulated via "Hash *" instead of "TObject" or
"lua_Object".
1998-12-30 11:14:46 -02:00
Roberto Ierusalimschy 766e67ef3b to avoid warnings about "typecast" (Visual C++) 1998-12-28 11:44:54 -02:00
Roberto Ierusalimschy 4c94d8cc2c new function "luaO_str2d" to convert strings to numbers, because
old "lex" algorithm had aproximation errors, but strtod (and atof
and scanf) are too slow.
1998-12-27 18:25:20 -02:00
Roberto Ierusalimschy d2de2d5eda format for double is always "%g", do not need #defines 1998-12-27 18:23:22 -02:00
Roberto Ierusalimschy 96a7695275 reorder and rename of most functions, for better documentation. 1998-12-27 18:22:36 -02:00
Roberto Ierusalimschy 63166c0ca0 new implementation of function "read", with predifined options. 1998-12-27 18:21:28 -02:00
Roberto Ierusalimschy a881abfd1e "strtod" is cleaner than "scanf" for this job. 1998-12-24 12:57:23 -02:00
Roberto Ierusalimschy d3ac7075a2 better error message 1998-12-23 12:06:57 -02:00
Roberto Ierusalimschy 0c9080c7a9 "tonumber" goes crazy with negative numbers in other bases (not 10),
because "strtol" returns long, not unsigned long.
1998-12-18 11:26:43 -02:00
Roberto Ierusalimschy b8fcb7b151 details 1998-12-15 13:21:09 -02:00
Roberto Ierusalimschy 5d6de9075d "print" uses fputs instead of printf (easier to reimplement). 1998-12-15 12:59:59 -02:00
Roberto Ierusalimschy 21cff3015a details (for regularity) 1998-12-15 12:59:43 -02:00
Roberto Ierusalimschy 5ca2709ba0 small warnings 1998-12-03 13:45:15 -02:00
Roberto Ierusalimschy bb1cb7b9f1 NUMBER_FMT also may be predefined in makefile 1998-12-01 17:09:47 -02:00
Roberto Ierusalimschy c64f36ab2b better behavior for "strsub" when indices are out-of-range 1998-12-01 16:41:25 -02:00
Roberto Ierusalimschy e4830ddce3 new option "mode" in "readfrom", "writeto" and "appendto" (for
binary files).
1998-11-20 13:41:43 -02:00
Roberto Ierusalimschy 758e330d6e new functions "getn" and "foreachi" 1998-11-13 14:48:48 -02:00
Roberto Ierusalimschy 8e3bd752bb small optimization in "sort" + new functions "getn" and "foreachi" 1998-11-13 14:39:18 -02:00
Roberto Ierusalimschy a84bca67fc bug: gsub/strfind do not check whether captures are properly finished. 1998-11-10 17:38:12 -02:00
Roberto Ierusalimschy 4ccfb2f9bc "_TRIGMODE" was still being declared. 1998-09-08 16:25:35 -03:00
Roberto Ierusalimschy ce9609296c function "luaL_argerror" prints wrong argument number (from a user's point
of view) when functions have upvalues.
1998-09-07 15:59:59 -03:00
Roberto Ierusalimschy b1450721be new function "lua_nups" (number of upvalues). 1998-09-07 15:59:59 -03:00
Roberto Ierusalimschy b04294d3d8 details. 1998-08-30 17:25:24 -03:00
Roberto Ierusalimschy 22c2704842 "lua_state" is already declared in lua.h, which is included here. 1998-08-30 15:28:58 -03:00
Roberto Ierusalimschy ee22af5ced new functions "seek" and "flush". 1998-08-24 17:14:56 -03:00
Roberto Ierusalimschy cc117253c8 new implementation for error handling: on error, function _ERRORMESSAGE
is called, which in turn calls _ALERT to write a message to stderr.
1998-08-21 14:43:44 -03:00
Roberto Ierusalimschy 8e226e6a09 small bug: nuse may change when table is rehashed;
3/2 is a good fraction for hash limit (instead of 0.7, using floats)
1998-08-11 13:38:34 -03:00
Roberto Ierusalimschy 1d420c2c11 better error message for code too long (old one was misleading when the
problem was SETLINE after 64k lines...)
1998-08-11 10:28:05 -03:00
Roberto Ierusalimschy 5378331f2d hash tables may shrink if use rate is too small. 1998-08-10 18:36:32 -03:00
Roberto Ierusalimschy 894a264671 new hash function. 1998-07-27 14:06:17 -03:00
Roberto Ierusalimschy e1a127245d details ("luaX_token2str" doesn't need LexState) 1998-07-24 15:02:38 -03:00
Roberto Ierusalimschy afb5ef72e1 new function "sort" + many small changes 1998-07-12 13:16:43 -03:00
Roberto Ierusalimschy 1d8edd347d small changes to use new auxiliar functions 1998-07-12 13:16:02 -03:00
Roberto Ierusalimschy 41d9ea948c auxiliar functions "luaH_setint" & "luaH_getint". 1998-07-12 13:15:19 -03:00
Roberto Ierusalimschy ee912e5a7f auxiliar function "luaD_calln". 1998-07-12 13:14:34 -03:00
Roberto Ierusalimschy ad446a0eb0 "%q" can handle strings with '\0'. 1998-07-12 13:13:45 -03:00
Roberto Ierusalimschy 176cb39feb macro encapsulates de "-". 1998-07-12 13:11:55 -03:00
Roberto Ierusalimschy 64ad009fb2 "fileName" cannot be NULL 1998-07-12 13:10:38 -03:00
Roberto Ierusalimschy dcb1a08906 "exp" changed to "exp0" to avoid problems with math.h. 1998-07-06 19:07:51 -03:00
Roberto Ierusalimschy 1788501eed double constant used in integer expression 1998-07-06 19:04:58 -03:00
Roberto Ierusalimschy bee1a5aeb2 spelling 1998-07-01 11:21:57 -03:00
Roberto Ierusalimschy 994aba062b when debuging, blocks must be kept in double allignment. 1998-06-29 19:03:06 -03:00
Roberto Ierusalimschy e869d17eb1 functions should return explicit "nil"s. 1998-06-29 15:24:06 -03:00
Roberto Ierusalimschy 9a0221ef58 detail 1998-06-29 15:09:28 -03:00
Roberto Ierusalimschy 07008b5d45 details (by lhf) 1998-06-25 13:48:44 -03:00
Roberto Ierusalimschy 8f31eda649 details in comments 1998-06-25 11:37:00 -03:00
Roberto Ierusalimschy da94130160 stupid bug (in syntax print "hello") 1998-06-24 11:48:15 -03:00
Roberto Ierusalimschy 468fbdbde7 details 1998-06-24 10:33:00 -03:00
Roberto Ierusalimschy eb45f8b631 details (dependencies) 1998-06-19 15:52:27 -03:00
Roberto Ierusalimschy df0df08bc5 "dostring" accepts chunk name. 1998-06-19 15:47:06 -03:00
Roberto Ierusalimschy 9618aaf07d small corrections in comments 1998-06-19 13:14:09 -03:00
Roberto Ierusalimschy bec9bc4154 sugestions by lhf 1998-06-18 14:36:27 -03:00
Roberto Ierusalimschy 955a811aa1 category for "setlocale" is given by name 1998-06-18 14:04:28 -03:00
Roberto Ierusalimschy c9902be294 "findname" moved from lobject.c to lauxlib.c (so libraries may use it). 1998-06-18 13:57:03 -03:00
Roberto Ierusalimschy 112c9d53ab new version by lhf 1998-06-18 13:52:04 -03:00
Roberto Ierusalimschy 0789451458 details 1998-06-18 13:51:53 -03:00
Roberto Ierusalimschy d97af0de26 "lua_dobuffer" gets an extra argument, with the chunk name 1998-06-15 18:34:14 -03:00
Roberto Ierusalimschy 1917149fdd details. 1998-06-11 15:21:37 -03:00
Roberto Ierusalimschy 0845e73b6a new copyright notice 1998-06-06 18:05:52 -03:00
Roberto Ierusalimschy 7dfa952091 no more error for '\x' (with "invalid" x) 1998-06-06 17:44:05 -03:00
Roberto Ierusalimschy 02134b4a87 name: lua_pushCclosure -> lua_pushcclosure. 1998-06-05 19:17:44 -03:00
Roberto Ierusalimschy bdb1db4d37 "read" more efficient when reading lines and whole files ('.*') 1998-06-02 18:20:54 -03:00
Roberto Ierusalimschy 02a6891939 API for functions to manipulate global state. 1998-06-02 17:37:04 -03:00
Roberto Ierusalimschy 741c6f5006 'dobuffer' addpoted. 1998-05-31 19:22:00 -03:00
Roberto Ierusalimschy 6152973f9c new names for 'ascii' ('strbyte') and 'int2str' ('strchar') 1998-05-31 19:20:45 -03:00
Roberto Ierusalimschy 243a808067 'print' now calls 'tostring' 1998-05-31 19:19:35 -03:00
Roberto Ierusalimschy 62c36a6056 better error message when '^' is not defined. 1998-05-31 19:18:24 -03:00
Roberto Ierusalimschy 74719afc33 new functions "frexp" and "ldexp" 1998-05-27 16:09:39 -03:00
Roberto Ierusalimschy 7e59a8901d NEW LL(1) PARSER 1998-05-27 10:08:34 -03:00
Roberto Ierusalimschy abc6eac404 new function "clock" 1998-05-20 19:21:35 -03:00
Roberto Ierusalimschy 054e0b888a number type in Lua changed for double (by default). 1998-05-18 19:26:03 -03:00
Roberto Ierusalimschy da252eeff7 arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int. 1998-05-18 19:21:55 -03:00
Roberto Ierusalimschy 9890bedaab details (format for html) 1998-04-02 13:09:16 -03:00
Roberto Ierusalimschy 0a0c9593b8 many small corrections; strings with '\0' 1998-03-30 15:17:55 -03:00
Roberto Ierusalimschy d470792517 words are stored in hi-lo order (easier to print) 1998-03-30 10:57:23 -03:00
Roberto Ierusalimschy 439236773b changes by lhf 1998-03-26 11:50:19 -03:00
Roberto Ierusalimschy 2a2b64d6ac opcode "CLOSURE" gets the prototipe (instead of a previous pushconstant) 1998-03-25 15:52:29 -03:00
Roberto Ierusalimschy daa937c043 pattern-matching support for '\0'. 1998-03-24 17:14:25 -03:00
Roberto Ierusalimschy 21455162b5 details (and new escape sequences: \a, \b, ...) 1998-03-20 11:18:18 -03:00
Roberto Ierusalimschy 99cc4b20f2 details 1998-03-11 10:59:50 -03:00
Roberto Ierusalimschy 0969a971cd better use of "ASSERT". 1998-03-09 18:49:52 -03:00
Roberto Ierusalimschy be6d215f67 BUG: gsub('a', '(b?)%1*' ...) loops (because the capture is empty). 1998-03-09 15:28:08 -03:00
Roberto Ierusalimschy e74817f8aa correct way to handle string delimiters 1998-03-09 14:22:49 -03:00
Roberto Ierusalimschy 043c2ac258 new names for "lua_pushlstr" and "lua_getstrlen" 1998-03-06 15:47:42 -03:00
Roberto Ierusalimschy 88a2023c32 support for strings with '\0' 1998-03-06 13:54:42 -03:00
Roberto Ierusalimschy 5ef1989c4b "settag" returns its first argument. 1998-02-12 17:27:10 -02:00
Roberto Ierusalimschy f380d627f8 usefull macros also available as functions 1998-02-12 17:23:32 -02:00
Roberto Ierusalimschy aafa106d10 implementation of numerical escape sequences in strings ("\12");
better error messages for wrong tokens
1998-02-11 18:56:46 -02:00
Roberto Ierusalimschy 29b7b8e52c better error messages for wrong tokens 1998-02-11 18:56:46 -02:00
Roberto Ierusalimschy a9dd2c6717 interrupts lua loops with "^C" (via signals) 1998-02-11 18:56:05 -02:00
Roberto Ierusalimschy aee3f97acb put back quotes (") when string in dostring ends with a \n 1998-01-29 13:59:35 -02:00
Roberto Ierusalimschy 46968b8ffa "volatile is the only reliable way to ensure that a local variable
retains the value it had at the time of the call to longjmp"
1998-01-28 15:47:05 -02:00
Roberto Ierusalimschy 6cdf0d8768 tables can become full of "emptys" slots, and keep growing without limits. 1998-01-28 14:50:33 -02:00
Roberto Ierusalimschy 07ff251a17 details in "dostring" identification 1998-01-27 19:21:27 -02:00
Roberto Ierusalimschy b3b7cf7335 BUG: "lua_getstring" may create a new string, so should check GC 1998-01-27 17:13:45 -02:00
Roberto Ierusalimschy 8622dc18bf bug: format size limits with little problems 1998-01-27 17:11:36 -02:00
Roberto Ierusalimschy d22e2644dd wrong line number (+1) in error report when file starts with "#..." 1998-01-19 18:18:02 -02:00
Roberto Ierusalimschy f529a22ca5 BUG: wrong line number (+1) in error report when file starts with "#..." 1998-01-19 18:18:02 -02:00
Roberto Ierusalimschy 783ba75129 needs "stdlib.h" (calls "exit") 1998-01-19 17:49:49 -02:00
Roberto Ierusalimschy d49e4dd752 MAX_WORD should not be bigger than MAX_INT 1998-01-19 17:49:22 -02:00
Roberto Ierusalimschy 981fddea02 module to load bytecodes from files. 1998-01-14 13:49:01 -02:00
Roberto Ierusalimschy 81b953f27e details 1998-01-14 11:49:44 -02:00
Roberto Ierusalimschy b9acf4b4af "strcoll" may not exist in ond ansi machines 1998-01-14 11:49:15 -02:00
Roberto Ierusalimschy 44ace0aefd we don't need a type "Word". 1998-01-14 11:48:28 -02:00
Roberto Ierusalimschy 5981161360 small optimizations (?) 1998-01-13 16:06:27 -02:00
Roberto Ierusalimschy 763c64be9b details 1998-01-13 13:42:43 -02:00
Roberto Ierusalimschy f0dffaa209 new way to hanlde arg information 1998-01-12 11:35:37 -02:00
Roberto Ierusalimschy 77a6836fef we don't need a type "Word". 1998-01-12 11:00:51 -02:00
Roberto Ierusalimschy 9f043e8017 luaL_arg_check now is inlined 1998-01-09 13:09:53 -02:00
Roberto Ierusalimschy 6ac047afc4 details 1998-01-09 12:57:43 -02:00
Roberto Ierusalimschy 0e1058cfdd small optimizations in switch order 1998-01-09 12:44:55 -02:00
Roberto Ierusalimschy 26679b1a48 back to upavalues as extra arguments for C closures; this way it's
trivial to make currying.
1998-01-07 14:26:48 -02:00
Roberto Ierusalimschy e04c2b9aa8 details 1998-01-06 17:17:31 -02:00
Roberto Ierusalimschy 0c031dcc8b details 1998-01-05 15:12:54 -02:00
Roberto Ierusalimschy c332c4e927 reference manual of the Lua language 1998-01-02 16:34:00 -02:00
Roberto Ierusalimschy 964c503a63 LUA_COMPAT2.5 may use #ifdef instead of #if 1998-01-02 15:46:32 -02:00
Roberto Ierusalimschy 90d87e3a78 details 1997-12-30 17:15:52 -02:00
Roberto Ierusalimschy f76bca23ef variants for "ARGS". 1997-12-30 17:08:23 -02:00
Roberto Ierusalimschy a5fd7d722c opctional "base" in "tonumber" convertion. 1997-12-30 15:57:45 -02:00
Roberto Ierusalimschy 4e0bf95622 variant opcodes for PUSHSELF 1997-12-29 15:35:46 -02:00
Roberto Ierusalimschy 498a934abf new syntax possibilities: f(x).x, etc; on the other hand,
"function ... (x)" now is more restricted.
1997-12-29 15:28:45 -02:00
Roberto Ierusalimschy ce53872684 new syntax: f´s´ for f(´s´). 1997-12-28 20:48:15 -02:00
Roberto Ierusalimschy da96eb2cce some details related to OLD_ANSI 1997-12-26 16:38:16 -02:00
Roberto Ierusalimschy fada8efd01 "rand()", in SunOS, may return values bigger than "RAND_MAX"... 1997-12-26 16:36:31 -02:00
Roberto Ierusalimschy d916487d7c auxlib split in two parts (lauxlib and lbuffer) 1997-12-23 17:24:36 -02:00
Roberto Ierusalimschy 1bf762ba38 Generic buffer facilities for Lua (and libraries) 1997-12-23 17:24:36 -02:00
Roberto Ierusalimschy 541e722360 details 1997-12-23 17:24:19 -02:00
Roberto Ierusalimschy 807ba6301c error method *always* gets a string (otherwise it is not called at all) 1997-12-23 10:50:49 -02:00
Roberto Ierusalimschy 03f3f9e707 "zio" now keeps its "name". 1997-12-22 18:57:18 -02:00
Roberto Ierusalimschy a78eecee48 details (aborts with invalid arguments) 1997-12-22 18:03:50 -02:00
Roberto Ierusalimschy 43461d267f help message 1997-12-22 16:05:23 -02:00
Roberto Ierusalimschy fae0b52825 small bugs in error report 1997-12-22 15:52:20 -02:00
Roberto Ierusalimschy 22439a7511 new syntax for constructors (a={n=3;1,2,3}). 1997-12-22 15:24:11 -02:00
Roberto Ierusalimschy 7ecc3ce827 new command line options 1997-12-19 16:34:23 -02:00
Roberto Ierusalimschy 4e91384e14 sorting the includes... 1997-12-18 17:11:43 -02:00
Roberto Ierusalimschy de79e7fc58 back to "lua_upvalue"... (seems better choice) 1997-12-18 16:32:39 -02:00
Roberto Ierusalimschy 8b5b42563c "lua_dobuffer" (is not official, but its there...) 1997-12-17 18:57:20 -02:00
Roberto Ierusalimschy 502343b402 new scheme for buffers, centralized in auxlib. 1997-12-17 18:48:58 -02:00
Roberto Ierusalimschy 82d09fbf0d new structure for closures, without static variables. 1997-12-15 15:58:49 -02:00
Roberto Ierusalimschy 9be85d1648 new year 1997-12-15 15:47:55 -02:00
Roberto Ierusalimschy 45e533599f optimization: closures without upvalues don't need to be closures 1997-12-15 14:17:20 -02:00
Roberto Ierusalimschy 94144a7821 otimization: closures without upvalues don't need to be closures 1997-12-15 14:17:20 -02:00
Roberto Ierusalimschy 4daae2165d new API function and built-in "lua_copytagmethods" 1997-12-11 15:21:11 -02:00
Roberto Ierusalimschy cdd261f332 new option "-q" (quiet), and multi-line commands (ending with '\') 1997-12-11 15:00:21 -02:00
Roberto Ierusalimschy 034f16892e better treatment of MARKs and DEBUG cases. 1997-12-11 12:48:46 -02:00
Roberto Ierusalimschy c759520bc8 safer way to put #defines in error messages... 1997-12-09 14:01:08 -02:00
Roberto Ierusalimschy 80b3d28f4a details (mainly error messages) 1997-12-09 11:50:08 -02:00
Roberto Ierusalimschy 69d97712ec arguments "var=value" doesn't need quotes for value 1997-12-03 17:57:54 -02:00
Roberto Ierusalimschy 5d89dad9b8 bug log 1997-12-02 10:46:15 -02:00
Roberto Ierusalimschy 525a91fed3 BUG: "lastline" was not reset on function entry, so debug information
started only in the 2nd line of a function.
1997-12-02 10:43:54 -02:00
Roberto Ierusalimschy 868d16dee0 comments 1997-12-02 10:43:44 -02:00
Roberto Ierusalimschy 3393fd7f25 first version of "lua_close" 1997-12-01 18:31:25 -02:00
Roberto Ierusalimschy 00c122cc29 other distribution of memory debug information. 1997-12-01 18:30:44 -02:00
Roberto Ierusalimschy 03160920cf store "functofind" in stack top, so doesn't need this field in
global state.
1997-11-28 14:56:05 -02:00
Roberto Ierusalimschy b42cc6a4d2 no more protected global variables; using upvalues to store tags. 1997-11-28 10:40:37 -02:00
Roberto Ierusalimschy a6ad644bf2 no more protected global variables 1997-11-28 10:39:45 -02:00
Roberto Ierusalimschy 39fd5bb9b0 details 1997-11-28 10:39:22 -02:00
Roberto Ierusalimschy 5482992dec other access method for C upvalues (as arguments) 1997-11-27 16:25:14 -02:00
Roberto Ierusalimschy 024528e0c2 global variables starting with '.' are protected in Lua (temporarily at
least...)
1997-11-27 13:59:44 -02:00
Roberto Ierusalimschy ef37c87e93 no more 'globalbag' 1997-11-27 13:59:25 -02:00
Roberto Ierusalimschy 9e029f98b9 details 1997-11-26 18:44:52 -02:00
Roberto Ierusalimschy e962330df9 "stacklimit" is not necessary. 1997-11-26 18:28:22 -02:00
Roberto Ierusalimschy b291e50006 extra argument for "assert" 1997-11-26 17:40:27 -02:00
Roberto Ierusalimschy 9ae0c082a3 small details by lint. 1997-11-26 16:53:45 -02:00
Roberto Ierusalimschy accd7bc253 small modifications (format, small optimizations, etc) 1997-11-21 17:00:46 -02:00
Roberto Ierusalimschy 6153200bc2 make sure there is no mem problems, using %.ns instead of %s for luaV_error. 1997-11-19 16:16:33 -02:00
Roberto Ierusalimschy 2e7595522d allows '\r' at the end of pragmas, so one can mix Windows and Unix files 1997-11-19 15:35:47 -02:00
Roberto Ierusalimschy b79ffdc4ce global state for Lua interpreter 1997-11-19 15:31:19 -02:00
Roberto Ierusalimschy 592a3f289b first implementation of centralized global state. 1997-11-19 15:29:23 -02:00
Roberto Ierusalimschy 9cdeb275e7 details 1997-11-10 15:47:01 -02:00
Roberto Ierusalimschy c957b270d2 "call" now handles errors (instead of "dostring") 1997-11-07 16:19:13 -02:00
Roberto Ierusalimschy 92791b9dd6 small details 1997-11-07 13:09:49 -02:00
Roberto Ierusalimschy 45cad43c3f "lua_open": now lua has an explicit open operation. 1997-11-04 13:27:53 -02:00
Roberto Ierusalimschy dad5a01fb0 trigonometric mode stored in a Lua global variable. 1997-11-03 19:11:44 -02:00
Roberto Ierusalimschy 66713181c1 no need of "emergency error"... 1997-11-03 19:00:23 -02:00
Roberto Ierusalimschy 7135803cc8 "global" version of a nil object. 1997-11-03 18:45:23 -02:00
Roberto Ierusalimschy b7567b6673 "read" & "write" may receive a file handler as first argument 1997-10-30 18:29:09 -02:00
Roberto Ierusalimschy f8c95fa9e8 new "block" syntax (DO ... END) 1997-10-30 16:47:19 -02:00
Roberto Ierusalimschy 9c965d0ffb more precise error messages for compiler limits. 1997-10-28 15:26:53 -02:00
Roberto Ierusalimschy 6103dca8ee small bug. 1997-10-27 14:14:37 -02:00
Roberto Ierusalimschy 18cd7adac6 optimization to handle <a.x> (new opcode). 1997-10-24 16:40:29 -02:00
Roberto Ierusalimschy 41223a01ec definition of "PI" and modes for angles. 1997-10-24 15:44:22 -02:00
Roberto Ierusalimschy e78cf96c97 first version of Cclosures. 1997-10-24 15:17:24 -02:00
Roberto Ierusalimschy 0cb3843956 "foreach" and "foreachvar" more robust (to survive GCs), and with
termination test.
1997-10-23 14:28:48 -02:00
Roberto Ierusalimschy 907368ead5 GC now considers an "estimate" of object size, instead of just the number
of objects.
1997-10-23 14:26:37 -02:00
Roberto Ierusalimschy 81489beea1 functions may use many upvalues, to keep global values. 1997-10-18 14:46:39 -02:00
Roberto Ierusalimschy ac30aad09b new functions "foreach" and "foreachvar" 1997-10-18 14:33:36 -02:00
Roberto Ierusalimschy 2c89651fc6 macro "val" should live together with macro "ref". 1997-10-18 14:29:15 -02:00
Roberto Ierusalimschy 3a89c973ff details 1997-10-16 19:14:47 -02:00
Roberto Ierusalimschy 52d5e8032c better identification of types which are tags 1997-10-16 18:07:40 -02:00
Roberto Ierusalimschy 19c178fa14 new (smaller) prompt 1997-10-16 16:35:59 -02:00
Roberto Ierusalimschy 45ccb0e881 "nupvalues" is kept in Closure, not in prototype (as a preparation
for C closures...)
1997-10-16 08:59:34 -02:00
Roberto Ierusalimschy 4be18fa889 details 1997-10-15 18:16:00 -02:00
Roberto Ierusalimschy 7c261a13b5 more uniform treatment to opcode variants. 1997-10-13 20:12:04 -02:00
Roberto Ierusalimschy 2bb94d9e22 using bison instead of yacc; lparser.c renamed to lstx.c (to
avoid confusion with lparser.h...)
1997-10-13 20:10:45 -02:00
Roberto Ierusalimschy a3235ad270 prompt for interactive mode 1997-10-06 12:51:32 -02:00
Roberto Ierusalimschy f6a9cc9a67 jumps are relative to next instruction 1997-10-06 12:51:11 -02:00
Roberto Ierusalimschy 28d47a0aaa all jumps have byte variants; WHILE optimization 1997-10-01 17:05:34 -03:00
Roberto Ierusalimschy eb617df2d8 better way to traverse GCnode lists. 1997-09-26 13:46:20 -03:00
Roberto Ierusalimschy a580480b07 new implementation for globals: Global value is stored in TaggedString 1997-09-26 12:02:26 -03:00
Roberto Ierusalimschy 0dd6d1080e new opcode variants. 1997-09-24 16:43:11 -03:00
Roberto Ierusalimschy 3c820d622e better control over closed files 1997-09-23 11:12:44 -03:00
Roberto Ierusalimschy d6c867ea50 better way to cope with opcode variants 1997-09-22 17:53:20 -03:00
Roberto Ierusalimschy 2079cfe8fa new way to code globals, using const table instead of putting global
index inside the opcode.
1997-09-19 18:17:52 -03:00
Roberto Ierusalimschy dfe03c7abe small optimizations (bit scrubbing) 1997-09-19 15:40:32 -03:00
Roberto Ierusalimschy 8cd67ac676 Syntax analizer and code generator 1997-09-16 16:33:21 -03:00
Roberto Ierusalimschy 9828893f7e Makefile 1997-09-16 16:33:21 -03:00
Roberto Ierusalimschy 6990da0057 Lua virtual machine 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy d985dc0629 Opcodes for Lua virtual machine 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 451124005b Standard I/O (and system) library 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 2f1fa3d427 Type definitions for Lua objects 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 189d64409b Garbage Collector 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 60cc473bcf Lexical Analizer 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 43a2ee6ea1 Stack and Call structure of Lua 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 4b91e9cde6 Tag methods 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 26c5f56ad1 Built-in functions 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy daa858ef27 String table (keep all strings handled by Lua) 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy ea169d2083 auxiliar functions from Lua API 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy c31aa863ac Auxiliar functions for building Lua libraries 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy ff08b0f406 Lua Function structures 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy c1801e623f Some generic functions over Lua objects 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy a404f6e0e6 Lua tables (hash) 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 2d2440a753 Lua stand-alone interpreter 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 0c4ed2b3dc main header file 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy b945fae40e Lua standard mathematical library 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy dadba4d6ed Interface to Memory Manager 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy d600a6b5b3 a generic input stream interface 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 75ac0d2172 Standard library for strings and pattern-matching 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 9f3785a2f3 Lua standard libraries 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy 84e92e0976 Debuging API 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy b8a049abed Global variables 1997-09-16 16:25:59 -03:00
Roberto Ierusalimschy e18f681333 very small corrections... 1997-09-16 16:01:10 -03:00
Roberto Ierusalimschy dd1aa28390 small optimization in opcodes for "and" and "or" 1997-08-04 16:15:05 -03:00
Roberto Ierusalimschy abbf14cd32 small optimizations; try to find previous use when coding a real constant. 1997-07-31 17:46:59 -03:00
Roberto Ierusalimschy e8292f076d new dependencies 1997-07-31 17:45:25 -03:00
Roberto Ierusalimschy 3037dccaf6 prime numbers spread better. 1997-07-31 17:44:46 -03:00
Roberto Ierusalimschy a7793468aa correct support for changing real to double (optional) 1997-07-31 16:37:37 -03:00
Roberto Ierusalimschy caa987faad "random" accepts an 'n' to return between 1 and 'n'. 1997-07-30 19:15:18 -03:00
Roberto Ierusalimschy 0892f0e5b7 BIG CHANGE: functions have their own "constant table". 1997-07-30 19:00:50 -03:00
Roberto Ierusalimschy 1d7857bc63 free(b) is equivalent to realloc(b, 0) 1997-07-30 15:29:08 -03:00
Roberto Ierusalimschy 72a1d81b51 bug: lua_getlocal breaks when called with a CFunction. 1997-07-29 18:11:10 -03:00
Roberto Ierusalimschy 2c580a0afb new way to handle global state during compilation. 1997-07-29 17:38:45 -03:00
Roberto Ierusalimschy 05e8b0ae80 new opcode, ENDCODE, to signal end of code vector. 1997-07-29 17:38:06 -03:00
Roberto Ierusalimschy 16dd77e8d9 unused field "size" in struct TFunc. 1997-07-29 16:44:02 -03:00
Roberto Ierusalimschy 0600f968c3 BUG: LUA_COMPAT2_5 written wrong... 1997-07-29 10:35:06 -03:00
Roberto Ierusalimschy 971b1d557d bug log. Most of the log is done automatically by RCS, and not in
the file itself :-)
1997-07-29 10:34:15 -03:00
Roberto Ierusalimschy 11d97c34d5 skipping of '#' in first line is done by lex.c. 1997-07-29 10:33:15 -03:00
Roberto Ierusalimschy 66be42549e BUG: files starting with '#' get wrong line numbers 1997-07-07 18:05:51 -03:00
Roberto Ierusalimschy 067db30d71 "next" & "nextvar" check if argument is a result of previous calls 1997-07-07 13:44:26 -03:00
Roberto Ierusalimschy da4dbe65b2 new functionality for "format": "%d$...". 1997-07-04 19:35:38 -03:00
Roberto Ierusalimschy 4321fde2a7 error inside an error method could break the stack. 1997-07-04 11:55:37 -03:00
Roberto Ierusalimschy 8f3df1d471 small details. 1997-07-02 15:50:18 -03:00
Roberto Ierusalimschy 1a17211707 auxliar support for "locale" (to avoid portability problems) 1997-07-02 15:45:09 -03:00
Roberto Ierusalimschy d56e3a6481 "locale" support + better uniformity in formating 1997-07-02 14:09:48 -03:00
Roberto Ierusalimschy 7820a47184 LOCALE support 1997-07-01 16:32:41 -03:00
Roberto Ierusalimschy 88b185ada1 more uniform source (more macros...) 1997-07-01 14:41:34 -03:00
Roberto Ierusalimschy ef3c45d523 for security reasons, one cannot change the tag of a udata
from Lua.
1997-06-27 19:38:49 -03:00
Roberto Ierusalimschy 20a48a818f a file handle must be a userdata. 1997-06-27 19:38:49 -03:00
Roberto Ierusalimschy c9e6ed1d9f small corrections. 1997-06-27 15:39:34 -03:00
Roberto Ierusalimschy 56fdab67d8 believe it or not, this makes a difference... 1997-06-26 18:40:57 -03:00
Roberto Ierusalimschy 3a98c8670d new name for _VERSION (standard of _UPPERCASES for pre-defined
global variable)
1997-06-26 17:47:43 -03:00
Roberto Ierusalimschy da585783e3 new method to handle current files, with global variables
_INPUT and _OUTPUT.
1997-06-26 17:39:10 -03:00
Roberto Ierusalimschy e81f184164 new #define LUA_COMPAT2_5 to select "compatibility mode". 1997-06-23 15:27:53 -03:00
Roberto Ierusalimschy 3e43275308 incompatibilities with 2.5 + restrictions on tag methods 1997-06-20 16:28:16 -03:00
Roberto Ierusalimschy f97307b548 zio should not care about how a user creates a FILE (pipe, socket, popen,
etc).
1997-06-20 16:25:54 -03:00
Roberto Ierusalimschy 6402bfb1f8 better error message for dostring (2nd argument) 1997-06-20 16:19:09 -03:00
Roberto Ierusalimschy 27b6bbdcf3 "testC" inactive (active only for tests) 1997-06-19 15:55:40 -03:00
Roberto Ierusalimschy 5a198de3c1 new prefix luaZ 1997-06-19 15:55:28 -03:00
Roberto Ierusalimschy c5d7ba7347 dostring has an optional error method argument 1997-06-19 15:49:40 -03:00
Roberto Ierusalimschy f84c2ebc4a dostring has an optional error method argument;
counter for gsub only when there is a table (to keep full compatibility)
1997-06-19 15:49:40 -03:00
Roberto Ierusalimschy c8897f2b08 counter for gsub only when there is a table (to keep full compatibility) 1997-06-19 15:49:40 -03:00
Roberto Ierusalimschy 6bb2cac3db setparsedfile is extern; luaz_... changed to luaZ_... 1997-06-19 15:04:34 -03:00
Roberto Ierusalimschy 88f020b626 new interface to "lua_seterrormethod" and "lua_settagmethod", to
allow the use of Lua functions too.
1997-06-19 15:03:04 -03:00
Roberto Ierusalimschy a38f093f05 luaI_initTFunc initializes fileName. 1997-06-19 14:46:12 -03:00
Roberto Ierusalimschy b6adfdd01b gsub aborts if error occurs. 1997-06-19 14:45:28 -03:00
Roberto Ierusalimschy b90b4bbd3a macros don't need prototypes. 1997-06-18 18:39:56 -03:00
Roberto Ierusalimschy f6d95140ae using old version functions. 1997-06-18 18:20:45 -03:00
Roberto Ierusalimschy eca17b24ea #if wraps compatibility issue 1997-06-18 18:20:45 -03:00
Roberto Ierusalimschy 6b61582e47 do not use $...$ to italic. 1997-06-18 18:11:53 -03:00
Roberto Ierusalimschy 60bdc370d9 new functions lua_doFILE and lua_dobuffer to help users... 1997-06-18 17:35:49 -03:00
Roberto Ierusalimschy b9e31f73ee exported functions follow "lua" prefix rule. 1997-06-18 17:30:52 -03:00
Roberto Ierusalimschy ea98620d98 new arguments for gsub 1997-06-18 17:15:47 -03:00
Roberto Ierusalimschy 6b78040840 lhf corrections + new gsub 1997-06-18 17:14:52 -03:00
Roberto Ierusalimschy e931c7c0f6 error message always shows file names. 1997-06-18 14:33:30 -03:00
Roberto Ierusalimschy 70160320b1 first version for Lua 3.0 (with tag methods, etc) 1997-06-17 15:45:16 -03:00
Roberto Ierusalimschy bfbf56f15a extra parameter for "call" is "pack" or "plain". 1997-06-17 15:44:31 -03:00
Roberto Ierusalimschy 732ef82c72 "luaI_undump1" cannot be static; luac uses it. 1997-06-17 15:19:17 -03:00
Roberto Ierusalimschy 2a1da64872 "lua_getobjname" must return "tag-method" and not "fallback". 1997-06-17 15:09:31 -03:00
Roberto Ierusalimschy 3c5d71cf77 "nil" may have fallbacks too. 1997-06-17 14:27:07 -03:00
Roberto Ierusalimschy 1848bcc15b "strsub" accepts negative indices (count from the end of the string). 1997-06-16 17:29:59 -03:00
Roberto Ierusalimschy 4d2de484f6 "lua_seterrormethod" should return the previous handler. 1997-06-16 16:48:18 -03:00
Roberto Ierusalimschy 312f78d925 default error method is not nil (nil does nothing). 1997-06-16 15:43:19 -03:00
Roberto Ierusalimschy e4b69d6c9c "order" and "concat" operations choose tag methods the same way that
"arith" operations do (first the first parameter, etc).
1997-06-16 15:42:32 -03:00
Roberto Ierusalimschy c9a2dfeb2c using "zio" for parsing Lua code. 1997-06-16 13:50:22 -03:00
Roberto Ierusalimschy 9fe5be3acf library for uniform buffered input. 1997-06-16 13:50:22 -03:00
Roberto Ierusalimschy 611680af08 functions "lua_settagmethod" and similars should be safe too. 1997-06-12 15:27:29 -03:00
Roberto Ierusalimschy cb1d8f0fa0 missing small dependency. 1997-06-11 15:57:00 -03:00
Roberto Ierusalimschy 33f4fef410 BUG: did not handle properly pragmas $endinput/$debug inside a $if. 1997-06-11 15:56:02 -03:00
Roberto Ierusalimschy e77534c08f small 'improvement' 1997-06-11 11:24:40 -03:00
Roberto Ierusalimschy a22b54bbb6 format more uniform, to facilitate filters .tex->.html 1997-06-09 15:16:33 -03:00
Roberto Ierusalimschy 414ebe8ce1 power method (^) acts only in numbers. 1997-06-09 14:30:10 -03:00
Roberto Ierusalimschy 33ace03b5a udata is just void * again, so there is no point for function "getbyte". 1997-06-09 14:29:45 -03:00
Roberto Ierusalimschy 085181a08a new function "testC", to help debug the API. 1997-06-09 14:29:16 -03:00
Roberto Ierusalimschy dd22ea4da5 new implementation for udata (again they are just void *);
new implementation for the API: most operations now do not disturb
structures lua2C and C2lua.
1997-06-09 14:28:14 -03:00
Roberto Ierusalimschy 5fdcfeb353 new lua_Objects are created below the C2lua stack, so most API functions
don't need to adjust stack.
1997-06-06 17:54:40 -03:00
Roberto Ierusalimschy d68d8287aa new lua_Objects are created below the C2lua stack, so most API functions
don't need to adjust stack. So lua_getref does not change the stack,
and lua_pushref can use it as a macro.
1997-06-06 17:54:40 -03:00
Roberto Ierusalimschy e1249970c2 new API function to force garbage collection. 1997-05-26 11:42:51 -03:00
Roberto Ierusalimschy 9d6f4e48a6 unused declaration. 1997-05-26 11:42:36 -03:00
Roberto Ierusalimschy b546a042e8 another (better?) implementation for "pushsubscript". 1997-05-26 11:23:55 -03:00
Roberto Ierusalimschy bd9e68cfcd new implementation of gc: "Pre-collect" garbage in temporary lists and
then call fallbacks.
1997-05-14 15:38:29 -03:00
Roberto Ierusalimschy 9747f3c87a double hashing + tables do not grow if there are empty slots 1997-05-08 17:43:30 -03:00
Roberto Ierusalimschy 12d9731a49 bug: string table must be initialized. 1997-05-05 17:21:23 -03:00
Roberto Ierusalimschy 4aade854bb correction of name (and "iternal" was wrong, any way). 1997-04-30 16:55:47 -03:00
Roberto Ierusalimschy 369dd65318 small optimization in the access to i.m. table. 1997-04-24 19:59:57 -03:00
Roberto Ierusalimschy 209602ac31 BUG: input file must be closed just after parser. 1997-04-15 14:32:47 -03:00
Roberto Ierusalimschy 6251d889ca missing definition of "lua_storesubscript", for compatibility 1997-04-15 13:52:20 -03:00
Roberto Ierusalimschy faec0b0824 new pragma "$endinput" 1997-04-14 16:08:09 -03:00
Roberto Ierusalimschy 64d93e7cf9 global variables (in $if) may have '_'. 1997-04-14 12:30:29 -03:00
Roberto Ierusalimschy d73c5bcfe7 function name is only needed *if* there is an error. 1997-04-14 12:30:03 -03:00
Luiz Henrique de Figueiredo e78c1c54aa mem.h is now luamem.h
removed warn
added support for new opcodes (VARARGS, STOREMAP)
better error messages with luaL_verror
1997-04-14 09:12:40 -03:00
Luiz Henrique de Figueiredo 42049b42f1 fix comment in VERSION 1997-04-14 09:12:40 -03:00
Roberto Ierusalimschy a8cd072c76 nested "$if's", "$else", and "$if" constants (nil & 1). 1997-04-12 12:01:49 -03:00
Roberto Ierusalimschy 83e9897cf0 correction on comments about opcodes. 1997-04-11 18:34:53 -03:00
Roberto Ierusalimschy f93704728f one cannot "create" a userdata. 1997-04-08 12:41:44 -03:00
Roberto Ierusalimschy c9e3d32182 first implementation of "$if";
new function "findstring" (useful in good places)
1997-04-07 11:48:53 -03:00
Roberto Ierusalimschy 00050b8a6b detail: local names 1997-04-06 11:17:06 -03:00
Roberto Ierusalimschy 19a1e19ae1 detail: better way to put a "..." in message. 1997-04-06 11:14:27 -03:00
Roberto Ierusalimschy 3a9516ffc8 luaL check functions do not need the function name (it can be
accessed via luadebug interface).
1997-04-06 11:08:08 -03:00
Roberto Ierusalimschy 42fa305649 better error messages;
better names for some API functions.
1997-04-04 19:24:51 -03:00
Roberto Ierusalimschy 9319735744 using new lib auxlib. 1997-04-04 12:35:37 -03:00
Roberto Ierusalimschy 1ea6e8064c "setintmethod" returns old method (to be coerent with seterrormethod).
BUG: wrong pointer arithmetic (index out of range when comparing).
obs: version 4 is due to internal methods.
1997-04-03 15:27:06 -03:00
Roberto Ierusalimschy c1746340c3 obs: version 4 is due to internal methods.
(some small details in comments)
1997-04-03 15:26:08 -03:00
Roberto Ierusalimschy d0339e7b72 "setintmethod" returns old method (to be coerent with seterrormethod).
obs: version 2 is due to internal methods.
1997-04-03 15:24:23 -03:00
Roberto Ierusalimschy 075b7918c3 new function "getintmethod" 1997-04-02 20:04:12 -03:00
Roberto Ierusalimschy 7c99149a76 "tostring" gives an overview of a userdata. 1997-04-02 19:53:35 -03:00
Roberto Ierusalimschy 27d95f1880 "newtag" does not need a type name. 1997-04-02 19:52:42 -03:00
Roberto Ierusalimschy f0d523887d lua_getuserdata must return NULL if object is not userdata 1997-04-02 14:44:18 -03:00
Roberto Ierusalimschy f29fbf2bf6 lua_getuserdata must return NULL if object is not userdata;
small BUG: wrong error message for a=b[1] (b not a table)
1997-04-02 14:44:18 -03:00
Roberto Ierusalimschy 4355e1afcd "getbyte" returns userdata size when called without second parameter. 1997-04-02 14:44:18 -03:00
Roberto Ierusalimschy cae1eff901 small "bugs" detected by Purify: cannot read "next" after 0. 1997-04-01 18:23:20 -03:00
Roberto Ierusalimschy f83bc86e51 small "bugs" detected by Purify: some blocks may be smaller than
sizeof(int).
1997-04-01 18:23:20 -03:00
Roberto Ierusalimschy 59744f0311 "storeglobal" changed to "setglobal" 1997-04-01 16:02:43 -03:00
Roberto Ierusalimschy bb2e2bec18 new lua function "tag" 1997-04-01 14:31:42 -03:00
Roberto Ierusalimschy efaaf99c42 first version of "setglobal" and "getglobal" internal methods. 1997-03-31 17:59:09 -03:00
Roberto Ierusalimschy f8a571ee35 some new options for warnings and optimizations. 1997-03-31 17:58:42 -03:00
Roberto Ierusalimschy 397e32399b update of ".h" dependencies 1997-03-31 11:23:49 -03:00
Roberto Ierusalimschy 373363cb69 new name for old "mem.h" (conflicts with some compiler libraries) 1997-03-31 11:19:01 -03:00
Roberto Ierusalimschy ad5574c4c9 "Object" renamed to "TObject" (Tagged Object), to avoid conflicts with
pre-defined names in some C compilers.
1997-03-31 11:02:58 -03:00
Roberto Ierusalimschy 264f8c5e7b new (internal?) functions to manipulate userdata 1997-03-26 19:23:15 -03:00
Roberto Ierusalimschy 9e9e2ea287 BUG: must mark userdata in garbage collection. 1997-03-26 19:22:41 -03:00
Roberto Ierusalimschy 03d917f229 some corrections, improvements; 1997-03-24 14:13:22 -03:00
Roberto Ierusalimschy c3488f5115 must call "gc" i.m. for nil after all others. 1997-03-21 18:39:57 -03:00
Roberto Ierusalimschy 6fef372fb8 mathlib now uses i.m. for "pow" operator. 1997-03-21 15:37:28 -03:00
Roberto Ierusalimschy 052a1cc46c files now have proper tags. 1997-03-20 17:36:58 -03:00
Roberto Ierusalimschy ae067dcddd BUG: lua_newtag can be called before luaI_IMtable is initialized. 1997-03-20 17:36:19 -03:00
Roberto Ierusalimschy 5d60470508 i.m. "arith" and "order" splited for different operations 1997-03-20 16:20:43 -03:00
Roberto Ierusalimschy 88d7ffb0d0 luaI_type moved to fallback.c 1997-03-20 16:20:23 -03:00
Roberto Ierusalimschy 47527d2d3c setmethods should return old methods. 1997-03-19 18:12:34 -03:00
Roberto Ierusalimschy 1444d28476 first full implementation of internal methods 1997-03-19 16:41:10 -03:00
Roberto Ierusalimschy 2de803c250 new header 'auxlib.h' + new function luaL_verror 1997-03-18 12:30:50 -03:00
Roberto Ierusalimschy fa08b42dd8 new header for auxiliar functions. 1997-03-18 12:30:50 -03:00
Roberto Ierusalimschy eea734aa88 new module 'auxlib' centralizes functions to get/check parameters. 1997-03-17 14:02:29 -03:00
Roberto Ierusalimschy b6d91e24e2 "tag" changed to "ttype" (since now tag has other meaning) 1997-03-11 15:44:28 -03:00
Roberto Ierusalimschy a82ab0852e new explanation about communication between Lua and C. 1997-03-06 19:19:08 -03:00
Roberto Ierusalimschy b8af9c56c9 new form for constructors: {[exp] = exp, ...} 1997-03-06 14:30:55 -03:00
Roberto Ierusalimschy c3c0b52a1f atualization of #include dependencies. 1997-03-05 10:37:04 -03:00
Roberto Ierusalimschy ec422ec7d0 skips can be nested (why not?). 1997-03-05 10:32:41 -03:00
Roberto Ierusalimschy a8a15ff1bd "mem.c.debug" incorporated (with "#if"). 1997-03-03 16:55:38 -03:00
Roberto Ierusalimschy 131d66efd2 first step in implementing internal methods. 1997-02-26 14:38:41 -03:00
Roberto Ierusalimschy bbf1b3060a small correction. 1997-02-26 14:07:57 -03:00
Roberto Ierusalimschy 8b7f271ea2 new pattern item ".-";
empty patterns may be used in gsub.
1997-02-21 12:21:34 -03:00
Roberto Ierusalimschy bc323435ee new facilities for pattern matching (%b and .-);
explanations about  next-nextvar.
1997-02-21 12:19:37 -03:00
Roberto Ierusalimschy 6769f34817 lua_Type is private (preparation for tags) 1997-02-20 12:51:14 -03:00
Roberto Ierusalimschy 0b110f7922 small syntax error (yacc does not complain, but bison does). 1997-02-13 14:18:39 -02:00
Roberto Ierusalimschy 205ee1ec84 userdata can handle arbitrary binary data;
user tag is stored with data;
1997-02-11 09:40:01 -02:00
Roberto Ierusalimschy b48847c5fa BUG: "inclinenumber" cannot use public buffer, since it could change
the buffer pointer (luaY_lex and read_long_string have local
pointers to it).
1997-02-07 11:49:46 -02:00
Roberto Ierusalimschy 1143bf9286 better check when converting from float to int, to avoid overflow
(on some machines it may result in run-time error)
1997-01-31 12:27:11 -02:00
Roberto Ierusalimschy d9ecc13545 lhf revisions/sugestions 1997-01-23 14:17:53 -02:00
Roberto Ierusalimschy f00d692445 small correction to avoid "wrong" default action 1997-01-15 14:11:37 -02:00
Roberto Ierusalimschy d8b0bbb2ad BUG: pointer arithmetic does not have to work when pointing outside
an array.
1996-11-22 11:08:28 -02:00
Roberto Ierusalimschy 1f4ee4a4d2 ANSI ctype only works for unsigned chars (or EOF) 1996-11-22 11:08:02 -02:00
Roberto Ierusalimschy 6a9efa8b8e useless include. 1996-11-22 11:07:20 -02:00
Roberto Ierusalimschy 65459e7938 small BUG: pragma deletes 0 at end of yytext, so a syntax error just after
it may have a wrong token in message.
1996-11-21 12:44:04 -02:00
Roberto Ierusalimschy 42359b8b13 new version 1996-11-20 11:49:32 -02:00
Roberto Ierusalimschy 169870e37d BUG: ISO chars are negative, ISO ints are not. 1996-11-20 11:47:59 -02:00
Roberto Ierusalimschy 78e454d864 BUG: ISO chars are negative, ISO ints are not.
new "balanced" pattern.
1996-11-20 11:47:59 -02:00
Roberto Ierusalimschy dbfe28e199 correction in inheritance code in C 1996-11-18 12:27:42 -02:00
Roberto Ierusalimschy d59c52753f undump needs file in binary mode 1996-11-18 11:48:44 -02:00
Roberto Ierusalimschy 62e1a4c84d BUG: problems with negative indexes 1996-11-18 11:48:44 -02:00
Luiz Henrique de Figueiredo 81411e8913 headers includes sizeof(Word) not sizeof(int) 1996-11-18 09:18:29 -02:00
Luiz Henrique de Figueiredo 62aa717f7e stdlib.h for exit
blocks are void*
1996-11-16 18:14:23 -02:00
Roberto Ierusalimschy a5614eae3c spelling corrections. 1996-11-14 15:45:37 -02:00
Luiz Henrique de Figueiredo 536bae5871 corrected version test (0x23 not 23) 1996-11-14 13:00:32 -02:00
Luiz Henrique de Figueiredo 679eddf296 1996-11-14 11:33:15 -02:00
Luiz Henrique de Figueiredo d991def36c added 3 new bytes to header (sizeof's) 1996-11-14 09:44:34 -02:00
Luiz Henrique de Figueiredo 8b195533d2 new header version 1996-11-14 09:44:34 -02:00
Roberto Ierusalimschy 3ccdd57c26 new version 1996-11-12 14:00:16 -02:00
Roberto Ierusalimschy a103455dda better format for error messages. 1996-11-08 17:08:30 -02:00
Roberto Ierusalimschy 60242e1930 error message for syntax "1..2";
syntax error function is in "lex.c" (it has the token)
1996-11-08 10:49:35 -02:00
Roberto Ierusalimschy a0e9bfbb48 syntax error function is in "lex.c" (it has the token) 1996-11-08 10:49:35 -02:00
Roberto Ierusalimschy 2f19e0ba16 SunOS is not ANSI about the return value of "sprintf". 1996-11-07 18:26:19 -02:00
Roberto Ierusalimschy ab7fdcbbed corrected copyright notice 1996-11-07 18:26:08 -02:00
Luiz Henrique de Figueiredo 48cf1de356 replaced unions by memcpy 1996-11-07 12:13:28 -02:00
Luiz Henrique de Figueiredo 8d50122af0 replaced unions by memcpy 1996-11-07 11:59:51 -02:00
Roberto Ierusalimschy fd379b38f7 new flag for STRERROR; libs now are called lib... 1996-11-06 18:48:03 -02:00
Roberto Ierusalimschy aa4d865077 anna's comments 1996-11-06 18:26:56 -02:00
Roberto Ierusalimschy 3e94febfc1 pragmas should not be recognized inside literal strings. 1996-11-06 18:24:29 -02:00
Roberto Ierusalimschy 243b3a1a47 i/o functions return an error message 1996-11-01 16:02:53 -02:00
Roberto Ierusalimschy 389e808c60 although an ANSI function, some systems do not offer "strerror" 1996-11-01 15:54:41 -02:00
Roberto Ierusalimschy 450465c4d4 new parameters for "read" and "write". BIG CHANGE. 1996-11-01 15:03:36 -02:00
Roberto Ierusalimschy 2f44cc9f4d new pattern matching facilities; new version of i/o lib;
other small corrections.
1996-11-01 15:02:10 -02:00
Roberto Ierusalimschy d106f3f43c pre-defined variable _VERSION_ 1996-11-01 10:47:45 -02:00
Roberto Ierusalimschy bf3091d94f new version number 1996-11-01 10:46:59 -02:00
Roberto Ierusalimschy 4dbf7285a8 small omission corrected ("s_tsvalue") 1996-11-01 10:46:59 -02:00
Roberto Ierusalimschy a1e41e3a12 small corrections in error messages 1996-10-31 18:18:05 -02:00
Roberto Ierusalimschy 9d0044ce53 "strfind" has an extra parameter to turn off all special characteres. 1996-10-31 15:26:04 -02:00
Roberto Ierusalimschy 37bf74efb7 some compilers do not accept "stdin"/"stdout" as constants. 1996-10-16 18:22:34 -02:00
Roberto Ierusalimschy 8c37d3b9d6 documentation of opcode meanings (thanks to lhf) 1996-09-26 18:08:41 -03:00
Roberto Ierusalimschy 0af581f0bf new way to handle pragmas (at the lexical level, instead of parsing). 1996-09-25 18:52:00 -03:00
Roberto Ierusalimschy 2a506ea9d2 lua_linenumber is initialized in lex.c 1996-09-25 09:57:22 -03:00
Roberto Ierusalimschy e5ec547eb3 "call" returns separate results, instead of a table. 1996-09-24 18:46:44 -03:00
Roberto Ierusalimschy 6d383202dc "dofile" and "dostring" may return values. 1996-09-24 14:30:28 -03:00
Roberto Ierusalimschy 7b8166d7b3 a chunk may end with a return. 1996-09-24 14:29:50 -03:00
Roberto Ierusalimschy 3636bbad3a new function "strrep" 1996-09-20 15:20:44 -03:00
Roberto Ierusalimschy 82f9f3e552 better structure to control stack interface lua-C.
beginblock-endblock keeps better control over stack
1996-09-20 09:51:16 -03:00
Roberto Ierusalimschy c96ad1c945 "strmap" replaced by "strupper" and "strlower" (that's what people will
use, anyway).
"gsub" aceppts a function to give the replacement string.
1996-09-16 15:02:40 -03:00
Roberto Ierusalimschy 5b9fbfa006 "dostring" now stores the prefix of its string, to improve error messages. 1996-09-11 18:53:02 -03:00
Roberto Ierusalimschy f0cc2d5506 BUG: a program ending in a comment without EOL made lex loops forever. 1996-09-09 11:11:11 -03:00
Roberto Ierusalimschy d289ac81d3 functions may have tags CMARK and MARK, too. 1996-09-02 18:57:51 -03:00
Roberto Ierusalimschy 15791f93fe lhf's corrections. 1996-08-28 17:46:26 -03:00
Roberto Ierusalimschy d763b69740 skip first line of a lua file if it starts with a '#' (to allow shell
scripts).
1996-08-15 15:40:55 -03:00
Roberto Ierusalimschy 36dd1af92d "[^]]" must mean "not ]". 1996-08-09 10:14:11 -03:00
Roberto Ierusalimschy 25b6dae7c0 singlematch and item_end are used by "read", in iolib. 1996-08-05 17:55:24 -03:00
Roberto Ierusalimschy 1630c2533a Pattern-Matching!
plus several other changes...
1996-08-01 11:55:33 -03:00
Roberto Ierusalimschy 1d373d77de more functions exported. 1996-08-01 11:55:33 -03:00
Roberto Ierusalimschy f025b0d160 "pushnil" is not needed (default return is nil). 1996-08-01 11:55:33 -03:00
Roberto Ierusalimschy cc02b4729b new mod implementation (more portable). 1996-08-01 11:55:33 -03:00
Roberto Ierusalimschy 2bb3830fc1 "memcpy" is defined in "string.h". 1996-07-24 15:01:52 -03:00
Roberto Ierusalimschy 7a38bdd4b3 "exit" is defined in "stdlib". 1996-07-24 14:55:57 -03:00
Roberto Ierusalimschy 7614b17e85 very small corrections 1996-07-24 11:38:12 -03:00
Roberto Ierusalimschy 6dfdb76538 C functions don't need to "pushnil" to return nil value (this is
the default value).
1996-07-12 17:00:26 -03:00
Roberto Ierusalimschy 9a3c51cff1 new name for POSIX flag (this one turns on some posix stuff in standard
header files).
1996-07-06 17:20:35 -03:00
Roberto Ierusalimschy 6336d2f9e1 flag for direct execution is "-e"; argument with an "=" goes to
direct execution, independently of flags.
1996-07-05 17:55:43 -03:00
Roberto Ierusalimschy ec6677e551 when "block" is computed, "nentity" == "block". So the change is only
a simpler way to write the same expression.
1996-06-18 18:12:23 -03:00
Roberto Ierusalimschy 20cbca699a "lua_dofile" has a more informative return code. 1996-06-18 17:08:40 -03:00
Roberto Ierusalimschy 3211a9648a "lua_dofile" returns different error codes if it could not open the file 1996-06-10 16:36:24 -03:00
Roberto Ierusalimschy 0baa915343 new option "-x" to execute a string given as argument. 1996-06-10 16:35:46 -03:00
Roberto Ierusalimschy 5cddb264d4 lexical analiser may use luaI_buffer, instead of waste space with
a separate buffer.
1996-05-30 11:04:07 -03:00
Roberto Ierusalimschy 9863223fbf first version of vararg facility (plus new function "call"). 1996-05-28 18:07:32 -03:00
Roberto Ierusalimschy 9a1948e67d small correction. 1996-05-27 11:06:58 -03:00
Roberto Ierusalimschy f9deeac632 "luaI_malloc(s)" is just a macro to "luaI_realloc(NULL, s)". 1996-05-24 11:31:10 -03:00
Roberto Ierusalimschy 29f0021837 variables which contain string lengths must be long (if they also may
be negative) or size_t.
1996-05-22 18:59:07 -03:00
Roberto Ierusalimschy 7acddb871d memory manager for old versions of Lua. It should be in RCS since
the beginning.
1996-05-06 18:37:28 -03:00
Roberto Ierusalimschy a7ca46405d unused "#include". 1996-05-06 13:59:00 -03:00
Roberto Ierusalimschy 0e2297afaa update of dependencies from "#include"s. 1996-05-06 11:38:40 -03:00
Roberto Ierusalimschy 0a1891f6a0 new version. 1996-05-06 11:32:59 -03:00
Roberto Ierusalimschy 1936a9e53b tables may grow bigger than words. 1996-05-06 11:30:27 -03:00
Roberto Ierusalimschy 820ec63bdf as strings are no more duplicated, "nextvar" can use "pushstring". 1996-05-06 11:29:35 -03:00
Roberto Ierusalimschy 01ea523b80 small corrections. 1996-05-03 17:10:59 -03:00
Roberto Ierusalimschy 88cf0836fc "isatty" is POSIX, but not ANSI. 1996-05-03 14:27:03 -03:00
Roberto Ierusalimschy 3ec9ee0d0f new function "luaI_openlib" to help open libs. 1996-04-30 18:13:55 -03:00
Roberto Ierusalimschy 21c9ebf4a9 new algotithm to adjust garbage collection: it tries to adapt gc calls
so that it collects half of the total objects when it is called.
1996-04-29 15:53:53 -03:00
Roberto Ierusalimschy 4fb77c4308 no more "lua_Reference"; new return value for "append";
documentation of "exit" (it was not in the manual).
1996-04-29 15:50:08 -03:00
Roberto Ierusalimschy bced00ab9e lua_Reference is int, so say so. 1996-04-25 11:10:00 -03:00
Roberto Ierusalimschy 25116a3065 "malloc.h" is not ansi. 1996-04-25 11:01:27 -03:00
Roberto Ierusalimschy eadbb9cff4 "stat" is not ansi. 1996-04-23 09:43:07 -03:00
Roberto Ierusalimschy 42b947296b "fileno" is not ansi. 1996-04-23 09:43:07 -03:00
Roberto Ierusalimschy f37e65d1cb "exit" has an optional parameter of status. 1996-04-22 16:28:37 -03:00
Roberto Ierusalimschy 0ef5cf2289 lock mechanism seperseded by the REFERENCE mechanism. 1996-04-22 15:00:37 -03:00
Roberto Ierusalimschy fed9408ab5 page size "letter". 1996-04-01 11:36:35 -03:00
Roberto Ierusalimschy ce23901f04 smaller limit to stack size (otherwise C stack can finish first) 1996-03-22 16:12:15 -03:00
Roberto Ierusalimschy df1ee1fb1c small "abstraction" 1996-03-22 14:57:24 -03:00
Roberto Ierusalimschy f1d0276684 small bug in strfind. 1996-03-21 19:18:08 -03:00
Roberto Ierusalimschy 7ecc2ea597 new version 1996-03-21 18:30:29 -03:00
Roberto Ierusalimschy 7a35f23c16 a simplification about memory error messages. 1996-03-21 15:55:02 -03:00
Roberto Ierusalimschy 9284742a11 better control when growing arrays. 1996-03-21 13:33:47 -03:00
Roberto Ierusalimschy 9704ff4cb1 hook variables are global, no more "lua_set...hook" functions. 1996-03-20 15:44:02 -03:00
Roberto Ierusalimschy e3c0ce9a69 dofile accepts pre-compiled chunks.
lua_is... do coercion.
small correction: = versus ==.
1996-03-19 19:39:07 -03:00
Roberto Ierusalimschy 85b76bcc01 functions "lua_is..." consider coercions.
small change when calling call hook.
1996-03-19 19:28:37 -03:00
Roberto Ierusalimschy a275d9a25b functions "lua_is..." consider coercions. 1996-03-19 19:28:37 -03:00
Roberto Ierusalimschy 7e0be1fbde unused "#include" 1996-03-19 13:50:24 -03:00
Roberto Ierusalimschy 54ba642cc3 new module "undump.o" 1996-03-15 15:22:09 -03:00
Roberto Ierusalimschy 8826eb7918 small correction 1996-03-15 15:21:58 -03:00
Roberto Ierusalimschy e701a86385 "openfile" now returns the file 1996-03-15 10:13:13 -03:00
Roberto Ierusalimschy 3e1f731826 integration with undump (execution of pre-compiled chuncks) 1996-03-15 10:13:13 -03:00
Roberto Ierusalimschy f86c1367db new functions "rename" and "tmpname".
new option 'q' for function "format".
new example, about vararg.
1996-03-14 14:45:01 -03:00
Luiz Henrique de Figueiredo 58fd8aa851 added cast instead of union [lazy?] 1996-03-14 14:31:15 -03:00
Roberto Ierusalimschy 3226ac2da8 "lua_ntable" and "lua_nconstant" are public (undump.c uses them). 1996-03-14 12:57:19 -03:00
Roberto Ierusalimschy 3e9daa7416 creation of strings must call garbage collector. 1996-03-14 12:56:26 -03:00
Roberto Ierusalimschy 7236df875a new function "luaI_buffer". 1996-03-14 12:55:49 -03:00
Roberto Ierusalimschy 675e608325 new functions "rename" and "tmpname". 1996-03-14 12:55:18 -03:00
Roberto Ierusalimschy 1dc0e82aeb "freefunc" now is public. 1996-03-14 12:54:20 -03:00
Roberto Ierusalimschy c2eb02aaf6 both "write" and "format" need "addquoted". 1996-03-14 12:53:09 -03:00
Roberto Ierusalimschy 2fee7e42c9 new option 'q' in function "format". 1996-03-14 12:52:35 -03:00
Roberto Ierusalimschy 281db390e8 no more "ugly" programs.
no more comments with '#'.
1996-03-14 12:17:28 -03:00
Luiz Henrique de Figueiredo df8cf53cc9 removed tf->marked=0; 1996-03-12 17:00:40 -03:00
Roberto Ierusalimschy 40306b10db small corrections. 1996-03-12 12:56:03 -03:00
Luiz Henrique de Figueiredo 5eff5d3eac moved some includes from undump.h
LoadString now uses luaI_buffer
added LoadNewString
needs tf->marked=0
luaI_undump now returns int and aborts if luaI_dorun fails
1996-03-11 19:01:46 -03:00
Luiz Henrique de Figueiredo 8ad8426c43 moved some includes to undump.c
luaI_undump now returns int
1996-03-11 18:59:41 -03:00
Luiz Henrique de Figueiredo 3cab7cd025 undump.c is now a module
panic is now lua_error
 included swap.c
 tries float permutation earlier
 new functions: luaI_undump1 and luaI_undump
1996-03-08 18:44:12 -03:00
Luiz Henrique de Figueiredo bb26efbbec definitions for lua decompiler
undump is now a module
1996-03-08 18:43:21 -03:00
Roberto Ierusalimschy 5c0e5fd36d details. 1996-03-08 09:04:04 -03:00
Roberto Ierusalimschy 621322a305 "PrintCode" now is defined in luac. 1996-03-08 09:02:37 -03:00
Luiz Henrique de Figueiredo e33a3b8e0d now loads size as two words 1996-03-06 18:40:10 -03:00
Luiz Henrique de Figueiredo 9a6cccb08c removed support for local vars 1996-03-06 13:01:08 -03:00
Roberto Ierusalimschy b58225e93b unused declaration removed. 1996-03-06 10:11:23 -03:00
Luiz Henrique de Figueiredo 852b919465 now swaps bytes (but need to make it more robust) 1996-03-05 22:41:18 -03:00
Roberto Ierusalimschy ef94999647 parse.o was included twice in lua.a 1996-03-05 12:57:53 -03:00
Roberto Ierusalimschy 6f30fa98d8 small change to avoid error on "lua_pushstring(NULL)". 1996-03-04 11:46:35 -03:00
Roberto Ierusalimschy 74102bd716 small corrections. 1996-03-04 10:29:10 -03:00
Roberto Ierusalimschy 8d82aa821a small correction (about types) 1996-03-01 13:54:00 -03:00
Luiz Henrique de Figueiredo cec1ffb80b uses ID_* constants
simplified signature checking
loads local vars
1996-03-01 00:43:50 -03:00
Luiz Henrique de Figueiredo 870967ca77 headers for Main and others are different 1996-02-28 20:10:46 -03:00
Roberto Ierusalimschy 66fc0f554a using double to read numbers. 1996-02-26 19:35:51 -03:00
Roberto Ierusalimschy d6e4c29733 fixed strings (not collectable) don't need to be inserted in the constant table. 1996-02-26 18:00:27 -03:00
Luiz Henrique de Figueiredo 3e42969979 main always reads "luac.out" 1996-02-26 16:44:17 -03:00
Roberto Ierusalimschy 712ac505e0 small correction 1996-02-26 14:07:49 -03:00
Roberto Ierusalimschy f935d3397e check if jump is bigger than 2^16. 1996-02-26 14:07:20 -03:00
Roberto Ierusalimschy 30dd3a2dbc small changes (preparing for new module of pre-compilation) 1996-02-26 14:06:39 -03:00
Luiz Henrique de Figueiredo b04f88d581 functions now linked into a list headed by main 1996-02-24 13:44:28 -03:00
Luiz Henrique de Figueiredo b3c10c8c41 fix to PUSHFUNCTION now correctly at tf->marked 1996-02-24 00:46:57 -03:00
Luiz Henrique de Figueiredo 5c1bd89a1c added fix to PUSHFUNCTION and support for main function 1996-02-23 19:00:26 -03:00
Luiz Henrique de Figueiredo 15f3ab09eb load bytecodes from files 1996-02-23 16:04:38 -03:00
Roberto Ierusalimschy c7e834f424 function "write_quoted" rewritten more clearly. 1996-02-22 17:56:33 -03:00
Roberto Ierusalimschy 8c1a9899d4 functions "luaI_free" and "luaI_realloc" (or macro "growvector") may be
called with NULL.
1996-02-22 17:34:33 -03:00
Roberto Ierusalimschy 05caf09a36 list of incompatibilities with version 2.2.
new macro \Version.
1996-02-16 10:12:12 -03:00
Roberto Ierusalimschy 168a865e60 more appropriate error message for "date" 1996-02-16 10:10:14 -03:00
Roberto Ierusalimschy 15c17c24fa small improvements 1996-02-14 16:11:09 -03:00
Roberto Ierusalimschy 45cf24485d useless #include. 1996-02-14 15:25:04 -03:00
Roberto Ierusalimschy c56e2b2e30 new version 1996-02-14 10:40:26 -03:00
Roberto Ierusalimschy d1608c597e reserved words are stored in main string table; "marked" field is
used to indicate its type.
Table initializations centralized by "tree.c".
1996-02-14 10:35:51 -03:00
Roberto Ierusalimschy 0f4903a5d7 new header "lex.h". 1996-02-13 14:30:39 -03:00
Roberto Ierusalimschy 772f25d3dd new header for lex.c 1996-02-13 14:30:39 -03:00
Roberto Ierusalimschy f1a1eda7c5 old trick in "strsub" does not work with new hash table for strings. 1996-02-12 15:34:44 -03:00
Roberto Ierusalimschy 41259bff31 BIG CHANGE: new data structure for constants, strings and globals, using
an array of hash tables for all them.
1996-02-12 15:32:40 -03:00
Roberto Ierusalimschy afaa98a666 no more "lua_pushliteral". 1996-02-12 15:32:09 -03:00
Roberto Ierusalimschy 73be918285 a backslash followed by a newline allows the newline to go into
a string.
1996-02-09 17:35:23 -02:00
Roberto Ierusalimschy ca412214cb new function "date", replaces old "date" and "time". 1996-02-09 17:02:30 -02:00
Roberto Ierusalimschy 801722825d "lua_check_number" accepts strings convertible to numbers. 1996-02-09 17:00:23 -02:00
Roberto Ierusalimschy 3abc25fa54 new functions "random" and "randomseed". 1996-02-09 15:21:27 -02:00
Roberto Ierusalimschy f4d67761f1 new section describing the debug interface. 1996-02-09 14:37:58 -02:00
Roberto Ierusalimschy 369c5fe3c0 lock mechanism more robust; nil is pseudo-locked under index -1. 1996-02-08 17:08:34 -02:00
Roberto Ierusalimschy 7918c6cf11 small bug 1996-02-08 16:14:17 -02:00
Roberto Ierusalimschy 826d70fcba new type lua_Function for activation records 1996-02-08 15:03:20 -02:00
Roberto Ierusalimschy bbb23048e3 correction of dependencies (include's). 1996-02-07 16:14:38 -02:00
Roberto Ierusalimschy 5a3a1fe458 debug interface functions to manipulated local variables:
"lua_getlocal" and "lua_setlocal".
1996-02-07 16:10:27 -02:00
Roberto Ierusalimschy 56fb06b6f5 "lua_debug" now is exported through debug interface (luadebug.h) 1996-02-07 12:14:40 -02:00
Roberto Ierusalimschy 995a9f7188 no more "Bool" type 1996-02-07 12:13:17 -02:00
Roberto Ierusalimschy a0ef046ef1 elimination of unused declarations (left from old modifications) 1996-02-06 14:18:21 -02:00
Roberto Ierusalimschy 5fa51fc426 new option "q" in function "write", to write literal strings. 1996-02-05 19:32:19 -02:00
Roberto Ierusalimschy 15057aa0a4 new examples showing data structures and object-oriented programming.
generic improvements and corrections.
1996-02-05 12:52:47 -02:00
Roberto Ierusalimschy 1431b52e76 improve of compiling error messages. 1996-02-05 11:26:01 -02:00
Roberto Ierusalimschy 98fe770cab small bug 1996-02-04 14:59:12 -02:00
Roberto Ierusalimschy 43382ce5a2 new fallback "getglobal". 1996-01-30 13:25:23 -02:00
Roberto Ierusalimschy abfebf1e21 new example showing how to build modules. 1996-01-30 13:24:49 -02:00
Roberto Ierusalimschy b1c02c7f00 new fallback "getglobal".
modifications to generate an index (not automatically yet).
1996-01-30 10:55:10 -02:00
Roberto Ierusalimschy 84df3ac267 new functions "tostring", "assert", and "format". 1996-01-29 15:08:23 -02:00
Roberto Ierusalimschy 55a70c9719 "read('s')" was "eating" delimiter. 1996-01-29 14:40:09 -02:00
Roberto Ierusalimschy 0d50b87aa4 lua_table now has references to global variable names (TreeNode's). 1996-01-26 16:03:19 -02:00
Roberto Ierusalimschy 19290a8e92 "dofile" issues an error when called with non string arguments, and
runs stdin when called without arguments.
1996-01-26 14:52:47 -02:00
Roberto Ierusalimschy d845963349 "setglobal" and "getglobal" moved to inout.c, as it concentrates pre-defined
library.
new function "assert".
1996-01-26 12:05:28 -02:00
Roberto Ierusalimschy 8dae4657a1 "setglobal" and "getglobal" moved to inout.c, as it concentrates pre-defined
library.
1996-01-26 12:04:32 -02:00
Roberto Ierusalimschy ca7be1cfeb elimination of function "int2str", as it can be replaced by "format('%c', .)" 1996-01-26 10:11:28 -02:00
Roberto Ierusalimschy 445872a6e2 "dofile" does not issue a warning when unable to open the file,
but only returns an error code.
1996-01-23 16:43:07 -02:00
Roberto Ierusalimschy 3681d025ac new function "assert" 1996-01-23 16:39:45 -02:00
Roberto Ierusalimschy 2998049f51 local variable stack needs only the name of the variable (TreeNode);
this way is simpler and faster than old way.
1996-01-23 15:50:29 -02:00
Roberto Ierusalimschy 24ccc7c038 correction of some order dependencies in debug code. 1996-01-22 16:39:37 -02:00
Roberto Ierusalimschy be48c4d91e add_char now is global.
time returns week-day.
1996-01-22 15:46:55 -02:00
Roberto Ierusalimschy a19f9056f3 new function "tostring". 1996-01-22 15:40:00 -02:00
Roberto Ierusalimschy 5b71ab780c add_char now is global.
new function format.
1996-01-22 15:38:57 -02:00
Roberto Ierusalimschy 481bafd581 add_char now is global. 1996-01-22 15:38:57 -02:00
Roberto Ierusalimschy e74b250d71 memory overflow tries a garbage collection; if it fails then exit the
program.
1996-01-22 12:15:13 -02:00
Roberto Ierusalimschy cd54c95ee1 bug: "read" with format MUST read given number of chars (if file ends
before that reports an error, returning nil).
"readuntil" can be called with nil or no parameters to read until EOF.
1996-01-12 15:00:30 -02:00
Roberto Ierusalimschy bf006eeaf5 "getobjectname" got a "lua_" prefix. 1996-01-09 18:23:19 -02:00
Roberto Ierusalimschy b2afc410fa hooks for line change and function calls; first version. 1996-01-09 18:22:44 -02:00
Roberto Ierusalimschy 19cfa32393 correction of dependencies from "luadebug.h". 1996-01-09 18:22:08 -02:00
Roberto Ierusalimschy 27ae8432b6 names generated by yacc (starting with "yy") are changed to start with
"luaY_", to avoid name clashes with hosts using yacc.
1995-12-21 14:14:04 -02:00
Roberto Ierusalimschy 415ee250b5 bug: luaI_findconstantbyname may change the value of lua_constant. 1995-12-18 14:47:29 -02:00
Roberto Ierusalimschy f188e1000b useless "#include math.h" 1995-11-16 18:46:24 -02:00
Roberto Ierusalimschy 07d64e78b6 reference manual 1995-11-16 18:46:02 -02:00
Roberto Ierusalimschy fa649fbc26 new distribution 1995-11-13 13:36:52 -02:00
Roberto Ierusalimschy 0c3e0fd95d "read" must return 'nil' on EOF. 1995-11-10 16:32:59 -02:00
Roberto Ierusalimschy 3bb6443131 changes to improve portability 1995-11-10 15:56:06 -02:00
Roberto Ierusalimschy f57afd6e32 re-implementation of functions "write" and "read" 1995-11-10 15:55:48 -02:00
Roberto Ierusalimschy 5f664a4516 error functions are shared by all libraries 1995-11-10 15:54:31 -02:00
Roberto Ierusalimschy 87fe07c0d4 little improvement 1995-11-10 12:12:02 -02:00
Roberto Ierusalimschy f9a9bd77e4 print_stack now gets a parameter (file to print);
small changes.
1995-11-03 13:43:50 -02:00
Roberto Ierusalimschy 63b8a6fd20 "getobjname" checks first fallbacks (so, if a function is global and
a fallback, it is reported as a fallback).
1995-11-03 13:30:50 -02:00
Roberto Ierusalimschy 024f2374ab "AUTHORS" separated from COPYRIGHT. 1995-10-31 15:05:35 -02:00
Roberto Ierusalimschy 9d9f9c48ff local variables may appear inside blocks in main code. 1995-10-26 15:02:50 -02:00
Roberto Ierusalimschy 15d48576ea functions now may be declared with any "var" as a name;
therefore they do not have a "baptism" name.
Changes in debug API to acomodate that.
1995-10-26 12:21:56 -02:00
Roberto Ierusalimschy 39b071f7b1 new syntax for function declarations: "function a.x () ... "
new semantics for function declarations: function f () is valid only
at run-time.
1995-10-25 12:33:25 -02:00
Roberto Ierusalimschy 9efc257d9d new method to keep debug line information: current line is stored on the
Lua stack, just below (new) base, with tag LUA_T_LINE.
SETLINE opcodes are generated by lex.
1995-10-25 11:05:51 -02:00
Roberto Ierusalimschy fa71304e54 "dofile" now accepts NULL as parameter, to run stdin. 1995-10-23 11:54:11 -02:00
Roberto Ierusalimschy b5745d11cd uses "isatty" to check if executes stdin line by line or as a file. 1995-10-23 11:54:11 -02:00
Roberto Ierusalimschy ebcf546a55 small changes in the format of debug information. 1995-10-23 11:53:48 -02:00
Roberto Ierusalimschy 2b45f8967c small bug 1995-10-17 16:16:58 -02:00
Roberto Ierusalimschy a66404aca6 function "setfallback" now gives an error if called with wrong parameters. 1995-10-17 12:30:05 -02:00
Roberto Ierusalimschy d80659759b new module luadebug.h. 1995-10-17 12:12:45 -02:00
Roberto Ierusalimschy d24253d92f module to declare API for debuging. 1995-10-17 12:12:45 -02:00
Roberto Ierusalimschy 2cffb08a5c new style for debug information about functions: no more SETFUNCTION
opcodes. When a function is called, its entry in the stack is marked with
LUA_T_(C)MARK, so function 'luaD_stackedfunction' can find it if
needed.
Functions now have their file names in the headers, so there is no need
of 'addfile' and the like.
1995-10-17 09:58:41 -02:00
Roberto Ierusalimschy 15f40fddca 'nextvar' now traverses the symbol array, instead of the constant tree. 1995-10-17 09:53:53 -02:00
Roberto Ierusalimschy 970995c3f2 'luaI_travfallbacks' now can look for a fallback. 1995-10-17 09:52:38 -02:00
Roberto Ierusalimschy b17c76817d new function "luaI_findconstantbyname". 1995-10-13 12:16:25 -03:00
Roberto Ierusalimschy b074306267 bug. "fgets" reads n-1 chars. 1995-10-11 17:50:56 -03:00
Roberto Ierusalimschy 3c75b75516 new module "func", for GC of functions,
and new "defines" for configuration setup.
1995-10-09 15:51:49 -03:00
Roberto Ierusalimschy 36a7fda014 bug: stack overflow error must leave space on the stack for error function. 1995-10-09 15:45:59 -03:00
Roberto Ierusalimschy 1bb3fb73cc fallback table now has number of parameters and results of each
fallback. This information is used by opcode.c, when calling a fallback.
1995-10-09 10:14:29 -03:00
Roberto Ierusalimschy 7e01348658 "docall" now assumes that called function is always on the stack, just
below "base". That gives more regularity for the stack shape, and
prevents fallbacks of being garbage collected if they are redefined
during execution.
1995-10-09 10:10:20 -03:00
Roberto Ierusalimschy 28b3017baf lua function "type" now returns the string "function" both for lua
functions and c functions.
1995-10-09 10:06:20 -03:00
Roberto Ierusalimschy ae808860ae new functions: "ascii" and "int2str",
small "re-engineering" on parameter checking.
1995-10-09 09:49:21 -03:00
Roberto Ierusalimschy a47e8c7dd0 small "re-engineering" on parameter checking.
correction of function "atan2".
1995-10-09 09:48:38 -03:00
Roberto Ierusalimschy 79ce619876 new command line options: -v to print Copyright message, and
- to read stdin.
1995-10-06 11:11:40 -03:00
Roberto Ierusalimschy 233f0b0cc7 definitions for Copyright and version notices 1995-10-06 11:11:10 -03:00
Roberto Ierusalimschy 025589f772 nova forma de comentarios: de '#' ate' fim de linha (para uso de lua
como shell)
1995-10-06 10:10:53 -03:00
Roberto Ierusalimschy 68f337dfa6 Garbage collection of functions + header structure for functions 1995-10-04 14:13:02 -03:00
Roberto Ierusalimschy f132ac03bc Module to manipulate function headers. 1995-10-04 11:20:26 -03:00
Roberto Ierusalimschy ec785a1d65 new option for "writeto" and "readfrom", to allow piped I/O on
machines that support it.
1995-10-04 10:53:10 -03:00
Roberto Ierusalimschy e0621e6115 new function "atan2". 1995-10-04 10:52:09 -03:00
Roberto Ierusalimschy 38411aa102 small correction to avoid problems with DOS/Windows 1995-10-03 15:06:10 -03:00
Roberto Ierusalimschy 3ec4f4eb86 small corrections to avoid warnings. 1995-10-02 14:03:33 -03:00
Roberto Ierusalimschy 367139c6d9 buffer for literals now grows dynamically, allowing big programs between [[ and ]]. 1995-09-15 17:48:26 -03:00
Roberto Ierusalimschy 457bac94ce small corrections to avoid uninitialized global variables. 1995-09-15 17:47:53 -03:00
Roberto Ierusalimschy bcf46ee83b new syntax for strings: [[ ... ]]. Still in tests,
since the code does not check buffer overflow.
1995-07-06 14:47:08 -03:00
Roberto Ierusalimschy 97b2fd1ba1 syntax for {...;...} is more flexible now. 1995-06-08 16:47:28 -03:00
Waldemar Celes e13753e2fb Ajustar limites para garbage collection. 1995-05-16 16:23:55 -03:00
Roberto Ierusalimschy ec79f25286 new lua function "getstack"; new interface to function luaI_reportbug. 1995-05-16 14:23:58 -03:00
Roberto Ierusalimschy 18ea2eff80 calls to "lua_reportbug" changed to "lua_error", since
"lua_reportbug" is only an internal function to build debug information
1995-05-02 15:43:03 -03:00
Waldemar Celes 8156604823 run-time stack now is controled at run time, instead of
compilation time.
1995-04-11 14:56:30 -03:00
Roberto Ierusalimschy 36b6fdda83 function "type" now returns a second result: the tag of the type,
so lua can discriminate different kinds of user data.
1995-03-17 17:42:20 -03:00
Waldemar Celes 3c67d2595b error message buffer got a bigger size 1995-03-17 17:27:11 -03:00
Roberto Ierusalimschy 2043a0ca30 adjust checks if stack has enough space 1995-02-10 10:51:29 -02:00
Luiz Henrique de Figueiredo 0761c4c036 included string.h 1995-02-07 14:04:15 -02:00
Roberto Ierusalimschy 2d053126e6 new function for copy strings (strdup is not ANSI) 1995-02-06 17:37:51 -02:00
Roberto Ierusalimschy 3203460c9e better approximation for PI 1995-02-06 17:36:43 -02:00
Roberto Ierusalimschy bb00cd66a7 function "stat" needs "sys/types.h" 1995-02-06 17:36:13 -02:00
Roberto Ierusalimschy 7c342c488e header "stdlib.h" was missing (gcc does not warn that) 1995-02-06 17:35:09 -02:00
Roberto Ierusalimschy b36cd823b1 header "string.h" was missing (gcc does not warn that) 1995-02-06 17:34:03 -02:00
Roberto Ierusalimschy cda444d7f4 type names changed to avoid clashes 1995-02-06 17:32:43 -02:00
Roberto Ierusalimschy dd28b830e9 a null lua_Object is LUA_NOOBJECT, not NULL. 1995-02-02 18:05:37 -02:00
Roberto Ierusalimschy 572ee14b52 use yacc++ instead of yacc. 1995-02-02 17:04:16 -02:00
Roberto Ierusalimschy 6198626138 libs should not use Lua internal functions (like mem.h).
a null lua_Object is LUA_NOOBJECT, not NULL.
1995-02-02 16:54:58 -02:00
Waldemar Celes 8795aab83e new API function lua_pushlocked & lua_checkstack is a macro 1995-01-27 15:19:06 -02:00
Waldemar Celes f83db16cab new API function lua_pushlocked 1995-01-27 15:19:06 -02:00
Waldemar Celes 6e0e9935ec trocar a funcao para garbage colector adaptativo. 1995-01-18 18:15:54 -02:00
Waldemar Celes 97053335fb Trocar 'pushstring' por 'pushliteral' na macro 'getfield'. 1995-01-18 18:15:05 -02:00
Roberto Ierusalimschy f4591397da strdup is done via mem.c to control its memory allocation 1995-01-14 13:40:26 -02:00
Roberto Ierusalimschy 8faf4d1de2 control of garbage collection is done with Longs, as there can be
more than WORD objects to collect.
1995-01-12 12:19:04 -02:00
Roberto Ierusalimschy 53c0a0f43c function 'strfind' now has two optional parameters, to specify where
to start and stop the search.
1995-01-06 18:31:10 -02:00
Roberto Ierusalimschy ad97e9ccbc small bug in fallback for power operator 1995-01-04 16:49:54 -02:00
Waldemar Celes e4c69cf917 correcao de bug na construcao do formato. 1995-01-03 11:14:13 -02:00
Roberto Ierusalimschy 5b8ced84b4 stack is indexed by integers, not Words, to allow bigger stack on 32 bit machines 1994-12-30 15:45:11 -02:00
Roberto Ierusalimschy df3a81ec88 functions that no more return error codes now have return type void 1994-12-28 10:55:47 -02:00
Waldemar Celes b8e76d9b5c 'lua_getsubscript' and 'lua_storesubscript' now run unprotected (to improve efficiency) 1994-12-27 18:53:15 -02:00
Waldemar Celes dc97a07e19 better names for 'y.tab.c' and 'y.tab.h' (now they are moved to 'parser.c' and 'parser.h') 1994-12-27 18:50:38 -02:00
Waldemar Celes 4dce79f7e3 uses 'limits.h' for MAX_WORD and MAX_INT 1994-12-27 18:41:47 -02:00
Waldemar Celes a8220feed2 bytecodes are indexed by integers, not Words, to allow bigger code on 32 bit machines 1994-12-27 18:41:11 -02:00
Waldemar Celes 8bc4b0d741 routines are defined before rules, to allow correct compilation with bison 1994-12-27 18:04:29 -02:00
Roberto Ierusalimschy 96b2b90c50 new file 'types.h' 1994-12-23 18:47:59 -02:00
Roberto Ierusalimschy 89d823f16b implementation dependent types 1994-12-20 19:31:01 -02:00
Roberto Ierusalimschy 8cb8594a3b better control of integer types and their limits 1994-12-20 19:20:36 -02:00
Roberto Ierusalimschy fe8338335d a field with value 'nil' must call the fallback 'index' 1994-12-16 14:08:34 -02:00
Roberto Ierusalimschy 068d1cd1ee new constant LUA_NOOBJECT.
'lua_createtable' does not have parameters.
'lua_copystring' now is a macro
1994-12-16 13:56:45 -02:00
Roberto Ierusalimschy 3365a35243 new constant LUA_NOOBJECT 1994-12-16 13:55:04 -02:00
Roberto Ierusalimschy fad57bfa00 new constant LUA_NOOBJECT.
'lua_error' never returns
1994-12-16 13:53:57 -02:00
Waldemar Celes 891cab8a31 Passar os argv apos '--' para Lua.
Captura-se cada argv com a funcao argv(i), onde i = 1, 2, ...
1994-12-14 17:58:20 -02:00
Roberto Ierusalimschy 2486d677c9 no special treatment for C++ (this should be done in the C++ code) 1994-12-13 13:59:16 -02:00
Roberto Ierusalimschy 84b99d25ad debug message goes to stderr 1994-12-13 13:55:41 -02:00
Roberto Ierusalimschy 5dfd17dd76 new API function 'lua_pushliteral' 1994-12-13 13:54:21 -02:00
Roberto Ierusalimschy ce4fb88b34 opcode PUSHSELF has a parameter that indicates the method to be called 1994-12-06 12:27:18 -02:00
Roberto Ierusalimschy e742d54253 small bug correction 1994-11-30 19:20:37 -02:00
Roberto Ierusalimschy 0f580df73c 'main' returns condition code 1994-11-28 15:12:49 -02:00
Roberto Ierusalimschy 2b301d711b new hash function; hash value for strings are kept with the string 1994-11-28 13:10:51 -02:00
Roberto Ierusalimschy 10bdd83844 new hash function; hash value for strings are kept with the string 1994-11-25 17:27:03 -02:00
Roberto Ierusalimschy fbfa1cbe9b erased function yywrap (nobody used it) 1994-11-25 17:24:57 -02:00
Roberto Ierusalimschy 10c1641b8e new modules 'mem' and 'fallback'.
correction of dependencies
1994-11-23 18:15:04 -02:00
Roberto Ierusalimschy e901e0feae modifications to avoid warnings when compiling yacc code 1994-11-23 12:39:52 -02:00
Roberto Ierusalimschy d490555ec9 garbage collection tag for strings organized in struct TaggedString 1994-11-23 12:32:00 -02:00
Roberto Ierusalimschy ad0ec203f6 small simplification 1994-11-22 14:13:45 -02:00
Roberto Ierusalimschy 577ae944e9 correction of function tonumber 1994-11-22 14:02:53 -02:00
Roberto Ierusalimschy 68d1091b79 no more unary '+' 1994-11-22 13:50:46 -02:00
Roberto Ierusalimschy 52db68a600 debug shows lines where functions were called 1994-11-21 19:41:09 -02:00
Roberto Ierusalimschy bba1ae427f new lua functions 'getglobal' and 'setglobal' 1994-11-21 19:41:09 -02:00
Roberto Ierusalimschy 609392ff2e fallback for "call expression not a function" errors 1994-11-21 16:22:58 -02:00
Roberto Ierusalimschy 96ea2e0fb4 fallback to unary minus is 'arith' with operation code 'unm' 1994-11-21 11:30:15 -02:00
Roberto Ierusalimschy 93ccdd52ef lua_lock receives its parameter via stack.
beginblock and endblock do not have parameters
1994-11-18 17:46:21 -02:00
Roberto Ierusalimschy 333a4f13d0 lua_lock receives its parameter via stack 1994-11-18 17:46:21 -02:00
Roberto Ierusalimschy 73664eb739 function 'lua_createstring' moved from table.c to tree.c 1994-11-18 17:27:38 -02:00
Roberto Ierusalimschy feed56a01c small correction 1994-11-17 19:27:30 -02:00
Roberto Ierusalimschy 1929ddcf49 userdata can have different tags 1994-11-17 19:23:43 -02:00
Roberto Ierusalimschy aa4cd37adf small bug corrected 1994-11-17 19:11:37 -02:00
Roberto Ierusalimschy a84aa11f71 pow operation is defined in mathlib.c 1994-11-17 17:43:34 -02:00
Roberto Ierusalimschy 9bee23fd05 listing did not list POWOP 1994-11-17 17:09:46 -02:00
Roberto Ierusalimschy 3bd0f9e211 uses new memory module (mem.c).
small changes in seting debug line.
if and elseif unified in a outine 'codeIf'
1994-11-17 16:59:06 -02:00
Roberto Ierusalimschy 5406d391cd new API functions startblock and endblock 1994-11-17 14:41:42 -02:00
Roberto Ierusalimschy b234da1cc2 changes in garbage collection control 1994-11-17 11:58:57 -02:00
Roberto Ierusalimschy d6a1699e37 uses a single list to keep allocated strings. 1994-11-16 16:09:11 -02:00
Roberto Ierusalimschy a5862498a1 set first position of a free block to -1, to catch errors 1994-11-16 16:09:11 -02:00
Roberto Ierusalimschy 2b5bc5d1a8 new module for memory allocation 1994-11-16 15:39:16 -02:00
Roberto Ierusalimschy 94686ce585 correction of function 'nextvar' 1994-11-16 14:03:48 -02:00
Roberto Ierusalimschy 86b35cf4f6 unification of symbol tree and constant tree 1994-11-14 19:40:14 -02:00
Roberto Ierusalimschy 3b7a36653b lua_equalObj now is global (and is used by opcode) 1994-11-14 16:41:15 -02:00
Roberto Ierusalimschy e1d91fd0e1 new API function to create tables 1994-11-13 14:17:04 -02:00
Roberto Ierusalimschy 5e60b961de small changes to avoid shadowing 1994-11-13 12:54:18 -02:00
Roberto Ierusalimschy e4645c835d small changes in 'ugly' part. 1994-11-13 12:39:04 -02:00
Roberto Ierusalimschy 0c5ac77c99 small corrections to avoid 'warings' with acc.
do_call was moving results in the wrong order.
1994-11-11 12:00:08 -02:00
Roberto Ierusalimschy b8996eaaba small corrections to avoid 'warings' with acc 1994-11-11 12:00:08 -02:00
Roberto Ierusalimschy ff7f769454 small changes in error recovery 1994-11-10 18:41:37 -02:00
Roberto Ierusalimschy 8a0521fa52 fallback for garbage collection 1994-11-10 15:36:54 -02:00
Roberto Ierusalimschy 9deac27704 fallback list moved from opcode.c to fallback.c 1994-11-10 15:11:52 -02:00
Roberto Ierusalimschy d531ccd082 execution of 'mains' separated from calls 1994-11-09 16:13:29 -02:00
Roberto Ierusalimschy df0cfc1e19 calls lua_reportbug instead of lua_error, in default fallbacks 1994-11-09 16:12:42 -02:00
Roberto Ierusalimschy 5f2d187b73 frees file names when unstacked 1994-11-09 16:11:47 -02:00
Roberto Ierusalimschy 6b387e01b2 lua_parse has a different interface 1994-11-09 16:10:58 -02:00
Roberto Ierusalimschy d0780fa16d lua_call cannot be a macro, because it would push the function
over the parameters
1994-11-09 16:10:11 -02:00
Roberto Ierusalimschy fc0de64c2c lua_debugline is kept in the stack 'funcstack' when debugging. 1994-11-09 16:09:22 -02:00
Roberto Ierusalimschy b8bfa9628d because lua_error does a longjmp, there is no need to a variable
'err'.
lua_parse has a different interface, to allow the free of the main
block even if compilation fails.
small changes in the debug system.
1994-11-09 16:07:38 -02:00
Roberto Ierusalimschy dabe09518f garbage collection for locked objects 1994-11-08 18:07:54 -02:00
Roberto Ierusalimschy 65f28f0824 error function for Lua 1994-11-08 18:06:15 -02:00
Roberto Ierusalimschy 2cf954b8ae lock mechanism 1994-11-08 17:56:39 -02:00
Roberto Ierusalimschy aa7b1fcec4 new API 1994-11-07 16:27:39 -02:00
Roberto Ierusalimschy d95a8b3121 new API: lua_Object now is an integer 1994-11-07 14:34:44 -02:00
Roberto Ierusalimschy 9ffba7a3db first implementation of 'fallbacks' 1994-11-07 13:20:56 -02:00
Roberto Ierusalimschy de4e2305c5 Type renamed to lua_Type 1994-11-07 13:20:56 -02:00
Roberto Ierusalimschy 63d300167e module to implement default fallbacks and lock mechanisms 1994-11-07 13:20:56 -02:00
Roberto Ierusalimschy 62ec3797d5 inheritance is not built-in 1994-11-07 13:19:51 -02:00
Roberto Ierusalimschy 0a5dce5704 new opcodes for '>' and '>=' 1994-11-06 13:35:04 -02:00
Roberto Ierusalimschy 8c22057b2e new global function 'setfallback' 1994-11-04 15:20:00 -02:00
Roberto Ierusalimschy 253655ae4b small corrections. 1994-11-04 08:47:49 -02:00
Roberto Ierusalimschy c635044f2f creation of function do_protectedrun, that executes lua code enclosed
in a setjmp, with error recovery.
Elimination of functions lua_isnil, etc.
1994-11-04 08:47:49 -02:00
Roberto Ierusalimschy 3db06a95a3 Elimination of functions lua_isnil, etc. 1994-11-04 08:47:49 -02:00
Roberto Ierusalimschy 31d58e2f01 more functions from opcode.c
'open_file' and 'open_string' return an error message
lua_type renamed to luaI_type (I for Internal, as this function is not
exported outside lua)
1994-11-03 20:34:29 -02:00
Roberto Ierusalimschy 42ef3f9388 there is no need of predefined constants. 1994-11-03 20:33:40 -02:00
Roberto Ierusalimschy 2651afc455 RESET is generated at codereturn. 1994-11-03 20:32:42 -02:00
Roberto Ierusalimschy 5cb6856ebc because lua_error now does a longjmp, many functions do not need
to check conditions.
1994-11-03 20:20:15 -02:00
Roberto Ierusalimschy 852d9a8597 function 'lua_addfile' returns an error message 1994-11-03 19:48:36 -02:00
Roberto Ierusalimschy 6b18cc9a17 prototype for function 'yylex' 1994-11-03 15:09:20 -02:00
Roberto Ierusalimschy fbf887ec2b new way to call functions, plus several small changes. This is
a temporary version!
1994-11-02 18:30:53 -02:00
Roberto Ierusalimschy ae77864844 tags T_NIL, etc, changed to LUA_T_NIL, etc
some lua_ functions changed form opcode.c to here
1994-11-02 18:29:39 -02:00
Roberto Ierusalimschy 0162decc58 tags T_NIL, etc, changed to LUA_T_NIL, etc 1994-11-02 18:29:09 -02:00
Roberto Ierusalimschy ac68a3abc4 frees filename from file stack 1994-11-02 17:09:23 -02:00
Roberto Ierusalimschy f53460aab9 CREATEARRAY now has an argument, the size of the array to create. 1994-11-01 16:25:20 -02:00
Roberto Ierusalimschy 41e4c5798e small corrections 1994-11-01 15:54:31 -02:00
Roberto Ierusalimschy fb23cd2e26 deletion of 'include mm.h' 1994-10-21 17:00:12 -02:00
Waldemar Celes 2f1de3b1e1 implementacao das funcoes 'date', 'time' e 'beep'.
troca de nome de 'abort' para 'exit'
1994-10-19 15:02:20 -02:00
Roberto Ierusalimschy 1a6536aaad deletion of 'include mm.h' 1994-10-18 16:34:47 -02:00
Waldemar Celes d7cb47fadf new parameter in function 'tree_create'. Maybe we will return to
version 1.1
1994-10-18 15:36:11 -02:00
Waldemar Celes f84abc6799 split to 'ugly.h'. 1994-10-18 15:34:34 -02:00
Waldemar Celes 3386e3c1fb definition of ugly tokens 1994-10-18 12:30:29 -02:00
Roberto Ierusalimschy 25010f8e09 remove of 'printf' for debuging. 1994-10-17 19:45:00 -02:00
Waldemar Celes 424db1db0c power operator (^).
no more contructors (@).
methods can be called on indexed variables.
fixed debuging information.
1994-10-17 17:05:32 -02:00
Waldemar Celes e9049cbfc9 files end with EOF, instead of 0. 1994-10-17 17:04:19 -02:00
Waldemar Celes f8c8159362 adaptative garbage collection. 1994-10-17 17:03:23 -02:00
Waldemar Celes d1c5f42943 new algorithm for reading floats.
files end with EOF, instead of 0.
1994-10-17 17:01:53 -02:00
Waldemar Celes ad07c0f638 new operations POWOP (power) and PUSHMARKMET (for marking method calls).
remove of operation PUSHOBJECT.
1994-10-17 17:00:40 -02:00
Waldemar Celes fca10c6733 Aumentar buffer para saida. 1994-10-13 16:28:54 -03:00
Waldemar Celes 6bc68d4645 Acertar bug para evitar formato "%5.0s", por exemplo. 1994-10-13 14:18:32 -03:00
Waldemar Celes ceaaa0cca8 Correcao do tratamento de erro reportado dentro de uma funcao. 1994-10-11 11:38:17 -03:00
Waldemar Celes 82ceb12b7a Implementacao das funcoes para conversao de angulos rad r deg. 1994-10-11 10:06:47 -03:00
Waldemar Celes 87dded9363 Mudancas na sintaxe para a versao 2.0. Igual relacional passa
a ser ==, tiramos o colchete na criacao de tabelas usando apenas
chaves (podendo fazer inicializacao mista). O caracter  @ so' deve
estar presente quando se tem construtores associados.
/
1994-10-11 10:02:39 -03:00
Waldemar Celes d107d5bfd2 implementacao de busca no campo godparent em substituicao
ao campo parents.
1994-10-11 09:59:49 -03:00
Waldemar Celes d7d7b477bb consertar bug no formato real com zero casas decimais e
implementar a funcao readuntil.
1994-10-07 19:47:05 -03:00
Waldemar Celes dc6d0dcc09 retirar especificador de formato %n da funcao ToReal e
acertar funcao lua_convtonumber.
1994-09-27 18:43:30 -03:00
Waldemar Celes 7cfb5ff41f Mudancas para tornar lex.c um modulo independente dos outros
modulos de Lua
1994-09-26 13:21:52 -03:00
Luiz Henrique de Figueiredo 24c962de43 added support for ugly tokens 1994-09-22 09:44:00 -03:00
Waldemar Celes 98d9509676 sai strtod, entra sscanf. permite conversao de numeros com espacos em volta. 1994-09-20 12:11:11 -03:00
Waldemar Celes 98263e2ef1 acertar bug no formato de string. 1994-09-12 16:24:31 -03:00
Waldemar Celes d2117d66ec default size for arrays is no more 101, as arrays now can grow. 1994-09-08 13:51:49 -03:00
Waldemar Celes 0dcae99d74 new field 'next' in struct 'Hash', to list tables for garbage collection. 1994-09-08 13:51:49 -03:00
Waldemar Celes b826a39919 Implementacao de heranca multipla. 1994-09-08 12:27:10 -03:00
Waldemar Celes 1ea0d09281 Alteracao do buffer de funcao de 32 para 64. 1994-09-05 18:22:43 -03:00
Waldemar Celes 3693f3f062 escapes \' e \" em strings; correcao do escape \\ 1994-09-05 16:14:40 -03:00
Waldemar Celes 0c6b906c8c Compatibilizacao com C++. 1994-08-24 12:29:02 -03:00
Roberto Ierusalimschy 9294a2787f nova funcao 'debug', para auxiliar debugacao de programas lua. 1994-08-17 19:34:20 -03:00
Roberto Ierusalimschy 0ec3a21451 inclui 'lua.h' que contem prototipos das funcoes 'lua_errorfunction' e
'lua_error'.
1994-08-17 19:22:44 -03:00
Waldemar Celes 0624540eef Implementacao da macro 'lua_strcmp' 1994-08-17 14:41:50 -03:00
Waldemar Celes a4eeb099c8 Alteracao na macro 'streq' 1994-08-17 14:41:23 -03:00
Waldemar Celes c364c7286f inclusao de 'lualib.h' para ter prototipos das funcoes de
'iolib_open' e 'strlib_open'.
1994-08-17 12:10:04 -03:00
Waldemar Celes 7c05266050 novas funcoes 'gettable' e 'pushtable'. 1994-08-17 12:05:08 -03:00
Waldemar Celes 592a949272 heranca e nova implementacao do hash. 1994-08-17 12:03:11 -03:00
Waldemar Celes c4b8b1b989 novas funcoes 'gettable' e 'pushtable', nova implementacao do hash e
heranca nas indexacoes.
1994-08-17 12:02:03 -03:00
Waldemar Celes f490b1bff8 Implementacao das funcoes 'log', 'log10' e 'exp'. 1994-08-15 11:13:44 -03:00
Waldemar Celes 3921b43e44 Implementacao das funcoes 'getenv' e 'abort' 1994-08-11 20:11:57 -03:00
Waldemar Celes b28da81cfe Alteracao do hash, trocando tratamento de colisao por lista
pela estrategia de re-hash.
Foi feito uma avaliacao da funcao de hash, e constatado sua
eficiencia com uma media de 4 acessos no hash ate' 70% ocupado.
1994-08-09 08:24:45 -03:00
Waldemar Celes 41fd23287a Implementacao da definicao e chamada de METODOS. 1994-08-05 16:31:09 -03:00
Waldemar Celes be7aa3854b implementacao de dois buffer de 'yytext' para evitar bug
no look ahead do yacc
1994-08-05 16:27:41 -03:00
Waldemar Celes 088cc3f380 evitar, durante consultas, criacao de nos nao encontrados. 1994-08-05 16:25:09 -03:00
Waldemar Celes 5034be6635 Alteracao na funcao 'write" para permitir acrescentar caracteres
de espacamento, tabs, newline, etc. nos formatos.
Corrigiu tambem bug do formato 'F' maiusculo.
1994-08-04 13:23:29 -03:00
Waldemar Celes b1e9b37883 Implementacao de funcoes para tratar Lua function em C e
correcoes de bugs nas tabelas dinamicas.
1994-08-03 11:15:46 -03:00
Roberto Ierusalimschy 467288e5b3 arquivo nao mais utilizado em Lua. 1994-07-21 14:27:43 -03:00
Waldemar Celes e9e9cb03f0 Aumentar precisao do valor de PI. 1994-07-20 19:12:27 -03:00
Waldemar Celes 0eb6ee3fee novos warnings "missing-prototypes" e "ansi". 1994-07-19 19:17:02 -03:00
Waldemar Celes 6c99b8bbdf opcao "clear" para limpar arquivos que podem ser reconstruidos pelo
make (menos os .a e o executavel "lua").
1994-07-19 19:04:51 -03:00
77 changed files with 18360 additions and 4652 deletions
+766
View File
@@ -0,0 +1,766 @@
--[[
** lua.stx / llex.c
Tue Dec 2 10:45:48 EDT 1997
>> BUG: "lastline" was not reset on function entry, so debug information
>> started only in the 2nd line of a function.
=================================================================
--- Version 3.1 alpha
** lua.c
Thu Jan 15 14:34:58 EDT 1998
>> must include "stdlib.h" (for "exit()").
** lbuiltin.c / lobject.h
Thu Jan 15 14:34:58 EDT 1998
>> MAX_WORD may be bigger than MAX_INT
(by lhf)
** llex.c
Mon Jan 19 18:17:18 EDT 1998
>> wrong line number (+1) in error report when file starts with "#..."
** lstrlib.c
Tue Jan 27 15:27:49 EDT 1998
>> formats like "%020d" were considered too big (3 digits); moreover,
>> some sistems limit printf to at most 500 chars, so we can limit sizes
>> to 2 digits (99).
** lapi.c
Tue Jan 27 17:12:36 EDT 1998
>> "lua_getstring" may create a new string, so should check GC
** lstring.c / ltable.c
Wed Jan 28 14:48:12 EDT 1998
>> tables can become full of "empty" slots, and keep growing without limits.
** lstrlib.c
Mon Mar 9 15:26:09 EST 1998
>> gsub('a', '(b?)%1*' ...) loops (because the capture is empty).
** lstrlib.c
Mon May 18 19:20:00 EST 1998
>> arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int.
=================================================================
--- Version 3.1
** liolib.c / lauxlib.c
Mon Sep 7 15:57:02 EST 1998
>> function "luaL_argerror" prints wrong argument number (from a user's point
of view) when functions have upvalues.
** lstrlib.c
Tue Nov 10 17:29:36 EDT 1998
>> gsub/strfind do not check whether captures are properly finished.
(by roberto/tomas)
** lbuiltin.c
Fri Dec 18 11:22:55 EDT 1998
>> "tonumber" goes crazy with negative numbers in other bases (not 10),
because "strtol" returns long, not unsigned long.
(by Visual C++)
** lstrlib.c
Mon Jan 4 10:41:40 EDT 1999
>> "format" does not check size of format item (such as "%00000...00000d").
** lapi.c
Wed Feb 3 14:40:21 EDT 1999
>> getlocal cannot return the local itself, since lua_isstring and
lua_isnumber can modify it.
** lstrlib.c
Thu Feb 4 17:08:50 EDT 1999
>> format "%s" may break limit of "sprintf" on some machines.
(by Marcelo Sales)
** lzio.c
Thu Mar 4 11:49:37 EST 1999
>> file stream cannot call fread after EOF.
(by lhf)
=================================================================
--- Version 3.2 (beta)
** lstrlib.c
Fri Apr 30 11:10:20 EST 1999
>> '$' at end of pattern was matching regular '$', too.
(by anna; since 2.5)
** lbuiltin.c
Fri May 21 17:15:11 EST 1999
>> foreach, foreachi, foreachvar points to function in stack when stack
can be reallocated.
(by tomas; since 3.2 beta)
** lparser.c
Wed Jun 16 10:32:46 EST 1999
>> cannot assign to unlimited variables, because it causes overflow in
the number of returns of a function.
(since 3.1)
=================================================================
--- Version 3.2
** lmathlib.c
Wed Aug 18 11:28:38 EST 1999
>> random(0) and random(x,0) are wrong (0 is read as no argument!).
(by Dave Bollinger; since 3.1)
** lparser.c
Thu Sep 2 10:07:20 EST 1999
>> in the (old) expression << ls->fs->f->consts[checkname(ls)] >>, checkname
could realloc f->consts.
(by Supratik Champati; since 3.2 beta)
** lobject.c / lbuiltin.c
Wed Sep 8 17:41:54 EST 1999
>> tonumber'e1' and tonumber(' ', x), for x!=10, gave 0 instead of nil.
(since 3.1)
** lstrlib.c
Thu Nov 11 14:36:30 EDT 1999
>> `strfind' does not handle \0 in plain search.
(by Jon Kleiser; since 3.1)
** lparser.c
Wed Dec 29 16:05:43 EDT 1999
>> return gives wrong line in debug information
(by lhf; since 3.2 [at least])
** ldo.c
Thu Dec 30 16:39:33 EDT 1999
>> cannot reopen stdin (for binary mode)
(by lhf & roberto; since 3.1)
** lapi.c
Thu Mar 2 09:41:53 EST 2000
>> lua_settable should check stack space (it could call a T.M.)
(by lhf & celes; since 3.2; it was already fixed by fixed stack)
** lparser.c
Mon Apr 3 09:59:06 EST 2000
>> '%' should be in expfollow
(by Edgar Toernig; since 3.1; it was already fixed)
** lbuiltin.c
Mon Apr 3 10:05:05 EST 2000
>> tostring() without arguments gives seg. fault.
(by Edgar Toernig; since 3.0)
=================================================================
--- Version 4.0 alpha
Tested with full test suites (as locked in Mon Apr 24 14:23:11 EST 2000)
in the following platforms:
* Linux - gcc, g++
* AIX - gcc
* Solaris - gcc, cc
* IRIX - cc, cc-purify
* Windows - Visual C++ (.c e .cpp, warning level=4)
** lstrlib.c
Tue May 2 15:27:58 EST 2000
>> `strfind' gets wrong subject length when there is an offset
(by Jon Kleiser; since 4.0a)
** lparser.c
Fri May 12 15:11:12 EST 2000
>> first element in a list constructor is not adjusted to one value
>> (e.g. «a = {gsub('a','a','')}»)
(by Tomas; since 4.0a)
** lparser.c
Wed May 24 14:50:16 EST 2000
>> record-constructor starting with an upvalue name gets an error
>> (e.g. «local a; function f() x = {a=1} end»)
(by Edgar Toernig; since 3.1)
** lparser.c
Tue Aug 29 15:56:05 EST 2000
>> error message for `for' uses `while'
(since 4.0a; already corrected)
** lgc.c
Tue Aug 29 15:57:41 EST 2000
>> gc tag method for nil could call line hook
(by ry; since ?)
=================================================================
--- Version 4.0 Beta
** liolib.c
Fri Sep 22 15:12:37 EST 2000
>> `read("*w")' should return nil at EOF
(by roberto; since 4.0b)
** lvm.c
Mon Sep 25 11:47:48 EST 2000
>> lua_gettable does not get key from stack top
(by Philip Yi; since 4.0b)
** lgc.c
Mon Sep 25 11:50:48 EST 2000
>> GC may crash when checking locked C closures
(by Philip Yi; since 4.0b)
** lapi.c
Wed Sep 27 09:50:19 EST 2000
>> lua_tag should return LUA_NOTAG for non-valid indices
(by Paul Hankin; since 4.0b)
** llex.h / llex.c / lparser.c
Wed Sep 27 13:39:45 EST 2000
>> parser overwrites semantic information when looking ahead
>> (e.g. «a = {print'foo'}»)
(by Edgar Toernig; since 4.0b, deriving from previous bug)
** liolib.c
Thu Oct 26 10:50:46 EDT 2000
>> in function `read_file', realloc() doesn't free the buffer if it can't
>> allocate new memory
(by Mauro Vezzosi; since 4.0b)
=================================================================
--- Version 4.0
** lparser.c
Wed Nov 29 09:51:44 EDT 2000
>> parser does not accept a `;' after a `return'
(by lhf; since 4.0b)
** liolib.c
Fri Dec 22 15:30:42 EDT 2000
>> when `read' fails it must return nil (and not no value)
(by cassino; since at least 3.1)
** lstring.c/lapi.c
Thu Feb 1 11:55:45 EDT 2001
>> lua_pushuserdata(L, NULL) is buggy
(by Edgar Toernig; since 4.0)
** ldo.c
Fri Feb 2 14:06:40 EDT 2001
>> «while 1 dostring[[print('hello\n')]] end» never reclaims memory
(by Andrew Paton; since 4.0b)
** lbaselib.c
Tue Feb 6 11:57:13 EDT 2001
>> ESC (which starts precompiled code) in C is \33, not \27
(by Edgar Toernig and lhf; since 4.0b)
** lparser.c
Tue Jul 10 16:59:18 EST 2001
>> error message for `%a' gave wrong line number
(by Leonardo Constantino; since 4.0)
** lbaselib.c
Fri Dec 21 15:21:05 EDT 2001
>> seg. fault when rawget/rawset get extra arguments
(by Eric Mauger; since 4.0b)
** lvm.c
Wed Jun 19 13:28:20 EST 2002
>> line hook gets wrong `ar'
(by Daniel C. Sinclair; since 4.0.b)
** ldo.c
Wed Jun 19 13:31:49 EST 2002
>> `protectedparser' may run GC, and then collect `filename'
>> (in function `parse_file')
(by Alex Bilyk; since 4.0)
=================================================================
--- Version 5.0 alpha
** lgc.c
Fri Aug 30 13:49:14 EST 2002
>> GC metamethod stored in a weak metatable being collected together with
>> userdata may not be cleared properly
(by Roberto; since 5.0a)
** lapi.c
Thu Nov 21 11:00:00 EST 2002
>> ULONG_MAX>>10 may not fit into an int
(by Jeff Petkau; since 4.0)
** lparser.c
Fri Dec 6 17:06:40 UTC 2002
>> scope of generic for variables is not sound
(by Gavin Wraith; since 5.0a)
=================================================================
--- Version 5.0 beta
** lbaselib.c
Fri Dec 20 09:53:19 UTC 2002
>> `resume' was checking the wrong value for stack overflow
(by Maik Zimmermann; since 5.0b)
** ldo.c
Thu Jan 23 11:29:06 UTC 2003
>> error during garbage collection in luaD_protectedparser is not being
>> protected
(by Benoit Germain; since 5.0a)
** ldo.c (and others)
Fri Feb 28 14:20:33 EST 2003
>> GC metamethod calls could mess C/Lua stack syncronization
(by Roberto; since 5.0b)
** lzio.h/zlio.c
Thu Mar 20 11:40:12 EST 2003
>> zio mixes a 255 as first char in a buffer with EOZ
(by lhf; since 5.0a)
--]]
-----------------------------------------------------------------
-- Lua 5.0 (final)
Bug{
what = [[lua_closethread exists only in the manual]],
report = [[by Nguyen Binh, 28/04/2003]],
patch = [[no patch; the manual is wrong]],
}
Bug{
what = [[attempt to resume a running coroutine crashes Lua]],
example = [[
function co_func (current_co)
coroutine.resume(co)
end
co = coroutine.create(co_func)
coroutine.resume(co)
coroutine.resume(co) --> seg. fault
]],
report = [[by Alex Bilyk, 09/05/2003]],
patch = [[
* ldo.c:
325,326c325
< if (nargs >= L->top - L->base)
< luaG_runerror(L, "cannot resume dead coroutine");
---
> lua_assert(nargs < L->top - L->base);
329c328,329
< else if (ci->state & CI_YIELD) { /* inside a yield? */
---
> else { /* inside a yield */
> lua_assert(ci->state & CI_YIELD);
344,345d343
< else
< luaG_runerror(L, "cannot resume non-suspended coroutine");
351a350,358
> static int resume_error (lua_State *L, const char *msg) {
> L->top = L->ci->base;
> setsvalue2s(L->top, luaS_new(L, msg));
> incr_top(L);
> lua_unlock(L);
> return LUA_ERRRUN;
> }
>
>
355a363,368
> if (L->ci == L->base_ci) {
> if (nargs >= L->top - L->base)
> return resume_error(L, "cannot resume dead coroutine");
> }
> else if (!(L->ci->state & CI_YIELD)) /* not inside a yield? */
> return resume_error(L, "cannot resume non-suspended coroutine");
]],
}
Bug{
what = [[file:close cannot be called without a file. (results in seg fault)]],
example = [[
> io.stdin.close() -- correct call shold be io.stdin:close()
]],
report = [[by Tuomo Valkonen, 27/05/2003]],
patch = [[
* liolib.c:
161c161
< if (lua_isnone(L, 1)) {
---
> if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) {
]], --}}
}
Bug{
what = [[C functions also may have stacks larger than current top]],
example = [[
Must recompile lua with a change in lua.c and with lua_assert defined:
* lua.c:
381a382
> lua_checkstack(l, 1000);
]],
report = [[Alex Bilyk, 09/06/2003]],
patch = [[
* lgc.c:
247c247
< if (!(ci->state & CI_C) && lim < ci->top)
---
> if (lim < ci->top)
]],
}
Bug{
what = [[`pc' address is invalidated when a coroutine is suspended]],
example = [[
function g(x)
coroutine.yield(x)
end
function f (i)
debug.sethook(print, "l")
for j=1,1000 do
g(i+j)
end
end
co = coroutine.wrap(f)
co(10)
pcall(co)
pcall(co)
]],
report = [[Nick Trout, 07/07/2003]],
patch = [[
* lvm.c:
402,403c402,403
< L->ci->u.l.pc = &pc;
< if (L->hookmask & LUA_MASKCALL)
---
> if (L->hookmask & LUA_MASKCALL) {
> L->ci->u.l.pc = &pc;
404a405
> }
405a407
> L->ci->u.l.pc = &pc;
676,678c678
< lua_assert(ci->u.l.pc == &pc &&
< ttisfunction(ci->base - 1) &&
< (ci->state & CI_SAVEDPC));
---
> lua_assert(ttisfunction(ci->base - 1) && (ci->state & CI_SAVEDPC));
]]
}
Bug{
what = [[userdata to be collected still counts into new GC threshold,
increasing memory consumption]],
report = [[Roberto, 25/07/2003]],
example = [[
a = newproxy(true)
getmetatable(a).__gc = function () end
for i=1,10000000 do
newproxy(a)
if math.mod(i, 10000) == 0 then print(gcinfo()) end
end
]],
patch = [[
* lgc.h:
18c18
< void luaC_separateudata (lua_State *L);
---
> size_t luaC_separateudata (lua_State *L);
* lgc.c:
113c113,114
< void luaC_separateudata (lua_State *L) {
---
> size_t luaC_separateudata (lua_State *L) {
> size_t deadmem = 0;
127a129
> deadmem += sizeudata(gcotou(curr)->uv.len);
136a139
> return deadmem;
390c393
< static void checkSizes (lua_State *L) {
---
> static void checkSizes (lua_State *L, size_t deadmem) {
400c403
< G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
---
> G(L)->GCthreshold = 2*G(L)->nblocks - deadmem; /* new threshold */
454c457,458
< static void mark (lua_State *L) {
---
> static size_t mark (lua_State *L) {
> size_t deadmem;
467c471
< luaC_separateudata(L); /* separate userdata to be preserved */
---
> deadmem = luaC_separateudata(L); /* separate userdata to be preserved */
475a480
> return deadmem;
480c485
< mark(L);
---
> size_t deadmem = mark(L);
482c487
< checkSizes(L);
---
> checkSizes(L, deadmem);
]]
}
Bug{
what=[[IBM AS400 (OS400) has sizeof(void *)==16, and a `%p' may generate
up to 60 characters in a `printf'. That causes a buffer overflow in
`tostring'.]],
report = [[David Burgess, 25/08/2003]],
example = [[print{}; (in an AS400 machine)]],
patch = [[
* liolib.c:
178c178
< char buff[32];
---
> char buff[128];
* lbaselib.c:
327c327
< char buff[64];
---
> char buff[128];
]]
}
Bug{
what = [[syntax `local function' does not increment stack size]],
report = [[Rici Lake, 26/09/2003]],
example = [[
-- must run this with precompiled code
local a,b,c
local function d () end
]],
patch = [[
* lparser.c:
1143a1144
> FuncState *fs = ls->fs;
1145c1146,1147
< init_exp(&v, VLOCAL, ls->fs->freereg++);
---
> init_exp(&v, VLOCAL, fs->freereg);
> luaK_reserveregs(fs, 1);
1148c1150,1152
< luaK_storevar(ls->fs, &v, &b);
---
> luaK_storevar(fs, &v, &b);
> /* debug information will only see the variable after this point! */
> getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
]],
}
Bug{
what = [[count hook may be called without being set]],
report = [[Andreas Stenius, 06/10/2003]],
example = [[
set your hooks with
lua_sethook(L, my_hook, LUA_MASKLINE | LUA_MASKRET, 1);
(It is weird to use a count > 0 without setting the count hook,
but it is not wrong.)
]],
patch = [[
* lvm.c:
69c69
< if (mask > LUA_MASKLINE) { /* instruction-hook set? */
---
> if (mask & LUA_MASKCOUNT) { /* instruction-hook set? */
]],
}
Bug{
what = [[`dofile' eats one return value when called without arguments]],
report = [[Frederico Abraham, 15/01/2004]],
example = [[
a,b = dofile() --< here you enter `return 1,2,3 <eof>'
print(a,b) --> 2 3 (should be 1 and 2)
]],
patch = [[
* lbaselib.c:
313a314
> int n = lua_gettop(L);
317c318
< return lua_gettop(L) - 1;
---
> return lua_gettop(L) - n;
]],
}
-----------------------------------------------------------------
-- Lua 5.0.2
Bug{
what = [[string concatenation may cause arithmetic overflow, leading
to a buffer overflow]],
report = [[Rici Lake, 20/05/2004]],
example = [[
longs = string.rep("\0", 2^25)
function catter(i)
return assert(loadstring(
string.format("return function(a) return a%s end",
string.rep("..a", i-1))))()
end
rep129 = catter(129)
rep129(longs)
]],
patch = [[
* lvm.c:
@@ -321,15 +321,15 @@
luaG_concaterror(L, top-2, top-1);
} else if (tsvalue(top-1)->tsv.len > 0) { /* if len=0, do nothing */
/* at least two string values; get as many as possible */
- lu_mem tl = cast(lu_mem, tsvalue(top-1)->tsv.len) +
- cast(lu_mem, tsvalue(top-2)->tsv.len);
+ size_t tl = tsvalue(top-1)->tsv.len;
char *buffer;
int i;
- while (n < total && tostring(L, top-n-1)) { /* collect total length */
- tl += tsvalue(top-n-1)->tsv.len;
- n++;
+ /* collect total length */
+ for (n = 1; n < total && tostring(L, top-n-1); n++) {
+ size_t l = tsvalue(top-n-1)->tsv.len;
+ if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
+ tl += l;
}
- if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow");
buffer = luaZ_openspace(L, &G(L)->buff, tl);
tl = 0;
for (i=n; i>0; i--) { /* concat all strings */
]]
}
Bug{
what = [[lua_getupvalue and setupvalue do not check for index too small]],
report = [[Mike Pall, ?/2004]],
example = [[debug.getupvalue(function() end, 0)]],
patch = [[
* lapi.c
941c941
< if (n > f->c.nupvalues) return NULL;
---
> if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
947c947
< if (n > p->sizeupvalues) return NULL;
---
> if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
]]
}
Bug{
what = [[values holded in open upvalues of suspended threads may be
incorrectly collected]],
report = [[Spencer Schumann, 31/12/2004]],
example = [[
local thread_id = 0
local threads = {}
function fn(thread)
thread_id = thread_id + 1
threads[thread_id] = function()
thread = nil
end
coroutine.yield()
end
while true do
local thread = coroutine.create(fn)
coroutine.resume(thread, thread)
end
]],
patch = [[
* lgc.c:
221,224c221,222
< if (!u->marked) {
< markobject(st, &u->value);
< u->marked = 1;
< }
---
> markobject(st, u->v);
> u->marked = 1;
]],
}
Bug{
what = [[rawset/rawget do not ignore extra arguments]],
report = [[Romulo Bahiense, 11/03/2005]],
example = [[
a = {}
rawset(a, 1, 2, 3)
print(a[1], a[2]) -- should be 2 and nil
]],
patch = [[
* lbaselib.c:
175a176
> lua_settop(L, 2);
183a185
> lua_settop(L, 3);
]],
}
-3
View File
@@ -1,3 +0,0 @@
1d
x
-345
View File
@@ -1,345 +0,0 @@
/*
** hash.c
** hash manager for lua
** Luiz Henrique de Figueiredo - 17 Aug 90
*/
char *rcs_hash="$Id: hash.c,v 2.1 1994/04/20 22:07:57 celes Exp celes $";
#include <string.h>
#include <stdlib.h>
#include "mm.h"
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "lua.h"
#define streq(s1,s2) (strcmp(s1,s2)==0)
#define strneq(s1,s2) (strcmp(s1,s2)!=0)
#define new(s) ((s *)malloc(sizeof(s)))
#define newvector(n,s) ((s *)calloc(n,sizeof(s)))
#define nhash(t) ((t)->nhash)
#define nodelist(t) ((t)->list)
#define list(t,i) ((t)->list[i])
#define markarray(t) ((t)->mark)
#define ref_tag(n) (tag(&(n)->ref))
#define ref_nvalue(n) (nvalue(&(n)->ref))
#define ref_svalue(n) (svalue(&(n)->ref))
typedef struct ArrayList
{
Hash *array;
struct ArrayList *next;
} ArrayList;
static ArrayList *listhead = NULL;
static int head (Hash *t, Object *ref) /* hash function */
{
if (tag(ref) == T_NUMBER) return (((int)nvalue(ref))%nhash(t));
else if (tag(ref) == T_STRING)
{
int h;
char *name = svalue(ref);
for (h=0; *name!=0; name++) /* interpret name as binary number */
{
h <<= 8;
h += (unsigned char) *name; /* avoid sign extension */
h %= nhash(t); /* make it a valid index */
}
return h;
}
else
{
lua_reportbug ("unexpected type to index table");
return -1;
}
}
static Node *present(Hash *t, Object *ref, int h)
{
Node *n=NULL, *p;
if (tag(ref) == T_NUMBER)
{
for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)
if (ref_tag(n) == T_NUMBER && nvalue(ref) == ref_nvalue(n)) break;
}
else if (tag(ref) == T_STRING)
{
for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)
if (ref_tag(n) == T_STRING && streq(svalue(ref),ref_svalue(n))) break;
}
if (n==NULL) /* name not present */
return NULL;
#if 0
if (p!=NULL) /* name present but not first */
{
p->next=n->next; /* move-to-front self-organization */
n->next=list(t,h);
list(t,h)=n;
}
#endif
return n;
}
static void freelist (Node *n)
{
while (n)
{
Node *next = n->next;
free (n);
n = next;
}
}
/*
** Create a new hash. Return the hash pointer or NULL on error.
*/
static Hash *hashcreate (unsigned int nhash)
{
Hash *t = new (Hash);
if (t == NULL)
{
lua_error ("not enough memory");
return NULL;
}
nhash(t) = nhash;
markarray(t) = 0;
nodelist(t) = newvector (nhash, Node*);
if (nodelist(t) == NULL)
{
lua_error ("not enough memory");
return NULL;
}
return t;
}
/*
** Delete a hash
*/
static void hashdelete (Hash *h)
{
int i;
for (i=0; i<nhash(h); i++)
freelist (list(h,i));
free (nodelist(h));
free(h);
}
/*
** Mark a hash and check its elements
*/
void lua_hashmark (Hash *h)
{
if (markarray(h) == 0)
{
int i;
markarray(h) = 1;
for (i=0; i<nhash(h); i++)
{
Node *n;
for (n = list(h,i); n != NULL; n = n->next)
{
lua_markobject(&n->ref);
lua_markobject(&n->val);
}
}
}
}
/*
** Garbage collection to arrays
** Delete all unmarked arrays.
*/
void lua_hashcollector (void)
{
ArrayList *curr = listhead, *prev = NULL;
while (curr != NULL)
{
ArrayList *next = curr->next;
if (markarray(curr->array) != 1)
{
if (prev == NULL) listhead = next;
else prev->next = next;
hashdelete(curr->array);
free(curr);
}
else
{
markarray(curr->array) = 0;
prev = curr;
}
curr = next;
}
}
/*
** Create a new array
** This function insert the new array at array list. It also
** execute garbage collection if the number of array created
** exceed a pre-defined range.
*/
Hash *lua_createarray (int nhash)
{
ArrayList *new = new(ArrayList);
if (new == NULL)
{
lua_error ("not enough memory");
return NULL;
}
new->array = hashcreate(nhash);
if (new->array == NULL)
{
lua_error ("not enough memory");
return NULL;
}
if (lua_nentity == lua_block)
lua_pack();
lua_nentity++;
new->next = listhead;
listhead = new;
return new->array;
}
/*
** If the hash node is present, return its pointer, otherwise create a new
** node for the given reference and also return its pointer.
** On error, return NULL.
*/
Object *lua_hashdefine (Hash *t, Object *ref)
{
int h;
Node *n;
h = head (t, ref);
if (h < 0) return NULL;
n = present(t, ref, h);
if (n == NULL)
{
n = new(Node);
if (n == NULL)
{
lua_error ("not enough memory");
return NULL;
}
n->ref = *ref;
tag(&n->val) = T_NIL;
n->next = list(t,h); /* link node to head of list */
list(t,h) = n;
}
return (&n->val);
}
/*
** Internal function to manipulate arrays.
** Given an array object and a reference value, return the next element
** in the hash.
** This function pushs the element value and its reference to the stack.
*/
static void firstnode (Hash *a, int h)
{
if (h < nhash(a))
{
int i;
for (i=h; i<nhash(a); i++)
{
if (list(a,i) != NULL)
{
if (tag(&list(a,i)->val) != T_NIL)
{
lua_pushobject (&list(a,i)->ref);
lua_pushobject (&list(a,i)->val);
return;
}
else
{
Node *next = list(a,i)->next;
while (next != NULL && tag(&next->val) == T_NIL) next = next->next;
if (next != NULL)
{
lua_pushobject (&next->ref);
lua_pushobject (&next->val);
return;
}
}
}
}
}
lua_pushnil();
lua_pushnil();
}
void lua_next (void)
{
Hash *a;
Object *o = lua_getparam (1);
Object *r = lua_getparam (2);
if (o == NULL || r == NULL)
{ lua_error ("too few arguments to function `next'"); return; }
if (lua_getparam (3) != NULL)
{ lua_error ("too many arguments to function `next'"); return; }
if (tag(o) != T_ARRAY)
{ lua_error ("first argument of function `next' is not a table"); return; }
a = avalue(o);
if (tag(r) == T_NIL)
{
firstnode (a, 0);
return;
}
else
{
int h = head (a, r);
if (h >= 0)
{
Node *n = list(a,h);
while (n)
{
if (memcmp(&n->ref,r,sizeof(Object)) == 0)
{
if (n->next == NULL)
{
firstnode (a, h+1);
return;
}
else if (tag(&n->next->val) != T_NIL)
{
lua_pushobject (&n->next->ref);
lua_pushobject (&n->next->val);
return;
}
else
{
Node *next = n->next->next;
while (next != NULL && tag(&next->val) == T_NIL) next = next->next;
if (next == NULL)
{
firstnode (a, h+1);
return;
}
else
{
lua_pushobject (&next->ref);
lua_pushobject (&next->val);
}
return;
}
}
n = n->next;
}
if (n == NULL)
lua_error ("error in function 'next': reference not found");
}
}
}
-32
View File
@@ -1,32 +0,0 @@
/*
** hash.h
** hash manager for lua
** Luiz Henrique de Figueiredo - 17 Aug 90
** $Id: hash.h,v 1.1 1993/12/17 18:41:19 celes Exp celes $
*/
#ifndef hash_h
#define hash_h
typedef struct node
{
Object ref;
Object val;
struct node *next;
} Node;
typedef struct Hash
{
char mark;
unsigned int nhash;
Node **list;
} Hash;
Hash *lua_createarray (int nhash);
void lua_hashmark (Hash *h);
void lua_hashcollector (void);
Object *lua_hashdefine (Hash *t, Object *ref);
void lua_next (void);
#endif
-178
View File
@@ -1,178 +0,0 @@
/*
** inout.c
** Provide function to realise the input/output function and debugger
** facilities.
*/
char *rcs_inout="$Id: inout.c,v 1.2 1993/12/22 21:15:16 roberto Exp celes $";
#include <stdio.h>
#include <string.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "tree.h"
/* Exported variables */
int lua_linenumber;
int lua_debug;
int lua_debugline;
/* Internal variables */
#ifndef MAXFUNCSTACK
#define MAXFUNCSTACK 32
#endif
static struct { int file; int function; } funcstack[MAXFUNCSTACK];
static int nfuncstack=0;
static FILE *fp;
static char *st;
static void (*usererror) (char *s);
/*
** Function to set user function to handle errors.
*/
void lua_errorfunction (void (*fn) (char *s))
{
usererror = fn;
}
/*
** Function to get the next character from the input file
*/
static int fileinput (void)
{
int c = fgetc (fp);
return (c == EOF ? 0 : c);
}
/*
** Function to get the next character from the input string
*/
static int stringinput (void)
{
st++;
return (*(st-1));
}
/*
** Function to open a file to be input unit.
** Return 0 on success or 1 on error.
*/
int lua_openfile (char *fn)
{
lua_linenumber = 1;
lua_setinput (fileinput);
fp = fopen (fn, "r");
if (fp == NULL) return 1;
if (lua_addfile (fn)) return 1;
return 0;
}
/*
** Function to close an opened file
*/
void lua_closefile (void)
{
if (fp != NULL)
{
lua_delfile();
fclose (fp);
fp = NULL;
}
}
/*
** Function to open a string to be input unit
*/
int lua_openstring (char *s)
{
lua_linenumber = 1;
lua_setinput (stringinput);
st = s;
{
char sn[64];
sprintf (sn, "String: %10.10s...", s);
if (lua_addfile (sn)) return 1;
}
return 0;
}
/*
** Function to close an opened string
*/
void lua_closestring (void)
{
lua_delfile();
}
/*
** Call user function to handle error messages, if registred. Or report error
** using standard function (fprintf).
*/
void lua_error (char *s)
{
if (usererror != NULL) usererror (s);
else fprintf (stderr, "lua: %s\n", s);
}
/*
** Called to execute SETFUNCTION opcode, this function pushs a function into
** function stack. Return 0 on success or 1 on error.
*/
int lua_pushfunction (int file, int function)
{
if (nfuncstack >= MAXFUNCSTACK-1)
{
lua_error ("function stack overflow");
return 1;
}
funcstack[nfuncstack].file = file;
funcstack[nfuncstack].function = function;
nfuncstack++;
return 0;
}
/*
** Called to execute RESET opcode, this function pops a function from
** function stack.
*/
void lua_popfunction (void)
{
nfuncstack--;
}
/*
** Report bug building a message and sending it to lua_error function.
*/
void lua_reportbug (char *s)
{
char msg[1024];
strcpy (msg, s);
if (lua_debugline != 0)
{
int i;
if (nfuncstack > 0)
{
sprintf (strchr(msg,0),
"\n\tin statement begining at line %d in function \"%s\" of file \"%s\"",
lua_debugline, lua_varname(funcstack[nfuncstack-1].function),
lua_file[funcstack[nfuncstack-1].file]);
sprintf (strchr(msg,0), "\n\tactive stack\n");
for (i=nfuncstack-1; i>=0; i--)
sprintf (strchr(msg,0), "\t-> function \"%s\" of file \"%s\"\n",
lua_varname(funcstack[i].function),
lua_file[funcstack[i].file]);
}
else
{
sprintf (strchr(msg,0),
"\n\tin statement begining at line %d of file \"%s\"",
lua_debugline, lua_filename());
}
}
lua_error (msg);
}
-21
View File
@@ -1,21 +0,0 @@
/*
** $Id: $
*/
#ifndef inout_h
#define inout_h
extern int lua_linenumber;
extern int lua_debug;
extern int lua_debugline;
int lua_openfile (char *fn);
void lua_closefile (void);
int lua_openstring (char *s);
void lua_closestring (void);
int lua_pushfunction (int file, int function);
void lua_popfunction (void);
void lua_reportbug (char *s);
#endif
-479
View File
@@ -1,479 +0,0 @@
/*
** iolib.c
** Input/output library to LUA
*/
char *rcs_iolib="$Id: iolib.c,v 1.3 1994/03/28 15:14:02 celes Exp celes $";
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/stat.h>
#ifdef __GNUC__
#include <floatingpoint.h>
#endif
#include "mm.h"
#include "lua.h"
static FILE *in=stdin, *out=stdout;
/*
** Open a file to read.
** LUA interface:
** status = readfrom (filename)
** where:
** status = 1 -> success
** status = 0 -> error
*/
static void io_readfrom (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart input */
{
if (in != stdin)
{
fclose (in);
in = stdin;
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'readfrom`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"r");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (in != stdin) fclose (in);
in = fp;
lua_pushnumber (1);
}
}
}
}
/*
** Open a file to write.
** LUA interface:
** status = writeto (filename)
** where:
** status = 1 -> success
** status = 0 -> error
*/
static void io_writeto (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart output */
{
if (out != stdout)
{
fclose (out);
out = stdout;
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'writeto`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"w");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (out != stdout) fclose (out);
out = fp;
lua_pushnumber (1);
}
}
}
}
/*
** Open a file to write appended.
** LUA interface:
** status = appendto (filename)
** where:
** status = 2 -> success (already exist)
** status = 1 -> success (new file)
** status = 0 -> error
*/
static void io_appendto (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart output */
{
if (out != stdout)
{
fclose (out);
out = stdout;
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'appendto`");
lua_pushnumber (0);
}
else
{
int r;
FILE *fp;
struct stat st;
if (stat(lua_getstring(o), &st) == -1) r = 1;
else r = 2;
fp = fopen (lua_getstring(o),"a");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (out != stdout) fclose (out);
out = fp;
lua_pushnumber (r);
}
}
}
}
/*
** Read a variable. On error put nil on stack.
** LUA interface:
** variable = read ([format])
**
** O formato pode ter um dos seguintes especificadores:
**
** s ou S -> para string
** f ou F, g ou G, e ou E -> para reais
** i ou I -> para inteiros
**
** Estes especificadores podem vir seguidos de numero que representa
** o numero de campos a serem lidos.
*/
static void io_read (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring(o)) /* free format */
{
int c;
char s[256];
while (isspace(c=fgetc(in)))
;
if (c == '\"')
{
int c, n=0;
while((c = fgetc(in)) != '\"')
{
if (c == EOF)
{
lua_pushnil ();
return;
}
s[n++] = c;
}
s[n] = 0;
}
else if (c == '\'')
{
int c, n=0;
while((c = fgetc(in)) != '\'')
{
if (c == EOF)
{
lua_pushnil ();
return;
}
s[n++] = c;
}
s[n] = 0;
}
else
{
char *ptr;
double d;
ungetc (c, in);
if (fscanf (in, "%s", s) != 1)
{
lua_pushnil ();
return;
}
d = strtod (s, &ptr);
if (!(*ptr))
{
lua_pushnumber (d);
return;
}
}
lua_pushstring (s);
return;
}
else /* formatted */
{
char *e = lua_getstring(o);
char t;
int m=0;
while (isspace(*e)) e++;
t = *e++;
while (isdigit(*e))
m = m*10 + (*e++ - '0');
if (m > 0)
{
char f[80];
char s[256];
sprintf (f, "%%%ds", m);
if (fgets (s, m, in) == NULL)
{
lua_pushnil();
return;
}
else
{
if (s[strlen(s)-1] == '\n')
s[strlen(s)-1] = 0;
}
switch (tolower(t))
{
case 'i':
{
long int l;
sscanf (s, "%ld", &l);
lua_pushnumber(l);
}
break;
case 'f': case 'g': case 'e':
{
float f;
sscanf (s, "%f", &f);
lua_pushnumber(f);
}
break;
default:
lua_pushstring(s);
break;
}
}
else
{
switch (tolower(t))
{
case 'i':
{
long int l;
if (fscanf (in, "%ld", &l) == EOF)
lua_pushnil();
else lua_pushnumber(l);
}
break;
case 'f': case 'g': case 'e':
{
float f;
if (fscanf (in, "%f", &f) == EOF)
lua_pushnil();
else lua_pushnumber(f);
}
break;
default:
{
char s[256];
if (fscanf (in, "%s", s) == EOF)
lua_pushnil();
else lua_pushstring(s);
}
break;
}
}
}
}
/*
** Write a variable. On error put 0 on stack, otherwise put 1.
** LUA interface:
** status = write (variable [,format])
**
** O formato pode ter um dos seguintes especificadores:
**
** s ou S -> para string
** f ou F, g ou G, e ou E -> para reais
** i ou I -> para inteiros
**
** Estes especificadores podem vir seguidos de:
**
** [?][m][.n]
**
** onde:
** ? -> indica justificacao
** < = esquerda
** | = centro
** > = direita (default)
** m -> numero maximo de campos (se exceder estoura)
** n -> indica precisao para
** reais -> numero de casas decimais
** inteiros -> numero minimo de digitos
** string -> nao se aplica
*/
static char *buildformat (char *e, lua_Object o)
{
static char buffer[512];
static char f[80];
char *string = &buffer[255];
char t, j='r';
int m=0, n=0, l;
while (isspace(*e)) e++;
t = *e++;
if (*e == '<' || *e == '|' || *e == '>') j = *e++;
while (isdigit(*e))
m = m*10 + (*e++ - '0');
e++; /* skip point */
while (isdigit(*e))
n = n*10 + (*e++ - '0');
sprintf(f,"%%");
if (j == '<' || j == '|') sprintf(strchr(f,0),"-");
if (m != 0) sprintf(strchr(f,0),"%d", m);
if (n != 0) sprintf(strchr(f,0),".%d", n);
sprintf(strchr(f,0), "%c", t);
switch (tolower(t))
{
case 'i': t = 'i';
sprintf (string, f, (long int)lua_getnumber(o));
break;
case 'f': case 'g': case 'e': t = 'f';
sprintf (string, f, (float)lua_getnumber(o));
break;
case 's': t = 's';
sprintf (string, f, lua_getstring(o));
break;
default: return "";
}
l = strlen(string);
if (m!=0 && l>m)
{
int i;
for (i=0; i<m; i++)
string[i] = '*';
string[i] = 0;
}
else if (m!=0 && j=='|')
{
int i=l-1;
while (isspace(string[i])) i--;
string -= (m-i) / 2;
i=0;
while (string[i]==0) string[i++] = ' ';
string[l] = 0;
}
return string;
}
static void io_write (void)
{
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (o1 == NULL) /* new line */
{
fprintf (out, "\n");
lua_pushnumber(1);
}
else if (o2 == NULL) /* free format */
{
int status=0;
if (lua_isnumber(o1))
status = fprintf (out, "%g", lua_getnumber(o1));
else if (lua_isstring(o1))
status = fprintf (out, "%s", lua_getstring(o1));
lua_pushnumber(status);
}
else /* formated */
{
if (!lua_isstring(o2))
{
lua_error ("incorrect format to function `write'");
lua_pushnumber(0);
return;
}
lua_pushnumber(fprintf (out, "%s", buildformat(lua_getstring(o2),o1)));
}
}
/*
** Execute a executable program using "system".
** Return the result of execution.
*/
void io_execute (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
int res = system(lua_getstring(o));
lua_pushnumber (res);
}
return;
}
/*
** Remove a file.
** On error put 0 on stack, otherwise put 1.
*/
void io_remove (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
if (remove(lua_getstring(o)) == 0)
lua_pushnumber (1);
else
lua_pushnumber (0);
}
return;
}
/*
** Open io library
*/
void iolib_open (void)
{
lua_register ("readfrom", io_readfrom);
lua_register ("writeto", io_writeto);
lua_register ("appendto", io_appendto);
lua_register ("read", io_read);
lua_register ("write", io_write);
lua_register ("execute", io_execute);
lua_register ("remove", io_remove);
}
+1062
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
/*
** $Id: lapi.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
#ifndef lapi_h
#define lapi_h
#include "lobject.h"
LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
#endif
+630
View File
@@ -0,0 +1,630 @@
/*
** $Id: lauxlib.c,v 1.151 2005/08/26 17:36:32 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* This file uses only the official API of Lua.
** Any function declared here could be written as an application function.
*/
#define lauxlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#define FREELIST_REF 0 /* free list of references */
/* convert a stack index to positive */
#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
lua_gettop(L) + (i) + 1)
/*
** {======================================================
** Error-report functions
** =======================================================
*/
LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
lua_Debug ar;
if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
lua_getinfo(L, "n", &ar);
if (strcmp(ar.namewhat, "method") == 0) {
narg--; /* do not count `self' */
if (narg == 0) /* error is in the self argument itself? */
return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
ar.name, extramsg);
}
if (ar.name == NULL)
ar.name = "?";
return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
narg, ar.name, extramsg);
}
LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
const char *msg = lua_pushfstring(L, "%s expected, got %s",
tname, luaL_typename(L, narg));
return luaL_argerror(L, narg, msg);
}
static void tag_error (lua_State *L, int narg, int tag) {
luaL_typerror(L, narg, lua_typename(L, tag));
}
LUALIB_API void luaL_where (lua_State *L, int level) {
lua_Debug ar;
if (lua_getstack(L, level, &ar)) { /* check function at level */
lua_getinfo(L, "Sl", &ar); /* get info about it */
if (ar.currentline > 0) { /* is there info? */
lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
return;
}
}
lua_pushliteral(L, ""); /* else, no information available... */
}
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
luaL_where(L, 1);
lua_pushvfstring(L, fmt, argp);
va_end(argp);
lua_concat(L, 2);
return lua_error(L);
}
/* }====================================================== */
LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
const char *const lst[]) {
const char *name = (def) ? luaL_optstring(L, narg, def) :
luaL_checkstring(L, narg);
int i;
for (i=0; lst[i]; i++)
if (strcmp(lst[i], name) == 0)
return i;
return luaL_argerror(L, narg,
lua_pushfstring(L, "invalid option " LUA_QS, name));
}
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua_pop(L, 1);
lua_newtable(L); /* create metatable */
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
return 1;
}
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2))
luaL_typerror(L, ud, tname);
lua_pop(L, 2); /* remove both metatables */
return p;
}
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
if (!lua_checkstack(L, space))
luaL_error(L, "stack overflow (%s)", mes);
}
LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
if (lua_type(L, narg) != t)
tag_error(L, narg, t);
}
LUALIB_API void luaL_checkany (lua_State *L, int narg) {
if (lua_type(L, narg) == LUA_TNONE)
luaL_argerror(L, narg, "value expected");
}
LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
const char *s = lua_tolstring(L, narg, len);
if (!s) tag_error(L, narg, LUA_TSTRING);
return s;
}
LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
const char *def, size_t *len) {
if (lua_isnoneornil(L, narg)) {
if (len)
*len = (def ? strlen(def) : 0);
return def;
}
else return luaL_checklstring(L, narg, len);
}
LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
lua_Number d = lua_tonumber(L, narg);
if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
tag_error(L, narg, LUA_TNUMBER);
return d;
}
LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
if (lua_isnoneornil(L, narg)) return def;
else return luaL_checknumber(L, narg);
}
LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
lua_Integer d = lua_tointeger(L, narg);
if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
tag_error(L, narg, LUA_TNUMBER);
return d;
}
LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
lua_Integer def) {
if (lua_isnoneornil(L, narg)) return def;
else return luaL_checkinteger(L, narg);
}
LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
if (!lua_getmetatable(L, obj)) /* no metatable? */
return 0;
lua_getfield(L, -1, event);
if (lua_isnil(L, -1)) {
lua_pop(L, 2); /* remove metatable and metafield */
return 0;
}
else {
lua_remove(L, -2); /* remove only metatable */
return 1;
}
}
LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
obj = abs_index(L, obj);
if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
return 0;
lua_pushvalue(L, obj);
lua_call(L, 1, 1);
return 1;
}
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l) {
luaI_openlib(L, libname, l, 0);
}
LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
const luaL_Reg *l, int nup) {
if (libname) {
/* check whether lib already exists */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, -1, libname); /* get _LOADED[libname] */
if (!lua_istable(L, -1)) { /* not found? */
lua_pop(L, 1); /* remove previous result */
/* try global variable (and create one if it does not exist) */
if (luaL_findtable(L, LUA_GLOBALSINDEX, libname) != NULL)
luaL_error(L, "name conflict for module " LUA_QS, libname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
}
lua_remove(L, -2); /* remove _LOADED table */
lua_insert(L, -(nup+1)); /* move library table to below upvalues */
}
for (; l->name; l++) {
int i;
for (i=0; i<nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup);
lua_pushcclosure(L, l->func, nup);
lua_setfield(L, -(nup+2), l->name);
}
lua_pop(L, nup); /* remove upvalues */
}
/*
** {======================================================
** getn-setn: size for arrays
** =======================================================
*/
#if defined(LUA_COMPAT_GETN)
static int checkint (lua_State *L, int topop) {
int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
lua_pop(L, topop);
return n;
}
static void getsizes (lua_State *L) {
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
if (lua_isnil(L, -1)) { /* no `size' table? */
lua_pop(L, 1); /* remove nil */
lua_newtable(L); /* create it */
lua_pushvalue(L, -1); /* `size' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushliteral(L, "kv");
lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
}
}
LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
t = abs_index(L, t);
getsizes(L);
lua_pushvalue(L, t);
lua_pushinteger(L, n);
lua_rawset(L, -3); /* sizes[t] = n */
lua_pop(L, 1); /* remove `sizes' */
}
LUALIB_API int luaL_getn (lua_State *L, int t) {
int n;
t = abs_index(L, t);
getsizes(L); /* try sizes[t] */
lua_pushvalue(L, t);
lua_rawget(L, -2);
if ((n = checkint(L, 2)) >= 0) return n;
lua_getfield(L, t, "n"); /* else try t.n */
if ((n = checkint(L, 1)) >= 0) return n;
return lua_objlen(L, t);
}
#endif
/* }====================================================== */
LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
const char *r) {
const char *wild;
size_t l = strlen(p);
luaL_Buffer b;
luaL_buffinit(L, &b);
while ((wild = strstr(s, p)) != NULL) {
luaL_addlstring(&b, s, wild - s); /* push prefix */
luaL_addstring(&b, r); /* push replacement in place of pattern */
s = wild + l; /* continue after `p' */
}
luaL_addstring(&b, s); /* push last suffix */
luaL_pushresult(&b);
return lua_tostring(L, -1);
}
LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
const char *fname) {
const char *e;
lua_pushvalue(L, idx);
do {
e = strchr(fname, '.');
if (e == NULL) e = fname + strlen(fname);
lua_pushlstring(L, fname, e - fname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */
lua_newtable(L); /* create a new table for field */
lua_pushlstring(L, fname, e - fname);
lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */
}
else if (!lua_istable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */
}
lua_remove(L, -2); /* remove previous table */
fname = e + 1;
} while (*e == '.');
return NULL;
}
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
#define bufflen(B) ((B)->p - (B)->buffer)
#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
#define LIMIT (LUA_MINSTACK/2)
static int emptybuffer (luaL_Buffer *B) {
size_t l = bufflen(B);
if (l == 0) return 0; /* put nothing on stack */
else {
lua_pushlstring(B->L, B->buffer, l);
B->p = B->buffer;
B->lvl++;
return 1;
}
}
static void adjuststack (luaL_Buffer *B) {
if (B->lvl > 1) {
lua_State *L = B->L;
int toget = 1; /* number of levels to concat */
size_t toplen = lua_strlen(L, -1);
do {
size_t l = lua_strlen(L, -(toget+1));
if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
toplen += l;
toget++;
}
else break;
} while (toget < B->lvl);
lua_concat(L, toget);
B->lvl = B->lvl - toget + 1;
}
}
LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
if (emptybuffer(B))
adjuststack(B);
return B->buffer;
}
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
while (l--)
luaL_addchar(B, *s++);
}
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
luaL_addlstring(B, s, strlen(s));
}
LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
emptybuffer(B);
lua_concat(B->L, B->lvl);
B->lvl = 1;
}
LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
lua_State *L = B->L;
size_t vl;
const char *s = lua_tolstring(L, -1, &vl);
if (vl <= bufffree(B)) { /* fit into buffer? */
memcpy(B->p, s, vl); /* put it there */
B->p += vl;
lua_pop(L, 1); /* remove from stack */
}
else {
if (emptybuffer(B))
lua_insert(L, -2); /* put buffer before new value */
B->lvl++; /* add new value into B stack */
adjuststack(B);
}
}
LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
B->L = L;
B->p = B->buffer;
B->lvl = 0;
}
/* }====================================================== */
LUALIB_API int luaL_ref (lua_State *L, int t) {
int ref;
t = abs_index(L, t);
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* `nil' has a unique fixed reference */
}
lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
lua_pop(L, 1); /* remove it from stack */
if (ref != 0) { /* any free element? */
lua_rawgeti(L, t, ref); /* remove it from list */
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
}
else { /* no free elements */
ref = lua_objlen(L, t);
ref++; /* create new reference */
}
lua_rawseti(L, t, ref);
return ref;
}
LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
if (ref >= 0) {
t = abs_index(L, t);
lua_rawgeti(L, t, FREELIST_REF);
lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
lua_pushinteger(L, ref);
lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
}
}
/*
** {======================================================
** Load functions
** =======================================================
*/
typedef struct LoadF {
int extraline;
FILE *f;
char buff[LUAL_BUFFERSIZE];
} LoadF;
static const char *getF (lua_State *L, void *ud, size_t *size) {
LoadF *lf = (LoadF *)ud;
(void)L;
if (lf->extraline) {
lf->extraline = 0;
*size = 1;
return "\n";
}
if (feof(lf->f)) return NULL;
*size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f);
return (*size > 0) ? lf->buff : NULL;
}
static int errfile (lua_State *L, const char *what, int fnameindex) {
const char *serr = strerror(errno);
const char *filename = lua_tostring(L, fnameindex) + 1;
lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
lua_remove(L, fnameindex);
return LUA_ERRFILE;
}
LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
LoadF lf;
int status, readstatus;
int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
if (filename == NULL) {
lua_pushliteral(L, "=stdin");
lf.f = stdin;
}
else {
lua_pushfstring(L, "@%s", filename);
lf.f = fopen(filename, "r");
if (lf.f == NULL) return errfile(L, "open", fnameindex);
}
c = getc(lf.f);
if (c == '#') { /* Unix exec. file? */
lf.extraline = 1;
while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
if (c == '\n') c = getc(lf.f);
}
if (c == LUA_SIGNATURE[0] && lf.f != stdin) { /* binary file? */
fclose(lf.f);
lf.f = fopen(filename, "rb"); /* reopen in binary mode */
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
/* skip eventual `#!...' */
while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
lf.extraline = 0;
}
ungetc(c, lf.f);
status = lua_load(L, getF, &lf, lua_tostring(L, -1));
readstatus = ferror(lf.f);
if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, "read", fnameindex);
}
lua_remove(L, fnameindex);
return status;
}
typedef struct LoadS {
const char *s;
size_t size;
} LoadS;
static const char *getS (lua_State *L, void *ud, size_t *size) {
LoadS *ls = (LoadS *)ud;
(void)L;
if (ls->size == 0) return NULL;
*size = ls->size;
ls->size = 0;
return ls->s;
}
LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
const char *name) {
LoadS ls;
ls.s = buff;
ls.size = size;
return lua_load(L, getS, &ls, name);
}
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
return luaL_loadbuffer(L, s, strlen(s), s);
}
/* }====================================================== */
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
(void)ud;
(void)osize;
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
static int panic (lua_State *L) {
(void)L; /* to avoid warnings */
fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
return 0;
}
LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL);
if (L) lua_atpanic(L, &panic);
return L;
}
+171
View File
@@ -0,0 +1,171 @@
/*
** $Id: lauxlib.h,v 1.84 2005/08/26 17:36:32 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
#ifndef lauxlib_h
#define lauxlib_h
#include <stddef.h>
#include <stdio.h>
#include "lua.h"
#if defined(LUA_COMPAT_GETN)
LUALIB_API int (luaL_getn) (lua_State *L, int t);
LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
#else
#define luaL_getn(L,i) ((int)lua_objlen(L, i))
#define luaL_setn(L,i,j) ((void)0) /* no op! */
#endif
#if defined(LUA_COMPAT_OPENLIB)
#define luaI_openlib luaL_openlib
#endif
/* extra error code for `luaL_load' */
#define LUA_ERRFILE (LUA_ERRERR+1)
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;
LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
const luaL_Reg *l, int nup);
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
const char *def, size_t *l);
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
lua_Integer def);
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
const char *const lst[]);
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
LUALIB_API lua_State *(luaL_newstate) (void);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);
LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
const char *fname);
/*
** ===============================================================
** some useful macros
** ===============================================================
*/
#define luaL_argcheck(L, cond,numarg,extramsg) \
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
#define luaL_dofile(L, fn) (luaL_loadfile(L, fn) || lua_pcall(L, 0, 0, 0))
#define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, 0, 0))
#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
typedef struct luaL_Buffer {
char *p; /* current position in buffer */
int lvl; /* number of strings in the stack (level) */
lua_State *L;
char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;
#define luaL_addchar(B,c) \
((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
(*(B)->p++ = (char)(c)))
/* compatibility only */
#define luaL_putchar(B,c) luaL_addchar(B,c)
#define luaL_addsize(B,n) ((B)->p += (n))
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
/* }====================================================== */
/* compatibility with ref system */
/* pre-defined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
(lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
#define luaL_reg luaL_Reg
#endif
+633
View File
@@ -0,0 +1,633 @@
/*
** $Id: lbaselib.c,v 1.181 2005/08/15 14:12:32 roberto Exp roberto $
** Basic library
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lbaselib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** If your system does not support `stdout', you can just remove this function.
** If you need, you can define your own `print' function, following this
** model but changing `fputs' to put the strings at a proper place
** (a console window or a log file, for instance).
*/
static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
lua_getglobal(L, "tostring");
for (i=1; i<=n; i++) {
const char *s;
lua_pushvalue(L, -1); /* function to be called */
lua_pushvalue(L, i); /* value to print */
lua_call(L, 1, 1);
s = lua_tostring(L, -1); /* get result */
if (s == NULL)
return luaL_error(L, LUA_QL("tostring") " must return a string to "
LUA_QL("print"));
if (i>1) fputs("\t", stdout);
fputs(s, stdout);
lua_pop(L, 1); /* pop result */
}
fputs("\n", stdout);
return 0;
}
static int luaB_tonumber (lua_State *L) {
int base = luaL_optint(L, 2, 10);
if (base == 10) { /* standard conversion */
luaL_checkany(L, 1);
if (lua_isnumber(L, 1)) {
lua_pushnumber(L, lua_tonumber(L, 1));
return 1;
}
}
else {
const char *s1 = luaL_checkstring(L, 1);
char *s2;
unsigned long n;
luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
n = strtoul(s1, &s2, base);
if (s1 != s2) { /* at least one valid digit? */
while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
if (*s2 == '\0') { /* no invalid trailing characters? */
lua_pushnumber(L, (lua_Number)n);
return 1;
}
}
}
lua_pushnil(L); /* else not a number */
return 1;
}
static int luaB_error (lua_State *L) {
int level = luaL_optint(L, 2, 1);
lua_settop(L, 1);
if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
luaL_where(L, level);
lua_pushvalue(L, 1);
lua_concat(L, 2);
}
return lua_error(L);
}
static int luaB_getmetatable (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
lua_pushnil(L);
return 1; /* no metatable */
}
luaL_getmetafield(L, 1, "__metatable");
return 1; /* returns either __metatable field (if present) or metatable */
}
static int luaB_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
if (luaL_getmetafield(L, 1, "__metatable"))
luaL_error(L, "cannot change a protected metatable");
lua_settop(L, 2);
lua_setmetatable(L, 1);
return 1;
}
static void getfunc (lua_State *L) {
if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
else {
lua_Debug ar;
int level = luaL_optint(L, 1, 1);
luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
if (lua_getstack(L, level, &ar) == 0)
luaL_argerror(L, 1, "invalid level");
lua_getinfo(L, "f", &ar);
if (lua_isnil(L, -1))
luaL_error(L, "no function environment for tail call at level %d",
level);
}
}
static int luaB_getfenv (lua_State *L) {
getfunc(L);
if (lua_iscfunction(L, -1)) /* is a C function? */
lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
else
lua_getfenv(L, -1);
return 1;
}
static int luaB_setfenv (lua_State *L) {
luaL_checktype(L, 2, LUA_TTABLE);
getfunc(L);
lua_pushvalue(L, 2);
if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
/* change environment of current thread */
lua_pushthread(L);
lua_insert(L, -2);
lua_setfenv(L, -2);
return 0;
}
else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
luaL_error(L,
LUA_QL("setfenv") " cannot change environment of given object");
return 1;
}
static int luaB_rawequal (lua_State *L) {
luaL_checkany(L, 1);
luaL_checkany(L, 2);
lua_pushboolean(L, lua_rawequal(L, 1, 2));
return 1;
}
static int luaB_rawget (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_rawget(L, 1);
return 1;
}
static int luaB_rawset (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2);
luaL_checkany(L, 3);
lua_settop(L, 3);
lua_rawset(L, 1);
return 1;
}
static int luaB_gcinfo (lua_State *L) {
lua_pushinteger(L, lua_getgccount(L));
return 1;
}
static int luaB_collectgarbage (lua_State *L) {
static const char *const opts[] = {"stop", "restart", "collect",
"count", "step", "setpause", "setstepmul", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
int o = luaL_checkoption(L, 1, "collect", opts);
int ex = luaL_optinteger(L, 2, 0);
lua_pushinteger(L, lua_gc(L, optsnum[o], ex));
return 1;
}
static int luaB_type (lua_State *L) {
luaL_checkany(L, 1);
lua_pushstring(L, luaL_typename(L, 1));
return 1;
}
static int luaB_next (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
if (lua_next(L, 1))
return 2;
else {
lua_pushnil(L);
return 1;
}
}
static int luaB_pairs (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushnil(L); /* and initial value */
return 3;
}
static int ipairsaux (lua_State *L) {
int i = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
i++; /* next value */
lua_pushinteger(L, i);
lua_rawgeti(L, 1, i);
return (lua_isnil(L, -1)) ? 0 : 2;
}
static int luaB_ipairs (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushinteger(L, 0); /* and initial value */
return 3;
}
static int load_aux (lua_State *L, int status) {
if (status == 0) /* OK? */
return 1;
else {
lua_pushnil(L);
lua_insert(L, -2); /* put before error message */
return 2; /* return nil plus error message */
}
}
static int luaB_loadstring (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
const char *chunkname = luaL_optstring(L, 2, s);
return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
}
static int luaB_loadfile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
return load_aux(L, luaL_loadfile(L, fname));
}
/*
** Reader for generic `load' function: `lua_load' uses the
** stack for internal stuff, so the reader cannot change the
** stack top. Instead, it keeps its resulting string in a
** reserved slot inside the stack.
*/
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
(void)ud; /* to avoid warnings */
luaL_checkstack(L, 2, "too many nested functions");
lua_pushvalue(L, 1); /* get function */
lua_call(L, 0, 1); /* call it */
if (lua_isnil(L, -1)) {
*size = 0;
return NULL;
}
else if (lua_isstring(L, -1)) {
lua_replace(L, 3); /* save string in a reserved stack slot */
return lua_tolstring(L, 3, size);
}
else luaL_error(L, "reader function must return a string");
return NULL; /* to avoid warnings */
}
static int luaB_load (lua_State *L) {
int status;
const char *cname = luaL_optstring(L, 2, "=(load)");
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
status = lua_load(L, generic_reader, NULL, cname);
return load_aux(L, status);
}
static int luaB_dofile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
int n = lua_gettop(L);
if (luaL_loadfile(L, fname) != 0) lua_error(L);
lua_call(L, 0, LUA_MULTRET);
return lua_gettop(L) - n;
}
static int luaB_assert (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_toboolean(L, 1))
return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
return lua_gettop(L);
}
static int luaB_unpack (lua_State *L) {
int i = luaL_optint(L, 2, 1);
int e = luaL_optint(L, 3, -1);
int n;
luaL_checktype(L, 1, LUA_TTABLE);
if (e == -1)
e = luaL_getn(L, 1);
n = e - i + 1; /* number of elements */
if (n <= 0) return 0; /* empty range */
luaL_checkstack(L, n, "table too big to unpack");
for (; i<=e; i++) /* push arg[i...e] */
lua_rawgeti(L, 1, i);
return n;
}
static int luaB_select (lua_State *L) {
int n = lua_gettop(L);
if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
lua_pushinteger(L, n-1);
return 1;
}
else {
int i = luaL_checkint(L, 1);
if (i <= 0) i = 1;
else if (i >= n) i = n;
return n - i;
}
}
static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
lua_pushboolean(L, (status == 0));
lua_insert(L, 1);
return lua_gettop(L); /* return status + all results */
}
static int luaB_xpcall (lua_State *L) {
int status;
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_insert(L, 1); /* put error function under function to be called */
status = lua_pcall(L, 0, LUA_MULTRET, 1);
lua_pushboolean(L, (status == 0));
lua_replace(L, 1);
return lua_gettop(L); /* return status + all results */
}
static int luaB_tostring (lua_State *L) {
luaL_checkany(L, 1);
if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
return 1; /* use its value */
switch (lua_type(L, 1)) {
case LUA_TNUMBER:
lua_pushstring(L, lua_tostring(L, 1));
break;
case LUA_TSTRING:
lua_pushvalue(L, 1);
break;
case LUA_TBOOLEAN:
lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
break;
case LUA_TNIL:
lua_pushliteral(L, "nil");
break;
default:
lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
break;
}
return 1;
}
static int luaB_newproxy (lua_State *L) {
lua_settop(L, 1);
lua_newuserdata(L, 0); /* create proxy */
if (lua_toboolean(L, 1) == 0)
return 1; /* no metatable */
else if (lua_isboolean(L, 1)) {
lua_newtable(L); /* create a new metatable `m' ... */
lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
lua_pushboolean(L, 1);
lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
}
else {
int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
if (lua_getmetatable(L, 1)) {
lua_rawget(L, lua_upvalueindex(1));
validproxy = lua_toboolean(L, -1);
lua_pop(L, 1); /* remove value */
}
luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
lua_getmetatable(L, 1); /* metatable is valid; get it */
}
lua_setmetatable(L, 2);
return 1;
}
static const luaL_Reg base_funcs[] = {
{"assert", luaB_assert},
{"collectgarbage", luaB_collectgarbage},
{"dofile", luaB_dofile},
{"error", luaB_error},
{"gcinfo", luaB_gcinfo},
{"getfenv", luaB_getfenv},
{"getmetatable", luaB_getmetatable},
{"loadfile", luaB_loadfile},
{"load", luaB_load},
{"loadstring", luaB_loadstring},
{"next", luaB_next},
{"pcall", luaB_pcall},
{"print", luaB_print},
{"rawequal", luaB_rawequal},
{"rawget", luaB_rawget},
{"rawset", luaB_rawset},
{"select", luaB_select},
{"setfenv", luaB_setfenv},
{"setmetatable", luaB_setmetatable},
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
{"type", luaB_type},
{"unpack", luaB_unpack},
{"xpcall", luaB_xpcall},
{NULL, NULL}
};
/*
** {======================================================
** Coroutine library
** =======================================================
*/
static int auxresume (lua_State *L, lua_State *co, int narg) {
int status;
if (!lua_checkstack(co, narg))
luaL_error(L, "too many arguments to resume");
if (lua_status(co) == 0 && lua_gettop(co) == 0) {
lua_pushliteral(L, "cannot resume dead coroutine");
return -1; /* error flag */
}
lua_xmove(L, co, narg);
status = lua_resume(co, narg);
if (status == 0 || status == LUA_YIELD) {
int nres = lua_gettop(co);
if (!lua_checkstack(L, nres))
luaL_error(L, "too many results to resume");
lua_xmove(co, L, nres); /* move yielded values */
return nres;
}
else {
lua_xmove(co, L, 1); /* move error message */
return -1; /* error flag */
}
}
static int luaB_coresume (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
int r;
luaL_argcheck(L, co, 1, "coroutine expected");
r = auxresume(L, co, lua_gettop(L) - 1);
if (r < 0) {
lua_pushboolean(L, 0);
lua_insert(L, -2);
return 2; /* return false + error message */
}
else {
lua_pushboolean(L, 1);
lua_insert(L, -(r + 1));
return r + 1; /* return true + `resume' returns */
}
}
static int luaB_auxwrap (lua_State *L) {
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
int r = auxresume(L, co, lua_gettop(L));
if (r < 0) {
if (lua_isstring(L, -1)) { /* error object is a string? */
luaL_where(L, 1); /* add extra info */
lua_insert(L, -2);
lua_concat(L, 2);
}
lua_error(L); /* propagate error */
}
return r;
}
static int luaB_cocreate (lua_State *L) {
lua_State *NL = lua_newthread(L);
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
"Lua function expected");
lua_pushvalue(L, 1); /* move function to top */
lua_xmove(L, NL, 1); /* move function from L to NL */
return 1;
}
static int luaB_cowrap (lua_State *L) {
luaB_cocreate(L);
lua_pushcclosure(L, luaB_auxwrap, 1);
return 1;
}
static int luaB_yield (lua_State *L) {
return lua_yield(L, lua_gettop(L));
}
static int luaB_costatus (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
luaL_argcheck(L, co, 1, "coroutine expected");
if (L == co) lua_pushliteral(L, "running");
else {
switch (lua_status(co)) {
case LUA_YIELD:
lua_pushliteral(L, "suspended");
break;
case 0: {
lua_Debug ar;
if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
lua_pushliteral(L, "normal"); /* it is running */
else if (lua_gettop(co) == 0)
lua_pushliteral(L, "dead");
else
lua_pushliteral(L, "suspended"); /* initial state */
break;
}
default: /* some error occured */
lua_pushliteral(L, "dead");
break;
}
}
return 1;
}
static int luaB_corunning (lua_State *L) {
if (lua_pushthread(L))
return 0; /* main thread is not a coroutine */
else
return 1;
}
static const luaL_Reg co_funcs[] = {
{"create", luaB_cocreate},
{"resume", luaB_coresume},
{"running", luaB_corunning},
{"status", luaB_costatus},
{"wrap", luaB_cowrap},
{"yield", luaB_yield},
{NULL, NULL}
};
/* }====================================================== */
static void auxopen (lua_State *L, const char *name,
lua_CFunction f, lua_CFunction u) {
lua_pushcfunction(L, u);
lua_pushcclosure(L, f, 1);
lua_setfield(L, -2, name);
}
static void base_open (lua_State *L) {
lua_pushvalue(L, LUA_GLOBALSINDEX);
luaL_register(L, NULL, base_funcs); /* open lib into global table */
lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */
/* `ipairs' and `pairs' need auxiliary functions as upvalues */
auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
auxopen(L, "pairs", luaB_pairs, luaB_next);
/* `newproxy' needs a weaktable as upvalue */
lua_newtable(L); /* new table `w' */
lua_pushvalue(L, -1); /* `w' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushliteral(L, "kv");
lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
lua_pushcclosure(L, luaB_newproxy, 1);
lua_setglobal(L, "newproxy"); /* set global `newproxy' */
/* create register._LOADED to track loaded modules */
lua_newtable(L);
lua_setfield(L, LUA_REGISTRYINDEX, "_LOADED");
/* set global _G */
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G");
}
LUALIB_API int luaopen_base (lua_State *L) {
base_open(L);
luaL_register(L, LUA_COLIBNAME, co_funcs);
return 2;
}
+782
View File
@@ -0,0 +1,782 @@
/*
** $Id: lcode.c,v 2.15 2005/08/17 18:32:09 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#define lcode_c
#define LUA_CORE
#include "lua.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "ltable.h"
#define hasjumps(e) ((e)->t != (e)->f)
void luaK_nil (FuncState *fs, int from, int n) {
Instruction *previous;
if (fs->pc > fs->lasttarget && /* no jumps to current position? */
GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) {
int pfrom = GETARG_A(*previous);
int pto = GETARG_B(*previous);
if (pfrom <= from && from <= pto+1) { /* can connect both? */
if (from+n-1 > pto)
SETARG_B(*previous, from+n-1);
return;
}
}
luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
}
int luaK_jump (FuncState *fs) {
int jpc = fs->jpc; /* save list of jumps to here */
int j;
fs->jpc = NO_JUMP;
j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
luaK_concat(fs, &j, jpc); /* keep them on hold */
return j;
}
void luaK_ret (FuncState *fs, int first, int nret) {
luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
}
static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
luaK_codeABC(fs, op, A, B, C);
return luaK_jump(fs);
}
static void fixjump (FuncState *fs, int pc, int dest) {
Instruction *jmp = &fs->f->code[pc];
int offset = dest-(pc+1);
lua_assert(dest != NO_JUMP);
if (abs(offset) > MAXARG_sBx)
luaX_syntaxerror(fs->ls, "control structure too long");
SETARG_sBx(*jmp, offset);
}
/*
** returns current `pc' and marks it as a jump target (to avoid wrong
** optimizations with consecutive instructions not in the same basic block).
*/
int luaK_getlabel (FuncState *fs) {
fs->lasttarget = fs->pc;
return fs->pc;
}
static int getjump (FuncState *fs, int pc) {
int offset = GETARG_sBx(fs->f->code[pc]);
if (offset == NO_JUMP) /* point to itself represents end of list */
return NO_JUMP; /* end of list */
else
return (pc+1)+offset; /* turn offset into absolute position */
}
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
Instruction *pi = &fs->f->code[pc];
if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
return pi-1;
else
return pi;
}
/*
** check whether list has any jump that do not produce a value
** (or produce an inverted value)
*/
static int need_value (FuncState *fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list)) {
Instruction i = *getjumpcontrol(fs, list);
if (GET_OPCODE(i) != OP_TESTSET) return 1;
}
return 0; /* not found */
}
static void patchtestreg (Instruction *i, int reg) {
if (reg != NO_REG)
SETARG_A(*i, reg);
else /* no register to put value; change TESTSET to TEST */
*i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
}
static void removevalues (FuncState *fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list)) {
Instruction *i = getjumpcontrol(fs, list);
if (GET_OPCODE(*i) == OP_TESTSET)
patchtestreg(i, NO_REG);
}
}
static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
int dtarget) {
while (list != NO_JUMP) {
int next = getjump(fs, list);
Instruction *i = getjumpcontrol(fs, list);
if (GET_OPCODE(*i) == OP_TESTSET) {
patchtestreg(i, reg);
fixjump(fs, list, vtarget);
}
else
fixjump(fs, list, dtarget); /* jump to default target */
list = next;
}
}
static void dischargejpc (FuncState *fs) {
patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
fs->jpc = NO_JUMP;
}
void luaK_patchlist (FuncState *fs, int list, int target) {
if (target == fs->pc)
luaK_patchtohere(fs, list);
else {
lua_assert(target < fs->pc);
patchlistaux(fs, list, target, NO_REG, target);
}
}
void luaK_patchtohere (FuncState *fs, int list) {
luaK_getlabel(fs);
luaK_concat(fs, &fs->jpc, list);
}
void luaK_concat (FuncState *fs, int *l1, int l2) {
if (l2 == NO_JUMP) return;
else if (*l1 == NO_JUMP)
*l1 = l2;
else {
int list = *l1;
int next;
while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
list = next;
fixjump(fs, list, l2);
}
}
void luaK_checkstack (FuncState *fs, int n) {
int newstack = fs->freereg + n;
if (newstack > fs->f->maxstacksize) {
if (newstack >= MAXSTACK)
luaX_syntaxerror(fs->ls, "function or expression too complex");
fs->f->maxstacksize = cast(lu_byte, newstack);
}
}
void luaK_reserveregs (FuncState *fs, int n) {
luaK_checkstack(fs, n);
fs->freereg += n;
}
static void freereg (FuncState *fs, int reg) {
if (!ISK(reg) && reg >= fs->nactvar) {
fs->freereg--;
lua_assert(reg == fs->freereg);
}
}
static void freeexp (FuncState *fs, expdesc *e) {
if (e->k == VNONRELOC)
freereg(fs, e->info);
}
static int addk (FuncState *fs, TValue *k, TValue *v) {
lua_State *L = fs->L;
TValue *idx = luaH_set(L, fs->h, k);
Proto *f = fs->f;
int oldsize = f->sizek;
if (ttisnumber(idx)) {
lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
return cast(int, nvalue(idx));
}
else { /* constant not found; create a new entry */
setnvalue(idx, cast(lua_Number, fs->nk));
luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
MAXARG_Bx, "constant table overflow");
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
setobj(L, &f->k[fs->nk], v);
luaC_barrier(L, f, v);
return fs->nk++;
}
}
int luaK_stringK (FuncState *fs, TString *s) {
TValue o;
setsvalue(fs->L, &o, s);
return addk(fs, &o, &o);
}
int luaK_numberK (FuncState *fs, lua_Number r) {
TValue o;
setnvalue(&o, r);
return addk(fs, &o, &o);
}
static int boolK (FuncState *fs, int b) {
TValue o;
setbvalue(&o, b);
return addk(fs, &o, &o);
}
static int nilK (FuncState *fs) {
TValue k, v;
setnilvalue(&v);
/* cannot use nil as key; instead use table itself to represent nil */
sethvalue(fs->L, &k, fs->h);
return addk(fs, &k, &v);
}
void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
if (e->k == VCALL) { /* expression is an open function call? */
SETARG_C(getcode(fs, e), nresults+1);
}
else if (e->k == VVARARG) {
SETARG_B(getcode(fs, e), nresults+1);
SETARG_A(getcode(fs, e), fs->freereg);
luaK_reserveregs(fs, 1);
}
}
void luaK_setoneret (FuncState *fs, expdesc *e) {
if (e->k == VCALL) { /* expression is an open function call? */
e->k = VNONRELOC;
e->info = GETARG_A(getcode(fs, e));
}
else if (e->k == VVARARG) {
SETARG_B(getcode(fs, e), 2);
e->k = VRELOCABLE; /* can relocate its simple result */
}
}
void luaK_dischargevars (FuncState *fs, expdesc *e) {
switch (e->k) {
case VLOCAL: {
e->k = VNONRELOC;
break;
}
case VUPVAL: {
e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0);
e->k = VRELOCABLE;
break;
}
case VGLOBAL: {
e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info);
e->k = VRELOCABLE;
break;
}
case VINDEXED: {
freereg(fs, e->aux);
freereg(fs, e->info);
e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux);
e->k = VRELOCABLE;
break;
}
case VVARARG:
case VCALL: {
luaK_setoneret(fs, e);
break;
}
default: break; /* there is one value available (somewhere) */
}
}
static int code_label (FuncState *fs, int A, int b, int jump) {
luaK_getlabel(fs); /* those instructions may be jump targets */
return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
}
static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
luaK_dischargevars(fs, e);
switch (e->k) {
case VNIL: {
luaK_nil(fs, reg, 1);
break;
}
case VFALSE: case VTRUE: {
luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
break;
}
case VK: {
luaK_codeABx(fs, OP_LOADK, reg, e->info);
break;
}
case VRELOCABLE: {
Instruction *pc = &getcode(fs, e);
SETARG_A(*pc, reg);
break;
}
case VNONRELOC: {
if (reg != e->info)
luaK_codeABC(fs, OP_MOVE, reg, e->info, 0);
break;
}
default: {
lua_assert(e->k == VVOID || e->k == VJMP);
return; /* nothing to do... */
}
}
e->info = reg;
e->k = VNONRELOC;
}
static void discharge2anyreg (FuncState *fs, expdesc *e) {
if (e->k != VNONRELOC) {
luaK_reserveregs(fs, 1);
discharge2reg(fs, e, fs->freereg-1);
}
}
static void exp2reg (FuncState *fs, expdesc *e, int reg) {
discharge2reg(fs, e, reg);
if (e->k == VJMP)
luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */
if (hasjumps(e)) {
int final; /* position after whole expression */
int p_f = NO_JUMP; /* position of an eventual LOAD false */
int p_t = NO_JUMP; /* position of an eventual LOAD true */
if (need_value(fs, e->t) || need_value(fs, e->f)) {
int fj = NO_JUMP; /* first jump (over LOAD ops.) */
if (e->k != VJMP)
fj = luaK_jump(fs);
p_f = code_label(fs, reg, 0, 1);
p_t = code_label(fs, reg, 1, 0);
luaK_patchtohere(fs, fj);
}
final = luaK_getlabel(fs);
patchlistaux(fs, e->f, final, reg, p_f);
patchlistaux(fs, e->t, final, reg, p_t);
}
e->f = e->t = NO_JUMP;
e->info = reg;
e->k = VNONRELOC;
}
void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
freeexp(fs, e);
luaK_reserveregs(fs, 1);
exp2reg(fs, e, fs->freereg - 1);
}
int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
if (e->k == VNONRELOC) {
if (!hasjumps(e)) return e->info; /* exp is already in a register */
if (e->info >= fs->nactvar) { /* reg. is not a local? */
exp2reg(fs, e, e->info); /* put value on it */
return e->info;
}
}
luaK_exp2nextreg(fs, e); /* default */
return e->info;
}
void luaK_exp2val (FuncState *fs, expdesc *e) {
if (hasjumps(e))
luaK_exp2anyreg(fs, e);
else
luaK_dischargevars(fs, e);
}
int luaK_exp2RK (FuncState *fs, expdesc *e) {
luaK_exp2val(fs, e);
switch (e->k) {
case VTRUE:
case VFALSE:
case VNIL: {
if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
e->info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
e->k = VK;
return RKASK(e->info);
}
else break;
}
case VK: {
if (e->info <= MAXINDEXRK) /* constant fit in argC? */
return RKASK(e->info);
else break;
}
default: break;
}
/* not a constant in the right range: put it in a register */
return luaK_exp2anyreg(fs, e);
}
void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
switch (var->k) {
case VLOCAL: {
freeexp(fs, ex);
exp2reg(fs, ex, var->info);
return;
}
case VUPVAL: {
int e = luaK_exp2anyreg(fs, ex);
luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0);
break;
}
case VGLOBAL: {
int e = luaK_exp2anyreg(fs, ex);
luaK_codeABx(fs, OP_SETGLOBAL, e, var->info);
break;
}
case VINDEXED: {
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
break;
}
default: {
lua_assert(0); /* invalid var kind to store */
break;
}
}
freeexp(fs, ex);
}
void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
int func;
luaK_exp2anyreg(fs, e);
freeexp(fs, e);
func = fs->freereg;
luaK_reserveregs(fs, 2);
luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key));
freeexp(fs, key);
e->info = func;
e->k = VNONRELOC;
}
static void invertjump (FuncState *fs, expdesc *e) {
Instruction *pc = getjumpcontrol(fs, e->info);
lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
GET_OPCODE(*pc) != OP_TEST);
SETARG_A(*pc, !(GETARG_A(*pc)));
}
static int jumponcond (FuncState *fs, expdesc *e, int cond) {
if (e->k == VRELOCABLE) {
Instruction ie = getcode(fs, e);
if (GET_OPCODE(ie) == OP_NOT) {
fs->pc--; /* remove previous OP_NOT */
return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
}
/* else go through */
}
discharge2anyreg(fs, e);
freeexp(fs, e);
return condjump(fs, OP_TESTSET, NO_REG, e->info, cond);
}
void luaK_goiftrue (FuncState *fs, expdesc *e) {
int pc; /* pc of last jump */
luaK_dischargevars(fs, e);
switch (e->k) {
case VK: case VTRUE: {
pc = NO_JUMP; /* always true; do nothing */
break;
}
case VFALSE: {
pc = luaK_jump(fs); /* always jump */
break;
}
case VJMP: {
invertjump(fs, e);
pc = e->info;
break;
}
default: {
pc = jumponcond(fs, e, 0);
break;
}
}
luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
luaK_patchtohere(fs, e->t);
e->t = NO_JUMP;
}
void luaK_goiffalse (FuncState *fs, expdesc *e) {
int pc; /* pc of last jump */
luaK_dischargevars(fs, e);
switch (e->k) {
case VNIL: case VFALSE: {
pc = NO_JUMP; /* always false; do nothing */
break;
}
case VTRUE: {
pc = luaK_jump(fs); /* always jump */
break;
}
case VJMP: {
pc = e->info;
break;
}
default: {
pc = jumponcond(fs, e, 1);
break;
}
}
luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
luaK_patchtohere(fs, e->f);
e->f = NO_JUMP;
}
static void codenot (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
switch (e->k) {
case VNIL: case VFALSE: {
e->k = VTRUE;
break;
}
case VK: case VTRUE: {
e->k = VFALSE;
break;
}
case VJMP: {
invertjump(fs, e);
break;
}
case VRELOCABLE:
case VNONRELOC: {
discharge2anyreg(fs, e);
freeexp(fs, e);
e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0);
e->k = VRELOCABLE;
break;
}
default: {
lua_assert(0); /* cannot happen */
break;
}
}
/* interchange true and false lists */
{ int temp = e->f; e->f = e->t; e->t = temp; }
removevalues(fs, e->f);
removevalues(fs, e->t);
}
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
t->aux = luaK_exp2RK(fs, k);
t->k = VINDEXED;
}
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
switch (op) {
case OPR_MINUS: {
luaK_exp2val(fs, e);
if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
e->info = luaK_numberK(fs, luai_numunm(L, nvalue(&fs->f->k[e->info])));
else {
luaK_exp2anyreg(fs, e);
freeexp(fs, e);
e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0);
e->k = VRELOCABLE;
}
break;
}
case OPR_NOT: {
codenot(fs, e);
break;
}
case OPR_LEN: {
luaK_exp2anyreg(fs, e);
freeexp(fs, e);
e->info = luaK_codeABC(fs, OP_LEN, 0, e->info, 0);
e->k = VRELOCABLE;
break;
}
default: lua_assert(0);
}
}
void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
switch (op) {
case OPR_AND: {
luaK_goiftrue(fs, v);
break;
}
case OPR_OR: {
luaK_goiffalse(fs, v);
break;
}
case OPR_CONCAT: {
luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
break;
}
default: {
luaK_exp2RK(fs, v);
break;
}
}
}
static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
int o1, int o2) {
if (op <= OPR_POW) { /* arithmetic operator? */
OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */
res->info = luaK_codeABC(fs, opc, 0, o1, o2);
res->k = VRELOCABLE;
}
else { /* test operator */
static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE};
int cond = 1;
if (op >= OPR_GT) { /* `>' or `>='? */
int temp; /* exchange args and replace by `<' or `<=' */
temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
}
else if (op == OPR_NE) cond = 0;
res->info = condjump(fs, ops[op - OPR_NE], cond, o1, o2);
res->k = VJMP;
}
}
void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
switch (op) {
case OPR_AND: {
lua_assert(e1->t == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &e1->f, e2->f);
e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t;
break;
}
case OPR_OR: {
lua_assert(e1->f == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &e1->t, e2->t);
e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f;
break;
}
case OPR_CONCAT: {
luaK_exp2val(fs, e2);
if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1);
freeexp(fs, e1);
SETARG_B(getcode(fs, e2), e1->info);
e1->k = e2->k; e1->info = e2->info;
}
else {
luaK_exp2nextreg(fs, e2);
freeexp(fs, e2);
freeexp(fs, e1);
e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info);
e1->k = VRELOCABLE;
}
break;
}
default: {
int o1 = luaK_exp2RK(fs, e1);
int o2 = luaK_exp2RK(fs, e2);
freeexp(fs, e2);
freeexp(fs, e1);
codebinop(fs, e1, op, o1, o2);
}
}
}
void luaK_fixline (FuncState *fs, int line) {
fs->f->lineinfo[fs->pc - 1] = line;
}
int luaK_code (FuncState *fs, Instruction i, int line) {
Proto *f = fs->f;
dischargejpc(fs); /* `pc' will change */
/* put new instruction in code array */
luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
MAX_INT, "code size overflow");
f->code[fs->pc] = i;
/* save corresponding line information */
luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
MAX_INT, "code size overflow");
f->lineinfo[fs->pc] = line;
return fs->pc++;
}
int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
lua_assert(getOpMode(o) == iABC);
lua_assert(getBMode(o) != OpArgN || b == 0);
lua_assert(getCMode(o) != OpArgN || c == 0);
return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
}
int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
lua_assert(getCMode(o) == OpArgN);
return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
}
void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
int b = (tostore == LUA_MULTRET) ? 0 : tostore;
lua_assert(tostore != 0);
if (c <= MAXARG_C)
luaK_codeABC(fs, OP_SETLIST, base, b, c);
else {
luaK_codeABC(fs, OP_SETLIST, base, b, 0);
luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
}
fs->freereg = base + 1; /* free registers with list values */
}
+79
View File
@@ -0,0 +1,79 @@
/*
** $Id: lcode.h,v 1.44 2005/05/20 15:53:42 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
#ifndef lcode_h
#define lcode_h
#include "llex.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
/*
** Marks the end of a patch list. It is an invalid value both as an absolute
** address, and as a list link (would link an element to itself).
*/
#define NO_JUMP (-1)
/*
** grep "ORDER OPR" if you change these enums
*/
typedef enum BinOpr {
OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_MOD, OPR_POW,
OPR_CONCAT,
OPR_NE, OPR_EQ,
OPR_LT, OPR_LE, OPR_GT, OPR_GE,
OPR_AND, OPR_OR,
OPR_NOBINOPR
} BinOpr;
#define binopistest(op) ((op) >= OPR_NE)
typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
#define getcode(fs,e) ((fs)->f->code[(e)->info])
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
LUAI_FUNC int luaK_code (FuncState *fs, Instruction i, int line);
LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_jump (FuncState *fs);
LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
LUAI_FUNC int luaK_getlabel (FuncState *fs);
LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
#endif
+390
View File
@@ -0,0 +1,390 @@
/*
** $Id: ldblib.c,v 1.100 2005/08/15 14:12:32 roberto Exp roberto $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ldblib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static int db_getmetatable (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
lua_pushnil(L); /* no metatable */
}
return 1;
}
static int db_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
lua_settop(L, 2);
lua_pushboolean(L, lua_setmetatable(L, 1));
return 1;
}
static int db_getfenv (lua_State *L) {
lua_getfenv(L, 1);
return 1;
}
static int db_setfenv (lua_State *L) {
luaL_checktype(L, 2, LUA_TTABLE);
lua_settop(L, 2);
if (lua_setfenv(L, 1) == 0)
luaL_error(L, LUA_QL("setfenv")
" cannot change environment of given object");
return 1;
}
static void settabss (lua_State *L, const char *i, const char *v) {
lua_pushstring(L, v);
lua_setfield(L, -2, i);
}
static void settabsi (lua_State *L, const char *i, int v) {
lua_pushinteger(L, v);
lua_setfield(L, -2, i);
}
static lua_State *getthread (lua_State *L, int *arg) {
if (lua_isthread(L, 1)) {
*arg = 1;
return lua_tothread(L, 1);
}
else {
*arg = 0;
return L;
}
}
static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
if (L == L1) {
lua_pushvalue(L, -2);
lua_remove(L, -3);
}
else
lua_xmove(L1, L, 1);
lua_setfield(L, -2, fname);
}
static int db_getinfo (lua_State *L) {
lua_Debug ar;
int arg;
lua_State *L1 = getthread(L, &arg);
const char *options = luaL_optstring(L, arg+2, "flnSu");
if (lua_isnumber(L, arg+1)) {
if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
lua_pushnil(L); /* level out of range */
return 1;
}
}
else if (lua_isfunction(L, arg+1)) {
lua_pushfstring(L, ">%s", options);
options = lua_tostring(L, -1);
lua_pushvalue(L, arg+1);
lua_xmove(L, L1, 1);
}
else
return luaL_argerror(L, arg+1, "function or level expected");
if (!lua_getinfo(L1, options, &ar))
return luaL_argerror(L, arg+2, "invalid option");
lua_newtable(L);
if (strchr(options, 'S')) {
settabss(L, "source", ar.source);
settabss(L, "short_src", ar.short_src);
settabsi(L, "linedefined", ar.linedefined);
settabsi(L, "lastlinedefined", ar.lastlinedefined);
settabss(L, "what", ar.what);
}
if (strchr(options, 'l'))
settabsi(L, "currentline", ar.currentline);
if (strchr(options, 'u'))
settabsi(L, "nups", ar.nups);
if (strchr(options, 'n')) {
settabss(L, "name", ar.name);
settabss(L, "namewhat", ar.namewhat);
}
if (strchr(options, 'L'))
treatstackoption(L, L1, "activelines");
if (strchr(options, 'f'))
treatstackoption(L, L1, "func");
return 1; /* return table */
}
static int db_getlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
const char *name;
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
if (name) {
lua_xmove(L1, L, 1);
lua_pushstring(L, name);
lua_pushvalue(L, -2);
return 2;
}
else {
lua_pushnil(L);
return 1;
}
}
static int db_setlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
luaL_checkany(L, arg+3);
lua_settop(L, arg+3);
lua_xmove(L, L1, 1);
lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
return 1;
}
static int auxupvalue (lua_State *L, int get) {
const char *name;
int n = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TFUNCTION);
if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
if (name == NULL) return 0;
lua_pushstring(L, name);
lua_insert(L, -(get+1));
return get + 1;
}
static int db_getupvalue (lua_State *L) {
return auxupvalue(L, 1);
}
static int db_setupvalue (lua_State *L) {
luaL_checkany(L, 3);
return auxupvalue(L, 0);
}
static const char KEY_HOOK = 'h';
static void hookf (lua_State *L, lua_Debug *ar) {
static const char *const hooknames[] =
{"call", "return", "line", "count", "tail return"};
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushlightuserdata(L, L);
lua_rawget(L, -2);
if (lua_isfunction(L, -1)) {
lua_pushstring(L, hooknames[(int)ar->event]);
if (ar->currentline >= 0)
lua_pushinteger(L, ar->currentline);
else lua_pushnil(L);
lua_assert(lua_getinfo(L, "lS", ar));
lua_call(L, 2, 0);
}
}
static int makemask (const char *smask, int count) {
int mask = 0;
if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
if (strchr(smask, 'r')) mask |= LUA_MASKRET;
if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
if (count > 0) mask |= LUA_MASKCOUNT;
return mask;
}
static char *unmakemask (int mask, char *smask) {
int i = 0;
if (mask & LUA_MASKCALL) smask[i++] = 'c';
if (mask & LUA_MASKRET) smask[i++] = 'r';
if (mask & LUA_MASKLINE) smask[i++] = 'l';
smask[i] = '\0';
return smask;
}
static void gethooktable (lua_State *L) {
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX);
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
lua_newtable(L);
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX);
}
}
static int db_sethook (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
if (lua_isnoneornil(L, arg+1)) {
lua_settop(L, arg+1);
lua_sethook(L1, NULL, 0, 0); /* turn off hooks */
}
else {
const char *smask = luaL_checkstring(L, arg+2);
int count = luaL_optint(L, arg+3, 0);
luaL_checktype(L, arg+1, LUA_TFUNCTION);
lua_sethook(L1, hookf, makemask(smask, count), count);
}
gethooktable(L1);
lua_pushlightuserdata(L1, L1);
lua_pushvalue(L, arg+1);
lua_xmove(L, L1, 1);
lua_rawset(L1, -3); /* set new hook */
lua_pop(L1, 1); /* remove hook table */
return 0;
}
static int db_gethook (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
char buff[5];
int mask = lua_gethookmask(L1);
lua_Hook hook = lua_gethook(L1);
if (hook != NULL && hook != hookf) /* external hook? */
lua_pushliteral(L, "external hook");
else {
gethooktable(L1);
lua_pushlightuserdata(L1, L1);
lua_rawget(L1, -2); /* get hook */
lua_remove(L1, -2); /* remove hook table */
lua_xmove(L1, L, 1);
}
lua_pushstring(L, unmakemask(mask, buff));
lua_pushinteger(L, lua_gethookcount(L1));
return 3;
}
static int db_debug (lua_State *L) {
for (;;) {
char buffer[250];
fputs("lua_debug> ", stderr);
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
strcmp(buffer, "cont\n") == 0)
return 0;
if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
lua_pcall(L, 0, 0, 0)) {
fputs(lua_tostring(L, -1), stderr);
fputs("\n", stderr);
}
lua_settop(L, 0); /* remove eventual returns */
}
}
#define LEVELS1 12 /* size of the first part of the stack */
#define LEVELS2 10 /* size of the second part of the stack */
static int db_errorfb (lua_State *L) {
int level;
int firstpart = 1; /* still before eventual `...' */
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
if (lua_isnumber(L, arg+2)) {
level = lua_tointeger(L, arg+2);
lua_pop(L, 1);
}
else
level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
if (lua_gettop(L) == arg)
lua_pushliteral(L, "");
else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
else lua_pushliteral(L, "\n");
lua_pushliteral(L, "stack traceback:");
while (lua_getstack(L1, level++, &ar)) {
if (level > LEVELS1 && firstpart) {
/* no more than `LEVELS2' more levels? */
if (!lua_getstack(L1, level+LEVELS2, &ar))
level--; /* keep going */
else {
lua_pushliteral(L, "\n\t..."); /* too many levels */
while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
level++;
}
firstpart = 0;
continue;
}
lua_pushliteral(L, "\n\t");
lua_getinfo(L1, "Snl", &ar);
lua_pushfstring(L, "%s:", ar.short_src);
if (ar.currentline > 0)
lua_pushfstring(L, "%d:", ar.currentline);
if (*ar.namewhat != '\0') /* is there a name? */
lua_pushfstring(L, " in function " LUA_QS, ar.name);
else {
if (*ar.what == 'm') /* main? */
lua_pushfstring(L, " in main chunk");
else if (*ar.what == 'C' || *ar.what == 't')
lua_pushliteral(L, " ?"); /* C function or tail call */
else
lua_pushfstring(L, " in function <%s:%d>",
ar.short_src, ar.linedefined);
}
lua_concat(L, lua_gettop(L) - arg);
}
lua_concat(L, lua_gettop(L) - arg);
return 1;
}
static const luaL_Reg dblib[] = {
{"debug", db_debug},
{"getfenv", db_getfenv},
{"gethook", db_gethook},
{"getinfo", db_getinfo},
{"getlocal", db_getlocal},
{"getmetatable", db_getmetatable},
{"getupvalue", db_getupvalue},
{"setfenv", db_setfenv},
{"sethook", db_sethook},
{"setlocal", db_setlocal},
{"setmetatable", db_setmetatable},
{"setupvalue", db_setupvalue},
{"traceback", db_errorfb},
{NULL, NULL}
};
LUALIB_API int luaopen_debug (lua_State *L) {
luaL_register(L, LUA_DBLIBNAME, dblib);
return 1;
}
+621
View File
@@ -0,0 +1,621 @@
/*
** $Id: ldebug.c,v 2.25 2005/07/11 13:59:03 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#define ldebug_c
#define LUA_CORE
#include "lua.h"
#include "lapi.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
static int currentpc (lua_State *L, CallInfo *ci) {
if (!isLua(ci)) return -1; /* function is not a Lua function? */
if (ci == L->ci)
ci->savedpc = L->savedpc;
return pcRel(ci->savedpc, ci_func(ci)->l.p);
}
static int currentline (lua_State *L, CallInfo *ci) {
int pc = currentpc(L, ci);
if (pc < 0)
return -1; /* only active lua functions have current-line information */
else
return getline(ci_func(ci)->l.p, pc);
}
/*
** this function can be called asynchronous (e.g. during a signal)
*/
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
if (func == NULL || mask == 0) { /* turn off hooks? */
mask = 0;
func = NULL;
}
L->hook = func;
L->basehookcount = count;
resethookcount(L);
L->hookmask = cast(lu_byte, mask);
return 1;
}
LUA_API lua_Hook lua_gethook (lua_State *L) {
return L->hook;
}
LUA_API int lua_gethookmask (lua_State *L) {
return L->hookmask;
}
LUA_API int lua_gethookcount (lua_State *L) {
return L->basehookcount;
}
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
int status;
CallInfo *ci;
lua_lock(L);
for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
level--;
if (f_isLua(ci)) /* Lua function? */
level -= ci->tailcalls; /* skip lost tail calls */
}
if (level == 0 && ci > L->base_ci) { /* level found? */
status = 1;
ar->i_ci = cast(int, ci - L->base_ci);
}
else if (level < 0) { /* level is of a lost tail call? */
status = 1;
ar->i_ci = 0;
}
else status = 0; /* no such level */
lua_unlock(L);
return status;
}
static Proto *getluaproto (CallInfo *ci) {
return (isLua(ci) ? ci_func(ci)->l.p : NULL);
}
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
CallInfo *ci;
Proto *fp;
lua_lock(L);
name = NULL;
ci = L->base_ci + ar->i_ci;
fp = getluaproto(ci);
if (fp) { /* is a Lua function? */
name = luaF_getlocalname(fp, n, currentpc(L, ci));
if (name)
luaA_pushobject(L, ci->base+(n-1)); /* push value */
}
lua_unlock(L);
return name;
}
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
CallInfo *ci;
Proto *fp;
lua_lock(L);
name = NULL;
ci = L->base_ci + ar->i_ci;
fp = getluaproto(ci);
L->top--; /* pop new value */
if (fp) { /* is a Lua function? */
name = luaF_getlocalname(fp, n, currentpc(L, ci));
if (!name || name[0] == '(') /* `(' starts private locals */
name = NULL;
else
setobjs2s(L, ci->base+(n-1), L->top);
}
lua_unlock(L);
return name;
}
static void funcinfo (lua_Debug *ar, Closure *cl) {
if (cl->c.isC) {
ar->source = "=[C]";
ar->linedefined = -1;
ar->lastlinedefined = -1;
ar->what = "C";
}
else {
ar->source = getstr(cl->l.p->source);
ar->linedefined = cl->l.p->linedefined;
ar->lastlinedefined = cl->l.p->lastlinedefined;
ar->what = (ar->linedefined == 0) ? "main" : "Lua";
}
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
}
static void info_tailcall (lua_Debug *ar) {
ar->name = ar->namewhat = "";
ar->what = "tail";
ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
ar->source = "=(tail call)";
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
ar->nups = 0;
}
static void collectvalidlines (lua_State *L, Closure *f) {
if (f == NULL || f->c.isC) {
setnilvalue(L->top);
}
else {
Table *t = luaH_new(L, 0, 0);
int *lineinfo = f->l.p->lineinfo;
int i;
for (i=0; i<f->l.p->sizelineinfo; i++)
setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
sethvalue(L, L->top, t);
}
incr_top(L);
}
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) {
int status = 1;
if (f == NULL) {
info_tailcall(ar);
return status;
}
for (; *what; what++) {
switch (*what) {
case 'S': {
funcinfo(ar, f);
break;
}
case 'l': {
ar->currentline = (ci) ? currentline(L, ci) : -1;
break;
}
case 'u': {
ar->nups = f->c.nupvalues;
break;
}
case 'n': {
ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */
ar->name = NULL;
}
break;
}
case 'L':
case 'f': /* handled by lua_getinfo */
break;
default: status = 0; /* invalid option */
}
}
return status;
}
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
int status;
Closure *f = NULL;
CallInfo *ci = NULL;
lua_lock(L);
if (*what == '>') {
StkId func = L->top - 1;
luai_apicheck(L, ttisfunction(func));
what++; /* skip the '>' */
f = clvalue(func);
L->top--; /* pop function */
}
else if (ar->i_ci != 0) { /* no tail call? */
ci = L->base_ci + ar->i_ci;
lua_assert(ttisfunction(ci->func));
f = clvalue(ci->func);
}
status = auxgetinfo(L, what, ar, f, ci);
if (strchr(what, 'f')) {
if (f == NULL) setnilvalue(L->top);
else setclvalue(L, L->top, f);
incr_top(L);
}
if (strchr(what, 'L'))
collectvalidlines(L, f);
lua_unlock(L);
return status;
}
/*
** {======================================================
** Symbolic Execution and code checker
** =======================================================
*/
#define check(x) if (!(x)) return 0;
#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
static int precheck (const Proto *pt) {
check(pt->maxstacksize <= MAXSTACK);
lua_assert(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
lua_assert(!(pt->is_vararg & VARARG_NEEDSARG) ||
(pt->is_vararg & VARARG_HASARG));
check(pt->sizeupvalues <= pt->nups);
check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
return 1;
}
#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
int luaG_checkopenop (Instruction i) {
switch (GET_OPCODE(i)) {
case OP_CALL:
case OP_TAILCALL:
case OP_RETURN:
case OP_SETLIST: {
check(GETARG_B(i) == 0);
return 1;
}
default: return 0; /* invalid instruction after an open call */
}
}
static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
switch (mode) {
case OpArgN: check(r == 0); break;
case OpArgU: break;
case OpArgR: checkreg(pt, r); break;
case OpArgK:
check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
break;
}
return 1;
}
static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
int pc;
int last; /* stores position of last instruction that changed `reg' */
last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
check(precheck(pt));
for (pc = 0; pc < lastpc; pc++) {
const Instruction i = pt->code[pc];
OpCode op = GET_OPCODE(i);
int a = GETARG_A(i);
int b = 0;
int c = 0;
check(op < NUM_OPCODES);
checkreg(pt, a);
switch (getOpMode(op)) {
case iABC: {
b = GETARG_B(i);
c = GETARG_C(i);
check(checkArgMode(pt, b, getBMode(op)));
check(checkArgMode(pt, c, getCMode(op)));
break;
}
case iABx: {
b = GETARG_Bx(i);
if (getBMode(op) == OpArgK) check(b < pt->sizek);
break;
}
case iAsBx: {
b = GETARG_sBx(i);
if (getBMode(op) == OpArgR) {
int dest = pc+1+b;
check(0 <= dest && dest < pt->sizecode);
if (dest > 0) {
/* cannot jump to a setlist count */
const Instruction d = pt->code[dest-1];
check(!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0));
}
}
break;
}
}
if (testAMode(op)) {
if (a == reg) last = pc; /* change register `a' */
}
if (testTMode(op)) {
check(pc+2 < pt->sizecode); /* check skip */
check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
}
switch (op) {
case OP_LOADBOOL: {
check(c == 0 || pc+2 < pt->sizecode); /* check its jump */
break;
}
case OP_LOADNIL: {
if (a <= reg && reg <= b)
last = pc; /* set registers from `a' to `b' */
break;
}
case OP_GETUPVAL:
case OP_SETUPVAL: {
check(b < pt->nups);
break;
}
case OP_GETGLOBAL:
case OP_SETGLOBAL: {
check(ttisstring(&pt->k[b]));
break;
}
case OP_SELF: {
checkreg(pt, a+1);
if (reg == a+1) last = pc;
break;
}
case OP_CONCAT: {
check(b < c); /* at least two operands */
break;
}
case OP_TFORLOOP: {
check(c >= 1); /* at least one result (control variable) */
checkreg(pt, a+2+c); /* space for results */
if (reg >= a+2) last = pc; /* affect all regs above its base */
break;
}
case OP_FORLOOP:
case OP_FORPREP:
checkreg(pt, a+3);
/* go through */
case OP_JMP: {
int dest = pc+1+b;
/* not full check and jump is forward and do not skip `lastpc'? */
if (reg != NO_REG && pc < dest && dest <= lastpc)
pc += b; /* do the jump */
break;
}
case OP_CALL:
case OP_TAILCALL: {
if (b != 0) {
checkreg(pt, a+b-1);
}
c--; /* c = num. returns */
if (c == LUA_MULTRET) {
check(checkopenop(pt, pc));
}
else if (c != 0)
checkreg(pt, a+c-1);
if (reg >= a) last = pc; /* affect all registers above base */
break;
}
case OP_RETURN: {
b--; /* b = num. returns */
if (b > 0) checkreg(pt, a+b-1);
break;
}
case OP_SETLIST: {
if (b > 0) checkreg(pt, a + b);
if (c == 0) pc++;
break;
}
case OP_CLOSURE: {
int nup;
check(b < pt->sizep);
nup = pt->p[b]->nups;
check(pc + nup < pt->sizecode);
for (; nup>0; nup--) {
OpCode op1 = GET_OPCODE(pt->code[pc+nup]);
check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
}
break;
}
case OP_VARARG: {
check((pt->is_vararg & VARARG_ISVARARG) &&
!(pt->is_vararg & VARARG_NEEDSARG));
b--;
if (b == LUA_MULTRET) check(checkopenop(pt, pc));
checkreg(pt, a+b-1);
break;
}
default: break;
}
}
return pt->code[last];
}
#undef check
#undef checkjump
#undef checkreg
/* }====================================================== */
int luaG_checkcode (const Proto *pt) {
return (symbexec(pt, pt->sizecode, NO_REG) != 0);
}
static const char *kname (Proto *p, int c) {
if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
return svalue(&p->k[INDEXK(c)]);
else
return "?";
}
static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
const char **name) {
if (isLua(ci)) { /* a Lua function? */
Proto *p = ci_func(ci)->l.p;
int pc = currentpc(L, ci);
Instruction i;
*name = luaF_getlocalname(p, stackpos+1, pc);
if (*name) /* is a local? */
return "local";
i = symbexec(p, pc, stackpos); /* try symbolic execution */
lua_assert(pc != -1);
switch (GET_OPCODE(i)) {
case OP_GETGLOBAL: {
int g = GETARG_Bx(i); /* global index */
lua_assert(ttisstring(&p->k[g]));
*name = svalue(&p->k[g]);
return "global";
}
case OP_MOVE: {
int a = GETARG_A(i);
int b = GETARG_B(i); /* move from `b' to `a' */
if (b < a)
return getobjname(L, ci, b, name); /* get name for `b' */
break;
}
case OP_GETTABLE: {
int k = GETARG_C(i); /* key index */
*name = kname(p, k);
return "field";
}
case OP_GETUPVAL: {
int u = GETARG_B(i); /* upvalue index */
*name = p->upvalues ? getstr(p->upvalues[u]) : "?";
return "upvalue";
}
case OP_SELF: {
int k = GETARG_C(i); /* key index */
*name = kname(p, k);
return "method";
}
default: break;
}
}
return NULL; /* no useful name found */
}
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
Instruction i;
if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
return NULL; /* calling function is not Lua (or is unknown) */
ci--; /* calling function */
i = ci_func(ci)->l.p->code[currentpc(L, ci)];
if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
GET_OPCODE(i) == OP_TFORLOOP)
return getobjname(L, ci, GETARG_A(i), name);
else
return NULL; /* no useful name can be found */
}
/* only ANSI way to check whether a pointer points to an array */
static int isinstack (CallInfo *ci, const TValue *o) {
StkId p;
for (p = ci->base; p < ci->top; p++)
if (o == p) return 1;
return 0;
}
void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
const char *name = NULL;
const char *t = luaT_typenames[ttype(o)];
const char *kind = (isinstack(L->ci, o)) ?
getobjname(L, L->ci, cast(int, o - L->base), &name) :
NULL;
if (kind)
luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
op, kind, name, t);
else
luaG_runerror(L, "attempt to %s a %s value", op, t);
}
void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
if (ttisstring(p1)) p1 = p2;
lua_assert(!ttisstring(p1));
luaG_typeerror(L, p1, "concatenate");
}
void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
TValue temp;
if (luaV_tonumber(p1, &temp) == NULL)
p2 = p1; /* first operand is wrong */
luaG_typeerror(L, p2, "perform arithmetic on");
}
int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = luaT_typenames[ttype(p1)];
const char *t2 = luaT_typenames[ttype(p2)];
if (t1[2] == t2[2])
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
return 0;
}
static void addinfo (lua_State *L, const char *msg) {
CallInfo *ci = L->ci;
if (isLua(ci)) { /* is Lua code? */
char buff[LUA_IDSIZE]; /* add file:line information */
int line = currentline(L, ci);
luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
}
}
void luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
setobjs2s(L, L->top, L->top - 1); /* move argument */
setobjs2s(L, L->top - 1, errfunc); /* push function */
incr_top(L);
luaD_call(L, L->top - 2, 1); /* call it */
}
luaD_throw(L, LUA_ERRRUN);
}
void luaG_runerror (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
addinfo(L, luaO_pushvfstring(L, fmt, argp));
va_end(argp);
luaG_errormsg(L);
}
+33
View File
@@ -0,0 +1,33 @@
/*
** $Id: ldebug.h,v 2.2 2004/06/02 19:07:55 roberto Exp roberto $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
#ifndef ldebug_h
#define ldebug_h
#include "lstate.h"
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
#define resethookcount(L) (L->hookcount = L->basehookcount)
LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
const char *opname);
LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaG_errormsg (lua_State *L);
LUAI_FUNC int luaG_checkcode (const Proto *pt);
LUAI_FUNC int luaG_checkopenop (Instruction i);
#endif
+514
View File
@@ -0,0 +1,514 @@
/*
** $Id: ldo.c,v 2.32 2005/08/24 16:15:49 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
#define ldo_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lundump.h"
#include "lvm.h"
#include "lzio.h"
/*
** {======================================================
** Error-recovery functions
** =======================================================
*/
/* chain list of long jump buffers */
struct lua_longjmp {
struct lua_longjmp *previous;
luai_jmpbuf b;
volatile int status; /* error code */
};
void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
switch (errcode) {
case LUA_ERRMEM: {
setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
break;
}
case LUA_ERRERR: {
setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
break;
}
case LUA_ERRSYNTAX:
case LUA_ERRRUN: {
setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
break;
}
}
L->top = oldtop + 1;
}
static void restore_stack_limit (lua_State *L) {
lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
int inuse = cast(int, L->ci - L->base_ci);
if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
luaD_reallocCI(L, LUAI_MAXCALLS);
}
}
static void resetstack (lua_State *L, int status) {
L->ci = L->base_ci;
L->base = L->ci->base;
luaF_close(L, L->base); /* close eventual pending closures */
luaD_seterrorobj(L, status, L->base);
L->nCcalls = 0;
L->allowhook = 1;
restore_stack_limit(L);
L->errfunc = 0;
L->errorJmp = NULL;
}
void luaD_throw (lua_State *L, int errcode) {
if (L->errorJmp) {
L->errorJmp->status = errcode;
LUAI_THROW(L, L->errorJmp);
}
else {
L->status = cast(lu_byte, errcode);
if (G(L)->panic) {
resetstack(L, errcode);
lua_unlock(L);
G(L)->panic(L);
}
exit(EXIT_FAILURE);
}
}
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
struct lua_longjmp lj;
lj.status = 0;
lj.previous = L->errorJmp; /* chain new error handler */
L->errorJmp = &lj;
LUAI_TRY(L, &lj,
(*f)(L, ud);
);
L->errorJmp = lj.previous; /* restore old error handler */
return lj.status;
}
/* }====================================================== */
static void correctstack (lua_State *L, TValue *oldstack) {
CallInfo *ci;
GCObject *up;
L->top = (L->top - oldstack) + L->stack;
for (up = L->openupval; up != NULL; up = up->gch.next)
gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
for (ci = L->base_ci; ci <= L->ci; ci++) {
ci->top = (ci->top - oldstack) + L->stack;
ci->base = (ci->base - oldstack) + L->stack;
ci->func = (ci->func - oldstack) + L->stack;
}
L->base = (L->base - oldstack) + L->stack;
}
void luaD_reallocstack (lua_State *L, int newsize) {
TValue *oldstack = L->stack;
int realsize = newsize + 1 + EXTRA_STACK;
lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
L->stacksize = realsize;
L->stack_last = L->stack+newsize;
correctstack(L, oldstack);
}
void luaD_reallocCI (lua_State *L, int newsize) {
CallInfo *oldci = L->base_ci;
luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
L->size_ci = newsize;
L->ci = (L->ci - oldci) + L->base_ci;
L->end_ci = L->base_ci + L->size_ci - 1;
}
void luaD_growstack (lua_State *L, int n) {
if (n <= L->stacksize) /* double size is enough? */
luaD_reallocstack(L, 2*L->stacksize);
else
luaD_reallocstack(L, L->stacksize + n);
}
static CallInfo *growCI (lua_State *L) {
if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */
luaD_throw(L, LUA_ERRERR);
else {
luaD_reallocCI(L, 2*L->size_ci);
if (L->size_ci > LUAI_MAXCALLS)
luaG_runerror(L, "stack overflow");
}
return ++L->ci;
}
void luaD_callhook (lua_State *L, int event, int line) {
lua_Hook hook = L->hook;
if (hook && L->allowhook) {
ptrdiff_t top = savestack(L, L->top);
ptrdiff_t ci_top = savestack(L, L->ci->top);
lua_Debug ar;
ar.event = event;
ar.currentline = line;
if (event == LUA_HOOKTAILRET)
ar.i_ci = 0; /* tail call; no debug information about it */
else
ar.i_ci = cast(int, L->ci - L->base_ci);
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
L->ci->top = L->top + LUA_MINSTACK;
lua_assert(L->ci->top <= L->stack_last);
L->allowhook = 0; /* cannot call hooks inside a hook */
lua_unlock(L);
(*hook)(L, &ar);
lua_lock(L);
lua_assert(!L->allowhook);
L->allowhook = 1;
L->ci->top = restorestack(L, ci_top);
L->top = restorestack(L, top);
}
}
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
int i;
int nfixargs = p->numparams;
Table *htab = NULL;
StkId base, fixed;
for (; actual < nfixargs; ++actual)
setnilvalue(L->top++);
#if defined(LUA_COMPAT_VARARG)
if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
int nvar = actual - nfixargs; /* number of extra arguments */
lua_assert(p->is_vararg & VARARG_HASARG);
luaC_checkGC(L);
htab = luaH_new(L, nvar, 1); /* create `arg' table */
for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
/* store counter in field `n' */
setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")),
cast(lua_Number, nvar));
}
#endif
/* move fixed parameters to final position */
fixed = L->top - actual; /* first fixed argument */
base = L->top; /* final position of first argument */
for (i=0; i<nfixargs; i++) {
setobjs2s(L, L->top++, fixed+i);
setnilvalue(fixed+i);
}
/* add `arg' parameter */
if (htab) {
sethvalue(L, L->top++, htab);
lua_assert(iswhite(obj2gco(htab)));
}
return base;
}
static StkId tryfuncTM (lua_State *L, StkId func) {
const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
StkId p;
ptrdiff_t funcr = savestack(L, func);
if (!ttisfunction(tm))
luaG_typeerror(L, func, "call");
/* Open a hole inside the stack at `func' */
for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
incr_top(L);
func = restorestack(L, funcr); /* previous call may change stack */
setobj2s(L, func, tm); /* tag method is the new function to be called */
return func;
}
#define inc_ci(L) \
((L->ci == L->end_ci) ? growCI(L) : \
(condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
int luaD_precall (lua_State *L, StkId func, int nresults) {
LClosure *cl;
ptrdiff_t funcr;
if (!ttisfunction(func)) /* `func' is not a function? */
func = tryfuncTM(L, func); /* check the `function' tag method */
funcr = savestack(L, func);
cl = &clvalue(func)->l;
L->ci->savedpc = L->savedpc;
if (!cl->isC) { /* Lua function? prepare its call */
CallInfo *ci;
StkId st, base;
Proto *p = cl->p;
luaD_checkstack(L, p->maxstacksize);
func = restorestack(L, funcr);
if (!p->is_vararg) /* no varargs? */
base = func + 1;
else { /* vararg function */
int nargs = cast(int, L->top - func) - 1;
base = adjust_varargs(L, p, nargs);
func = restorestack(L, funcr); /* previous call may change the stack */
}
ci = inc_ci(L); /* now `enter' new function */
ci->func = func;
L->base = ci->base = base;
ci->top = L->base + p->maxstacksize;
lua_assert(ci->top <= L->stack_last);
L->savedpc = p->code; /* starting point */
ci->tailcalls = 0;
ci->nresults = nresults;
for (st = L->top; st < ci->top; st++)
setnilvalue(st);
L->top = ci->top;
if (L->hookmask & LUA_MASKCALL) {
L->savedpc++; /* hooks assume 'pc' is already incremented */
luaD_callhook(L, LUA_HOOKCALL, -1);
L->savedpc--; /* correct 'pc' */
}
return PCRLUA;
}
else { /* if is a C function, call it */
CallInfo *ci;
int n;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci = inc_ci(L); /* now `enter' new function */
ci->func = restorestack(L, funcr);
L->base = ci->base = ci->func + 1;
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
ci->nresults = nresults;
if (L->hookmask & LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*curr_func(L)->c.f)(L); /* do the actual call */
lua_lock(L);
if (n >= 0) { /* no yielding? */
luaD_poscall(L, L->top - n);
return PCRC;
}
else {
ci->nresults = nresults;
return PCRYIELD;
}
}
}
static StkId callrethooks (lua_State *L, StkId firstResult) {
ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
luaD_callhook(L, LUA_HOOKRET, -1);
if (f_isLua(L->ci)) { /* Lua function? */
while (L->ci->tailcalls--) /* call hook for eventual tail calls */
luaD_callhook(L, LUA_HOOKTAILRET, -1);
}
return restorestack(L, fr);
}
int luaD_poscall (lua_State *L, StkId firstResult) {
StkId res;
int wanted, i;
CallInfo *ci;
if (L->hookmask & LUA_MASKRET)
firstResult = callrethooks(L, firstResult);
ci = L->ci--;
res = ci->func; /* res == final position of 1st result */
wanted = ci->nresults;
L->base = (ci - 1)->base; /* restore base */
L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
/* move results to correct place */
for (i = wanted; i != 0 && firstResult < L->top; i--)
setobjs2s(L, res++, firstResult++);
while (i-- > 0)
setnilvalue(res++);
L->top = res;
return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
}
/*
** Call a function (C or Lua). The function to be called is at *func.
** The arguments are on the stack, right after the function.
** When returns, all the results are on the stack, starting at the original
** function position.
*/
void luaD_call (lua_State *L, StkId func, int nResults) {
if (++L->nCcalls >= LUAI_MAXCCALLS) {
if (L->nCcalls == LUAI_MAXCCALLS)
luaG_runerror(L, "C stack overflow");
else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
luaV_execute(L, 1); /* call it */
L->nCcalls--;
luaC_checkGC(L);
}
static void resume (lua_State *L, void *ud) {
StkId firstArg = cast(StkId, ud);
CallInfo *ci = L->ci;
if (L->status != LUA_YIELD) { /* start coroutine */
lua_assert(ci == L->base_ci && firstArg > L->base);
if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
return;
}
else { /* resuming from previous yield */
if (!f_isLua(ci)) { /* `common' yield? */
/* finish interrupted execution of `OP_CALL' */
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
if (luaD_poscall(L, firstArg)) /* complete it... */
L->top = L->ci->top; /* and correct top if not multiple results */
}
else /* yielded inside a hook: just continue its execution */
L->base = L->ci->base;
}
L->status = 0;
luaV_execute(L, cast(int, L->ci - L->base_ci));
}
static int resume_error (lua_State *L, const char *msg) {
L->top = L->ci->base;
setsvalue2s(L, L->top, luaS_new(L, msg));
incr_top(L);
lua_unlock(L);
return LUA_ERRRUN;
}
LUA_API int lua_resume (lua_State *L, int nargs) {
int status;
lua_lock(L);
if (L->status != LUA_YIELD) {
if (L->status != 0)
return resume_error(L, "cannot resume dead coroutine");
else if (L->ci != L->base_ci)
return resume_error(L, "cannot resume non-suspended coroutine");
}
luai_userstateresume(L, nargs);
lua_assert(L->errfunc == 0 && L->nCcalls == 0);
status = luaD_rawrunprotected(L, resume, L->top - nargs);
if (status != 0) { /* error? */
L->status = cast(lu_byte, status); /* mark thread as `dead' */
luaD_seterrorobj(L, status, L->top);
}
else
status = L->status;
lua_unlock(L);
return status;
}
LUA_API int lua_yield (lua_State *L, int nresults) {
luai_userstateyield(L, nresults);
lua_lock(L);
if (L->nCcalls > 0)
luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
L->base = L->top - nresults; /* protect stack slots below */
L->status = LUA_YIELD;
lua_unlock(L);
return -1;
}
int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t old_top, ptrdiff_t ef) {
int status;
unsigned short oldnCcalls = L->nCcalls;
ptrdiff_t old_ci = saveci(L, L->ci);
lu_byte old_allowhooks = L->allowhook;
ptrdiff_t old_errfunc = L->errfunc;
L->errfunc = ef;
status = luaD_rawrunprotected(L, func, u);
if (status != 0) { /* an error occurred? */
StkId oldtop = restorestack(L, old_top);
luaF_close(L, oldtop); /* close eventual pending closures */
luaD_seterrorobj(L, status, oldtop);
L->nCcalls = oldnCcalls;
L->ci = restoreci(L, old_ci);
L->base = L->ci->base;
L->savedpc = L->ci->savedpc;
L->allowhook = old_allowhooks;
restore_stack_limit(L);
}
L->errfunc = old_errfunc;
return status;
}
/*
** Execute a protected parser.
*/
struct SParser { /* data to `f_parser' */
ZIO *z;
Mbuffer buff; /* buffer to be used by the scanner */
const char *name;
};
static void f_parser (lua_State *L, void *ud) {
int i;
Proto *tf;
Closure *cl;
struct SParser *p = cast(struct SParser *, ud);
int c = luaZ_lookahead(p->z);
luaC_checkGC(L);
tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
&p->buff, p->name);
cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
cl->l.p = tf;
for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
cl->l.upvals[i] = luaF_newupval(L);
setclvalue(L, L->top, cl);
incr_top(L);
}
int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
struct SParser p;
int status;
p.z = z; p.name = name;
luaZ_initbuffer(L, &p.buff);
status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
luaZ_freebuffer(L, &p.buff);
return status;
}
+57
View File
@@ -0,0 +1,57 @@
/*
** $Id: ldo.h,v 2.6 2005/08/22 19:58:29 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
#ifndef ldo_h
#define ldo_h
#include "lobject.h"
#include "lstate.h"
#include "lzio.h"
#define luaD_checkstack(L,n) \
if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
luaD_growstack(L, n); \
else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
#define savestack(L,p) ((char *)(p) - (char *)L->stack)
#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
/* results from luaD_precall */
#define PCRLUA 0 /* initiated a call to a Lua function */
#define PCRC 1 /* did a call to a C function */
#define PCRYIELD 2 /* C funtion yielded */
/* type of protected functions, to be ran by `runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line);
LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);
LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
#endif
+179
View File
@@ -0,0 +1,179 @@
/*
** $Id: ldump.c,v 2.5 2005/05/05 20:47:02 roberto Exp roberto $
** save pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define ldump_c
#define LUA_CORE
#include "lua.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lundump.h"
#define DumpVector(b,n,size,D) DumpBlock(b,(n)*(size),D)
#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D)
typedef struct {
lua_State* L;
lua_Writer writer;
void* data;
int strip;
int status;
} DumpState;
static void DumpBlock(const void* b, size_t size, DumpState* D)
{
if (D->status==0)
{
lua_unlock(D->L);
D->status=(*D->writer)(D->L,b,size,D->data);
lua_lock(D->L);
}
}
static void DumpByte(int y, DumpState* D)
{
char x=(char)y;
DumpBlock(&x,sizeof(x),D);
}
static void DumpInt(int x, DumpState* D)
{
DumpBlock(&x,sizeof(x),D);
}
static void DumpSize(size_t x, DumpState* D)
{
DumpBlock(&x,sizeof(x),D);
}
static void DumpNumber(lua_Number x, DumpState* D)
{
DumpBlock(&x,sizeof(x),D);
}
static void DumpString(const TString* s, DumpState* D)
{
if (s==NULL || getstr(s)==NULL)
DumpSize(0,D);
else
{
size_t size=s->tsv.len+1; /* include trailing '\0' */
DumpSize(size,D);
DumpBlock(getstr(s),size,D);
}
}
static void DumpCode(const Proto* f, DumpState* D)
{
DumpInt(f->sizecode,D);
DumpVector(f->code,f->sizecode,sizeof(*f->code),D);
}
static void DumpLocals(const Proto* f, DumpState* D)
{
int i,n=f->sizelocvars;
DumpInt(n,D);
for (i=0; i<n; i++)
{
DumpString(f->locvars[i].varname,D);
DumpInt(f->locvars[i].startpc,D);
DumpInt(f->locvars[i].endpc,D);
}
}
static void DumpLines(const Proto* f, DumpState* D)
{
DumpInt(f->sizelineinfo,D);
DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
}
static void DumpUpvalues(const Proto* f, DumpState* D)
{
int i,n=f->sizeupvalues;
DumpInt(n,D);
for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
}
static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
static void DumpConstants(const Proto* f, DumpState* D)
{
int i,n;
DumpInt(n=f->sizek,D);
for (i=0; i<n; i++)
{
const TValue* o=&f->k[i];
DumpByte(ttype(o),D);
switch (ttype(o))
{
case LUA_TNUMBER:
DumpNumber(nvalue(o),D);
break;
case LUA_TSTRING:
DumpString(rawtsvalue(o),D);
break;
case LUA_TNIL:
break;
case LUA_TBOOLEAN:
DumpByte(bvalue(o),D);
break;
default:
lua_assert(0); /* cannot happen */
break;
}
}
DumpInt(n=f->sizep,D);
for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
}
static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
{
DumpString((f->source==p) ? NULL : f->source,D);
DumpInt(f->linedefined,D);
DumpInt(f->lastlinedefined,D);
DumpByte(f->nups,D);
DumpByte(f->numparams,D);
DumpByte(f->is_vararg,D);
DumpByte(f->maxstacksize,D);
if (D->strip) DumpInt(0,D); else DumpLines(f,D);
if (D->strip) DumpInt(0,D); else DumpLocals(f,D);
if (D->strip) DumpInt(0,D); else DumpUpvalues(f,D);
DumpConstants(f,D);
DumpCode(f,D);
}
static void DumpHeader(DumpState* D)
{
DumpLiteral(LUA_SIGNATURE,D);
DumpByte(VERSION,D);
DumpByte(luaU_endianness(),D);
DumpByte(sizeof(int),D);
DumpByte(sizeof(size_t),D);
DumpByte(sizeof(Instruction),D);
DumpByte(sizeof(lua_Number),D);
DumpNumber(TEST_NUMBER,D);
}
/*
** dump Lua function as precompiled chunk
*/
int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data,
int strip)
{
DumpState D;
D.L=L;
D.writer=w;
D.data=data;
D.strip=strip;
D.status=0;
DumpHeader(&D);
DumpFunction(f,NULL,&D);
return D.status;
}
-233
View File
@@ -1,233 +0,0 @@
char *rcs_lex = "$Id: lex.c,v 1.3 1993/12/28 16:42:29 roberto Exp celes $";
/*$Log: lex.c,v $
* Revision 1.3 1993/12/28 16:42:29 roberto
* "include"s de string.h e stdlib.h para evitar warnings
*
* Revision 1.2 1993/12/22 21:39:15 celes
* Tratamento do token $debug e $nodebug
*
* Revision 1.1 1993/12/22 21:15:16 roberto
* Initial revision
**/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "y.tab.h"
#define next() { current = input(); }
#define save(x) { *yytextLast++ = (x); }
#define save_and_next() { save(current); next(); }
static int current;
static char yytext[256];
static char *yytextLast;
static Input input;
void lua_setinput (Input fn)
{
current = ' ';
input = fn;
}
char *lua_lasttext (void)
{
*yytextLast = 0;
return yytext;
}
static struct
{
char *name;
int token;
} reserved [] = {
{"and", AND},
{"do", DO},
{"else", ELSE},
{"elseif", ELSEIF},
{"end", END},
{"function", FUNCTION},
{"if", IF},
{"local", LOCAL},
{"nil", NIL},
{"not", NOT},
{"or", OR},
{"repeat", REPEAT},
{"return", RETURN},
{"then", THEN},
{"until", UNTIL},
{"while", WHILE} };
#define RESERVEDSIZE (sizeof(reserved)/sizeof(reserved[0]))
int findReserved (char *name)
{
int l = 0;
int h = RESERVEDSIZE - 1;
while (l <= h)
{
int m = (l+h)/2;
int comp = strcmp(name, reserved[m].name);
if (comp < 0)
h = m-1;
else if (comp == 0)
return reserved[m].token;
else
l = m+1;
}
return 0;
}
int yylex ()
{
while (1)
{
yytextLast = yytext;
switch (current)
{
case '\n': lua_linenumber++;
case ' ':
case '\t':
next();
continue;
case '$':
next();
while (isalnum(current) || current == '_')
save_and_next();
*yytextLast = 0;
if (strcmp(yytext, "debug") == 0)
{
yylval.vInt = 1;
return DEBUG;
}
else if (strcmp(yytext, "nodebug") == 0)
{
yylval.vInt = 0;
return DEBUG;
}
return WRONGTOKEN;
case '-':
save_and_next();
if (current != '-') return '-';
do { next(); } while (current != '\n' && current != 0);
continue;
case '<':
save_and_next();
if (current != '=') return '<';
else { save_and_next(); return LE; }
case '>':
save_and_next();
if (current != '=') return '>';
else { save_and_next(); return GE; }
case '~':
save_and_next();
if (current != '=') return '~';
else { save_and_next(); return NE; }
case '"':
case '\'':
{
int del = current;
next(); /* skip the delimiter */
while (current != del)
{
switch (current)
{
case 0:
case '\n':
return WRONGTOKEN;
case '\\':
next(); /* do not save the '\' */
switch (current)
{
case 'n': save('\n'); next(); break;
case 't': save('\t'); next(); break;
case 'r': save('\r'); next(); break;
default : save('\\'); break;
}
break;
default:
save_and_next();
}
}
next(); /* skip the delimiter */
*yytextLast = 0;
yylval.vWord = lua_findconstant (yytext);
return STRING;
}
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case '_':
{
int res;
do { save_and_next(); } while (isalnum(current) || current == '_');
*yytextLast = 0;
res = findReserved(yytext);
if (res) return res;
yylval.pChar = yytext;
return NAME;
}
case '.':
save_and_next();
if (current == '.')
{
save_and_next();
return CONC;
}
else if (!isdigit(current)) return '.';
/* current is a digit: goes through to number */
goto fraction;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
do { save_and_next(); } while (isdigit(current));
if (current == '.') save_and_next();
fraction: while (isdigit(current)) save_and_next();
if (current == 'e' || current == 'E')
{
save_and_next();
if (current == '+' || current == '-') save_and_next();
if (!isdigit(current)) return WRONGTOKEN;
do { save_and_next(); } while (isdigit(current));
}
*yytextLast = 0;
yylval.vFloat = atof(yytext);
return NUMBER;
default: /* also end of file */
{
save_and_next();
return *yytext;
}
}
}
}
+174
View File
@@ -0,0 +1,174 @@
/*
** $Id: lfunc.c,v 2.10 2005/04/29 13:54:05 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define lfunc_c
#define LUA_CORE
#include "lua.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
luaC_link(L, obj2gco(c), LUA_TFUNCTION);
c->c.isC = 1;
c->c.env = e;
c->c.nupvalues = cast(lu_byte, nelems);
return c;
}
Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
luaC_link(L, obj2gco(c), LUA_TFUNCTION);
c->l.isC = 0;
c->l.env = e;
c->l.nupvalues = cast(lu_byte, nelems);
while (nelems--) c->l.upvals[nelems] = NULL;
return c;
}
UpVal *luaF_newupval (lua_State *L) {
UpVal *uv = luaM_new(L, UpVal);
luaC_link(L, obj2gco(uv), LUA_TUPVAL);
uv->v = &uv->u.value;
setnilvalue(uv->v);
return uv;
}
UpVal *luaF_findupval (lua_State *L, StkId level) {
global_State *g = G(L);
GCObject **pp = &L->openupval;
UpVal *p;
UpVal *uv;
while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
lua_assert(p->v != &p->u.value);
if (p->v == level) { /* found a corresponding upvalue? */
if (isdead(g, obj2gco(p))) /* is it dead? */
changewhite(obj2gco(p)); /* ressurect it */
return p;
}
pp = &p->next;
}
uv = luaM_new(L, UpVal); /* not found: create a new one */
uv->tt = LUA_TUPVAL;
uv->marked = luaC_white(g);
uv->v = level; /* current value lives in the stack */
uv->next = *pp; /* chain it in the proper position */
*pp = obj2gco(uv);
uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
uv->u.l.next = g->uvhead.u.l.next;
uv->u.l.next->u.l.prev = uv;
g->uvhead.u.l.next = uv;
lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
return uv;
}
static void unlinkupval (UpVal *uv) {
lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
uv->u.l.prev->u.l.next = uv->u.l.next;
}
void luaF_freeupval (lua_State *L, UpVal *uv) {
if (uv->v != &uv->u.value) /* is it open? */
unlinkupval(uv); /* remove from open list */
luaM_free(L, uv); /* free upvalue */
}
void luaF_close (lua_State *L, StkId level) {
UpVal *uv;
global_State *g = G(L);
while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) {
GCObject *o = obj2gco(uv);
lua_assert(!isblack(o) && uv->v != &uv->u.value);
L->openupval = uv->next; /* remove from `open' list */
if (isdead(g, o))
luaF_freeupval(L, uv); /* free upvalue */
else {
unlinkupval(uv);
setobj(L, &uv->u.value, uv->v);
uv->v = &uv->u.value; /* now current value lives here */
luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
}
}
}
Proto *luaF_newproto (lua_State *L) {
Proto *f = luaM_new(L, Proto);
luaC_link(L, obj2gco(f), LUA_TPROTO);
f->k = NULL;
f->sizek = 0;
f->p = NULL;
f->sizep = 0;
f->code = NULL;
f->sizecode = 0;
f->sizelineinfo = 0;
f->sizeupvalues = 0;
f->nups = 0;
f->upvalues = NULL;
f->numparams = 0;
f->is_vararg = 0;
f->maxstacksize = 0;
f->lineinfo = NULL;
f->sizelocvars = 0;
f->locvars = NULL;
f->linedefined = 0;
f->lastlinedefined = 0;
f->source = NULL;
return f;
}
void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->code, f->sizecode, Instruction);
luaM_freearray(L, f->p, f->sizep, Proto *);
luaM_freearray(L, f->k, f->sizek, TValue);
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
luaM_free(L, f);
}
void luaF_freeclosure (lua_State *L, Closure *c) {
int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
sizeLclosure(c->l.nupvalues);
luaM_freemem(L, c, size);
}
/*
** Look for n-th local variable at line `line' in function `func'.
** Returns NULL if not found.
*/
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
int i;
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
if (pc < f->locvars[i].endpc) { /* is variable active? */
local_number--;
if (local_number == 0)
return getstr(f->locvars[i].varname);
}
}
return NULL; /* not found */
}
+34
View File
@@ -0,0 +1,34 @@
/*
** $Id: lfunc.h,v 2.3 2005/02/18 12:40:02 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
#ifndef lfunc_h
#define lfunc_h
#include "lobject.h"
#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
cast(int, sizeof(TValue)*((n)-1)))
#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
cast(int, sizeof(TValue *)*((n)-1)))
LUAI_FUNC Proto *luaF_newproto (lua_State *L);
LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
LUAI_FUNC void luaF_close (lua_State *L, StkId level);
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
int pc);
#endif
+708
View File
@@ -0,0 +1,708 @@
/*
** $Id: lgc.c,v 2.35 2005/08/04 13:37:38 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
#include <string.h>
#define lgc_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#define GCSTEPSIZE 1024u
#define GCSWEEPMAX 40
#define GCSWEEPCOST 10
#define GCFINALIZECOST 100
#define maskmarks \
cast(lu_byte, ~(bitmask(BLACKBIT)|WHITEBITS))
#define makewhite(g,x) \
((x)->gch.marked = ((x)->gch.marked & maskmarks) | luaC_white(g))
#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
#define KEYWEAK bitmask(KEYWEAKBIT)
#define VALUEWEAK bitmask(VALUEWEAKBIT)
#define markvalue(g,o) { checkconsistency(o); \
if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }
#define markobject(g,t) { if (iswhite(obj2gco(t))) \
reallymarkobject(g, obj2gco(t)); }
#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
static void removeentry (Node *n) {
lua_assert(ttisnil(gval(n)));
if (iscollectable(gkey(n)))
setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
}
static void reallymarkobject (global_State *g, GCObject *o) {
lua_assert(iswhite(o) && !isdead(g, o));
white2gray(o);
switch (o->gch.tt) {
case LUA_TSTRING: {
return;
}
case LUA_TUSERDATA: {
Table *mt = gco2u(o)->metatable;
gray2black(o); /* udata are never gray */
if (mt) markobject(g, mt);
markobject(g, gco2u(o)->env);
return;
}
case LUA_TUPVAL: {
UpVal *uv = gco2uv(o);
markvalue(g, uv->v);
if (uv->v == &uv->u.value) /* closed? */
gray2black(o); /* open upvalues are never black */
return;
}
case LUA_TFUNCTION: {
gco2cl(o)->c.gclist = g->gray;
g->gray = o;
break;
}
case LUA_TTABLE: {
gco2h(o)->gclist = g->gray;
g->gray = o;
break;
}
case LUA_TTHREAD: {
gco2th(o)->gclist = g->gray;
g->gray = o;
break;
}
case LUA_TPROTO: {
gco2p(o)->gclist = g->gray;
g->gray = o;
break;
}
default: lua_assert(0);
}
}
static void marktmu (global_State *g) {
GCObject *u = g->tmudata;
if (u) {
do {
u = u->gch.next;
makewhite(g, u); /* may be marked, if left from previous GC */
reallymarkobject(g, u);
} while (u != g->tmudata);
}
}
/* move `dead' udata that need finalization to list `tmudata' */
size_t luaC_separateudata (lua_State *L, int all) {
global_State *g = G(L);
size_t deadmem = 0;
GCObject **p = &g->mainthread->next;
GCObject *curr;
while ((curr = *p) != NULL) {
if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
p = &curr->gch.next; /* don't bother with them */
else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
markfinalized(gco2u(curr)); /* don't need finalization */
p = &curr->gch.next;
}
else { /* must call its gc method */
deadmem += sizeudata(gco2u(curr));
markfinalized(gco2u(curr));
*p = curr->gch.next;
/* link `curr' at the end of `tmudata' list */
if (g->tmudata == NULL) /* list is empty? */
g->tmudata = curr->gch.next = curr; /* creates a circular list */
else {
curr->gch.next = g->tmudata->gch.next;
g->tmudata->gch.next = curr;
g->tmudata = curr;
}
}
}
return deadmem;
}
static int traversetable (global_State *g, Table *h) {
int i;
int weakkey = 0;
int weakvalue = 0;
const TValue *mode;
if (h->metatable)
markobject(g, h->metatable);
mode = gfasttm(g, h->metatable, TM_MODE);
if (mode && ttisstring(mode)) { /* is there a weak mode? */
weakkey = (strchr(svalue(mode), 'k') != NULL);
weakvalue = (strchr(svalue(mode), 'v') != NULL);
if (weakkey || weakvalue) { /* is really weak? */
h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) |
(weakvalue << VALUEWEAKBIT));
h->gclist = g->weak; /* must be cleared after GC, ... */
g->weak = obj2gco(h); /* ... so put in the appropriate list */
}
}
if (weakkey && weakvalue) return 1;
if (!weakvalue) {
i = h->sizearray;
while (i--)
markvalue(g, &h->array[i]);
}
i = sizenode(h);
while (i--) {
Node *n = gnode(h, i);
lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
if (ttisnil(gval(n)))
removeentry(n); /* remove empty entries */
else {
lua_assert(!ttisnil(gkey(n)));
if (!weakkey) markvalue(g, gkey(n));
if (!weakvalue) markvalue(g, gval(n));
}
}
return weakkey || weakvalue;
}
/*
** All marks are conditional because a GC may happen while the
** prototype is still being created
*/
static void traverseproto (global_State *g, Proto *f) {
int i;
if (f->source) stringmark(f->source);
for (i=0; i<f->sizek; i++) /* mark literals */
markvalue(g, &f->k[i]);
for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
if (f->upvalues[i])
stringmark(f->upvalues[i]);
}
for (i=0; i<f->sizep; i++) { /* mark nested protos */
if (f->p[i])
markobject(g, f->p[i]);
}
for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
if (f->locvars[i].varname)
stringmark(f->locvars[i].varname);
}
}
static void traverseclosure (global_State *g, Closure *cl) {
markobject(g, cl->c.env);
if (cl->c.isC) {
int i;
for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
markvalue(g, &cl->c.upvalue[i]);
}
else {
int i;
lua_assert(cl->l.nupvalues == cl->l.p->nups);
markobject(g, cl->l.p);
for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
markobject(g, cl->l.upvals[i]);
}
}
static void checkstacksizes (lua_State *L, StkId max) {
int ci_used = cast(int, L->ci - L->base_ci); /* number of `ci' in use */
int s_used = cast(int, max - L->stack); /* part of stack in use */
if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */
return; /* do not touch the stacks */
if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
condhardstacktests(luaD_reallocCI(L, ci_used + 1));
if (4*s_used < L->stacksize &&
2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
condhardstacktests(luaD_reallocstack(L, s_used));
}
static void traversestack (global_State *g, lua_State *l) {
StkId o, lim;
CallInfo *ci;
markvalue(g, gt(l));
lim = l->top;
for (ci = l->base_ci; ci <= l->ci; ci++) {
lua_assert(ci->top <= l->stack_last);
if (lim < ci->top) lim = ci->top;
}
for (o = l->stack; o < l->top; o++)
markvalue(g, o);
for (; o <= lim; o++)
setnilvalue(o);
checkstacksizes(l, lim);
}
/*
** traverse one gray object, turning it to black.
** Returns `quantity' traversed.
*/
static l_mem propagatemark (global_State *g) {
GCObject *o = g->gray;
lua_assert(isgray(o));
gray2black(o);
switch (o->gch.tt) {
case LUA_TTABLE: {
Table *h = gco2h(o);
g->gray = h->gclist;
if (traversetable(g, h)) /* table is weak? */
black2gray(o); /* keep it gray */
return sizeof(Table) + sizeof(TValue) * h->sizearray +
sizeof(Node) * sizenode(h);
}
case LUA_TFUNCTION: {
Closure *cl = gco2cl(o);
g->gray = cl->c.gclist;
traverseclosure(g, cl);
return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
sizeLclosure(cl->l.nupvalues);
}
case LUA_TTHREAD: {
lua_State *th = gco2th(o);
g->gray = th->gclist;
th->gclist = g->grayagain;
g->grayagain = o;
black2gray(o);
traversestack(g, th);
return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
sizeof(CallInfo) * th->size_ci;
}
case LUA_TPROTO: {
Proto *p = gco2p(o);
g->gray = p->gclist;
traverseproto(g, p);
return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
sizeof(Proto *) * p->sizep +
sizeof(TValue) * p->sizek +
sizeof(int) * p->sizelineinfo +
sizeof(LocVar) * p->sizelocvars +
sizeof(TString *) * p->sizeupvalues;
}
default: lua_assert(0); return 0;
}
}
static void propagateall (global_State *g) {
while (g->gray) propagatemark(g);
}
/*
** The next function tells whether a key or value can be cleared from
** a weak table. Non-collectable objects are never removed from weak
** tables. Strings behave as `values', so are never removed too. for
** other objects: if really collected, cannot keep them; for userdata
** being finalized, keep them in keys, but not in values
*/
static int iscleared (const TValue *o, int iskey) {
if (!iscollectable(o)) return 0;
if (ttisstring(o)) {
stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
return 0;
}
return iswhite(gcvalue(o)) ||
(ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
}
/*
** clear collected entries from weaktables
*/
static void cleartable (GCObject *l) {
while (l) {
Table *h = gco2h(l);
int i = h->sizearray;
lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
testbit(h->marked, KEYWEAKBIT));
if (testbit(h->marked, VALUEWEAKBIT)) {
while (i--) {
TValue *o = &h->array[i];
if (iscleared(o, 0)) /* value was collected? */
setnilvalue(o); /* remove value */
}
}
i = sizenode(h);
while (i--) {
Node *n = gnode(h, i);
if (!ttisnil(gval(n)) && /* non-empty entry? */
(iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
setnilvalue(gval(n)); /* remove value ... */
removeentry(n); /* remove entry from table */
}
}
l = h->gclist;
}
}
static void freeobj (lua_State *L, GCObject *o) {
switch (o->gch.tt) {
case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
case LUA_TTHREAD: {
lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
luaE_freethread(L, gco2th(o));
break;
}
case LUA_TSTRING: {
G(L)->strt.nuse--;
luaM_freemem(L, o, sizestring(gco2ts(o)));
break;
}
case LUA_TUSERDATA: {
luaM_freemem(L, o, sizeudata(gco2u(o)));
break;
}
default: lua_assert(0);
}
}
#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
GCObject *curr;
global_State *g = G(L);
int deadmask = otherwhite(g);
while ((curr = *p) != NULL && count-- > 0) {
if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
sweepwholelist(L, &gco2th(curr)->openupval);
if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
makewhite(g, curr); /* make it white (for next cycle) */
p = &curr->gch.next;
}
else { /* must erase `curr' */
lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
*p = curr->gch.next;
if (curr == g->rootgc) /* is the first element of the list? */
g->rootgc = curr->gch.next; /* adjust first */
freeobj(L, curr);
}
}
return p;
}
static void checkSizes (lua_State *L) {
global_State *g = G(L);
/* check size of string hash */
if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
g->strt.size > MINSTRTABSIZE*2)
luaS_resize(L, g->strt.size/2); /* table is too big */
/* check size of buffer */
if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
luaZ_resizebuffer(L, &g->buff, newsize);
}
}
static void GCTM (lua_State *L) {
global_State *g = G(L);
GCObject *o = g->tmudata->gch.next; /* get first element */
Udata *udata = rawgco2u(o);
const TValue *tm;
/* remove udata from `tmudata' */
if (o == g->tmudata) /* last element? */
g->tmudata = NULL;
else
g->tmudata->gch.next = udata->uv.next;
udata->uv.next = g->mainthread->next; /* return it to `root' list */
g->mainthread->next = o;
makewhite(g, o);
tm = fasttm(L, udata->uv.metatable, TM_GC);
if (tm != NULL) {
lu_byte oldah = L->allowhook;
lu_mem oldt = g->GCthreshold;
L->allowhook = 0; /* stop debug hooks during GC tag method */
g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */
setobj2s(L, L->top, tm);
setuvalue(L, L->top+1, udata);
L->top += 2;
luaD_call(L, L->top - 2, 0);
L->allowhook = oldah; /* restore hooks */
g->GCthreshold = oldt; /* restore threshold */
}
}
/*
** Call all GC tag methods
*/
void luaC_callGCTM (lua_State *L) {
while (G(L)->tmudata)
GCTM(L);
}
void luaC_freeall (lua_State *L) {
global_State *g = G(L);
int i;
g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
sweepwholelist(L, &g->rootgc);
for (i = 0; i < g->strt.size; i++) /* free all string lists */
sweepwholelist(L, &g->strt.hash[i]);
}
static void markmt (global_State *g) {
int i;
for (i=0; i<NUM_TAGS; i++)
if (g->mt[i]) markobject(g, g->mt[i]);
}
/* mark root set */
static void markroot (lua_State *L) {
global_State *g = G(L);
g->gray = NULL;
g->grayagain = NULL;
g->weak = NULL;
markobject(g, g->mainthread);
/* make global table be traversed before main stack */
markvalue(g, gt(g->mainthread));
markvalue(g, registry(L));
markmt(g);
g->gcstate = GCSpropagate;
}
static void remarkupvals (global_State *g) {
UpVal *uv;
for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
if (isgray(obj2gco(uv)))
markvalue(g, uv->v);
}
}
static void atomic (lua_State *L) {
global_State *g = G(L);
size_t udsize; /* total size of userdata to be finalized */
/* remark occasional upvalues of (maybe) dead threads */
remarkupvals(g);
/* traverse objects cautch by write barrier and by 'remarkupvals' */
propagateall(g);
/* remark weak tables */
g->gray = g->weak;
g->weak = NULL;
lua_assert(!iswhite(obj2gco(g->mainthread)));
markobject(g, L); /* mark running thread */
markmt(g); /* mark basic metatables (again) */
propagateall(g);
/* remark gray again */
g->gray = g->grayagain;
g->grayagain = NULL;
propagateall(g);
udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
marktmu(g); /* mark `preserved' userdata */
propagateall(g); /* remark, to propagate `preserveness' */
cleartable(g->weak); /* remove collected objects from weak tables */
/* flip current white */
g->currentwhite = cast(lu_byte, otherwhite(g));
g->sweepstrgc = 0;
g->sweepgc = &g->rootgc;
g->gcstate = GCSsweepstring;
g->estimate = g->totalbytes - udsize; /* first estimate */
}
static l_mem singlestep (lua_State *L) {
global_State *g = G(L);
/*lua_checkmemory(L);*/
switch (g->gcstate) {
case GCSpause: {
markroot(L); /* start a new collection */
return 0;
}
case GCSpropagate: {
if (g->gray)
return propagatemark(g);
else { /* no more `gray' objects */
atomic(L); /* finish mark phase */
return 0;
}
}
case GCSsweepstring: {
lu_mem old = g->totalbytes;
sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
g->gcstate = GCSsweep; /* end sweep-string phase */
lua_assert(old >= g->totalbytes);
g->estimate -= old - g->totalbytes;
return GCSWEEPCOST;
}
case GCSsweep: {
lu_mem old = g->totalbytes;
g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
if (*g->sweepgc == NULL) { /* nothing more to sweep? */
checkSizes(L);
g->gcstate = GCSfinalize; /* end sweep phase */
}
lua_assert(old >= g->totalbytes);
g->estimate -= old - g->totalbytes;
return GCSWEEPMAX*GCSWEEPCOST;
}
case GCSfinalize: {
if (g->tmudata) {
GCTM(L);
return GCFINALIZECOST;
}
else {
g->gcstate = GCSpause; /* end collection */
g->gcdept = 0;
return 0;
}
}
default: lua_assert(0); return 0;
}
}
void luaC_step (lua_State *L) {
global_State *g = G(L);
l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
if (lim == 0)
lim = (MAX_LUMEM-1)/2; /* no limit */
g->gcdept += g->totalbytes - g->GCthreshold;
do {
lim -= singlestep(L);
if (g->gcstate == GCSpause)
break;
} while (lim > 0);
if (g->gcstate != GCSpause) {
if (g->gcdept < GCSTEPSIZE)
g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
else {
g->gcdept -= GCSTEPSIZE;
g->GCthreshold = g->totalbytes;
}
}
else {
lua_assert(g->totalbytes >= g->estimate);
setthreshold(g);
}
}
void luaC_fullgc (lua_State *L) {
global_State *g = G(L);
if (g->gcstate <= GCSpropagate) {
/* reset sweep marks to sweep all elements (returning them to white) */
g->sweepstrgc = 0;
g->sweepgc = &g->rootgc;
/* reset other collector lists */
g->gray = NULL;
g->grayagain = NULL;
g->weak = NULL;
g->gcstate = GCSsweepstring;
}
lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
/* finish any pending sweep phase */
while (g->gcstate != GCSfinalize) {
lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
singlestep(L);
}
markroot(L);
while (g->gcstate != GCSpause) {
singlestep(L);
}
setthreshold(g);
}
void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
global_State *g = G(L);
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
lua_assert(ttype(&o->gch) != LUA_TTABLE);
/* must keep invariant? */
if (g->gcstate == GCSpropagate)
reallymarkobject(g, v); /* restore invariant */
else /* don't mind */
makewhite(g, o); /* mark as white just to avoid other barriers */
}
void luaC_barrierback (lua_State *L, Table *t) {
global_State *g = G(L);
GCObject *o = obj2gco(t);
lua_assert(isblack(o) && !isdead(g, o));
lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
black2gray(o); /* make table gray (again) */
t->gclist = g->grayagain;
g->grayagain = o;
}
void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
global_State *g = G(L);
o->gch.next = g->rootgc;
g->rootgc = o;
o->gch.marked = luaC_white(g);
o->gch.tt = tt;
}
void luaC_linkupval (lua_State *L, UpVal *uv) {
global_State *g = G(L);
GCObject *o = obj2gco(uv);
o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
g->rootgc = o;
if (isgray(o)) {
if (g->gcstate == GCSpropagate) {
gray2black(o); /* closed upvalues need barrier */
luaC_barrier(L, uv, uv->v);
}
else { /* sweep phase: sweep it (turning it into white) */
makewhite(g, o);
lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
}
}
}
+110
View File
@@ -0,0 +1,110 @@
/*
** $Id: lgc.h,v 2.14 2005/06/07 18:53:45 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
#ifndef lgc_h
#define lgc_h
#include "lobject.h"
/*
** Possible states of the Garbage Collector
*/
#define GCSpause 0
#define GCSpropagate 1
#define GCSsweepstring 2
#define GCSsweep 3
#define GCSfinalize 4
/*
** some userful bit tricks
*/
#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
#define setbits(x,m) ((x) |= (m))
#define testbits(x,m) ((x) & (m))
#define bitmask(b) (1<<(b))
#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
#define l_setbit(x,b) setbits(x, bitmask(b))
#define resetbit(x,b) resetbits(x, bitmask(b))
#define testbit(x,b) testbits(x, bitmask(b))
#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))
/*
** Layout for bit use in `marked' field:
** bit 0 - object is white (type 0)
** bit 1 - object is white (type 1)
** bit 2 - object is black
** bit 3 - for userdata: has been finalized
** bit 3 - for tables: has weak keys
** bit 4 - for tables: has weak values
** bit 5 - object is fixed (should not be collected)
** bit 6 - object is "super" fixed (only the main thread)
*/
#define WHITE0BIT 0
#define WHITE1BIT 1
#define BLACKBIT 2
#define FINALIZEDBIT 3
#define KEYWEAKBIT 3
#define VALUEWEAKBIT 4
#define FIXEDBIT 5
#define SFIXEDBIT 6
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
#define isgray(x) (!isblack(x) && !iswhite(x))
#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
#define luaC_checkGC(L) { \
condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
if (G(L)->totalbytes >= G(L)->GCthreshold) \
luaC_step(L); }
#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \
luaC_barrierback(L,t); }
#define luaC_objbarrier(L,p,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
#define luaC_objbarriert(L,t,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); }
LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
LUAI_FUNC void luaC_callGCTM (lua_State *L);
LUAI_FUNC void luaC_freeall (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_fullgc (lua_State *L);
LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
#endif
+38
View File
@@ -0,0 +1,38 @@
/*
** $Id: linit.c,v 1.12 2005/08/10 18:06:58 roberto Exp roberto $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/
#define linit_c
#define LUA_LIB
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{LUA_LOADLIBNAME, luaopen_package},
{NULL, NULL}
};
LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib = lualibs;
for (; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);
}
}
+531
View File
@@ -0,0 +1,531 @@
/*
** $Id: liolib.c,v 2.66 2005/08/17 19:05:04 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define liolib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
static const char *const fnames[] = {"input", "output"};
static int pushresult (lua_State *L, int i, const char *filename) {
if (i) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
if (filename)
lua_pushfstring(L, "%s: %s", filename, strerror(errno));
else
lua_pushfstring(L, "%s", strerror(errno));
lua_pushinteger(L, errno);
return 3;
}
}
static void fileerror (lua_State *L, int arg, const char *filename) {
lua_pushfstring(L, "%s: %s", filename, strerror(errno));
luaL_argerror(L, arg, lua_tostring(L, -1));
}
#define topfile(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
static int io_type (lua_State *L) {
void *ud;
luaL_checkany(L, 1);
ud = lua_touserdata(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
lua_pushnil(L); /* not a file */
else if (*((FILE **)ud) == NULL)
lua_pushliteral(L, "closed file");
else
lua_pushliteral(L, "file");
return 1;
}
static FILE *tofile (lua_State *L) {
FILE **f = topfile(L);
if (*f == NULL)
luaL_error(L, "attempt to use a closed file");
return *f;
}
/*
** When creating file handles, always creates a `closed' file handle
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
static FILE **newfile (lua_State *L) {
FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
*pf = NULL; /* file handle is currently `closed' */
luaL_getmetatable(L, LUA_FILEHANDLE);
lua_setmetatable(L, -2);
return pf;
}
/*
** this function has a separated environment, which defines the
** correct __close for 'popen' files
*/
static int io_pclose (lua_State *L) {
FILE **p = topfile(L);
int ok = lua_pclose(L, *p);
if (ok) *p = NULL;
return pushresult(L, ok, NULL);
}
static int io_fclose (lua_State *L) {
FILE **p = topfile(L);
int ok = (fclose(*p) == 0);
if (ok) *p = NULL;
return pushresult(L, ok, NULL);
}
static int aux_close (lua_State *L) {
lua_getfenv(L, 1);
lua_getfield(L, -1, "__close");
return (lua_tocfunction(L, -1))(L);
}
static int io_close (lua_State *L) {
if (lua_isnone(L, 1))
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
tofile(L); /* make sure argument is a file */
return aux_close(L);
}
static int io_gc (lua_State *L) {
FILE *f = *topfile(L);
/* ignore closed files and standard files */
if (f != NULL && f != stdin && f != stdout && f != stderr)
aux_close(L);
return 0;
}
static int io_tostring (lua_State *L) {
FILE *f = *topfile(L);
if (f == NULL)
lua_pushstring(L, "file (closed)");
else
lua_pushfstring(L, "file (%p)", f);
return 1;
}
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
FILE **pf = newfile(L);
*pf = fopen(filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}
static int io_popen (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
FILE **pf = newfile(L);
*pf = lua_popen(L, filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}
static int io_tmpfile (lua_State *L) {
FILE **pf = newfile(L);
*pf = tmpfile();
return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
}
static FILE *getiofile (lua_State *L, int findex) {
FILE *f;
lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
f = *(FILE **)lua_touserdata(L, -1);
if (f == NULL)
luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
return f;
}
static int g_iofile (lua_State *L, int f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
if (filename) {
FILE **pf = newfile(L);
*pf = fopen(filename, mode);
if (*pf == NULL)
fileerror(L, 1, filename);
}
else {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
}
lua_rawseti(L, LUA_ENVIRONINDEX, f);
}
/* return current value */
lua_rawgeti(L, LUA_ENVIRONINDEX, f);
return 1;
}
static int io_input (lua_State *L) {
return g_iofile(L, IO_INPUT, "r");
}
static int io_output (lua_State *L) {
return g_iofile(L, IO_OUTPUT, "w");
}
static int io_readline (lua_State *L);
static void aux_lines (lua_State *L, int idx, int toclose) {
lua_pushvalue(L, idx);
lua_pushboolean(L, toclose); /* close/not close file when finished */
lua_pushcclosure(L, io_readline, 2);
}
static int f_lines (lua_State *L) {
tofile(L); /* check that it's a valid file handle */
aux_lines(L, 1, 0);
return 1;
}
static int io_lines (lua_State *L) {
if (lua_isnoneornil(L, 1)) { /* no arguments? */
/* will iterate over default input */
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
return f_lines(L);
}
else {
const char *filename = luaL_checkstring(L, 1);
FILE **pf = newfile(L);
*pf = fopen(filename, "r");
if (*pf == NULL)
fileerror(L, 1, filename);
aux_lines(L, lua_gettop(L), 1);
return 1;
}
}
/*
** {======================================================
** READ
** =======================================================
*/
static int read_number (lua_State *L, FILE *f) {
lua_Number d;
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
lua_pushnumber(L, d);
return 1;
}
else return 0; /* read fails */
}
static int test_eof (lua_State *L, FILE *f) {
int c = getc(f);
ungetc(c, f);
lua_pushlstring(L, NULL, 0);
return (c != EOF);
}
static int read_line (lua_State *L, FILE *f) {
luaL_Buffer b;
luaL_buffinit(L, &b);
for (;;) {
size_t l;
char *p = luaL_prepbuffer(&b);
if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
luaL_pushresult(&b); /* close buffer */
return (lua_strlen(L, -1) > 0); /* check whether read something */
}
l = strlen(p);
if (p[l-1] != '\n')
luaL_addsize(&b, l);
else {
luaL_addsize(&b, l - 1); /* do not include `eol' */
luaL_pushresult(&b); /* close buffer */
return 1; /* read at least an `eol' */
}
}
}
static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t rlen; /* how much to read */
size_t nr; /* number of chars actually read */
luaL_Buffer b;
luaL_buffinit(L, &b);
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
do {
char *p = luaL_prepbuffer(&b);
if (rlen > n) rlen = n; /* cannot read more than asked */
nr = fread(p, sizeof(char), rlen, f);
luaL_addsize(&b, nr);
n -= nr; /* still have to read `n' chars */
} while (n > 0 && nr == rlen); /* until end of count or eof */
luaL_pushresult(&b); /* close buffer */
return (n == 0 || lua_strlen(L, -1) > 0);
}
static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1;
int success;
int n;
clearerr(f);
if (nargs == 0) { /* no arguments? */
success = read_line(L, f);
n = first+1; /* to return 1 result */
}
else { /* ensure stack space for all results and for auxlib's buffer */
luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
success = 1;
for (n = first; nargs-- && success; n++) {
if (lua_type(L, n) == LUA_TNUMBER) {
size_t l = (size_t)lua_tointeger(L, n);
success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
}
else {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
case 'n': /* number */
success = read_number(L, f);
break;
case 'l': /* line */
success = read_line(L, f);
break;
case 'a': /* file */
read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
success = 1; /* always success */
break;
default:
return luaL_argerror(L, n, "invalid format");
}
}
}
}
if (ferror(f))
return pushresult(L, 0, NULL);
if (!success) {
lua_pop(L, 1); /* remove last result */
lua_pushnil(L); /* push nil instead */
}
return n - first;
}
static int io_read (lua_State *L) {
return g_read(L, getiofile(L, IO_INPUT), 1);
}
static int f_read (lua_State *L) {
return g_read(L, tofile(L), 2);
}
static int io_readline (lua_State *L) {
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int sucess;
if (f == NULL) /* file is already closed? */
luaL_error(L, "file is already closed");
sucess = read_line(L, f);
if (ferror(f))
return luaL_error(L, "%s", strerror(errno));
if (sucess) return 1;
else { /* EOF */
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
aux_close(L); /* close it */
}
return 0;
}
}
/* }====================================================== */
static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - 1;
int status = 1;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
status = status &&
fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
}
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
status = status && (fwrite(s, sizeof(char), l, f) == l);
}
}
return pushresult(L, status, NULL);
}
static int io_write (lua_State *L) {
return g_write(L, getiofile(L, IO_OUTPUT), 1);
}
static int f_write (lua_State *L) {
return g_write(L, tofile(L), 2);
}
static int f_seek (lua_State *L) {
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames);
lua_Integer offset = luaL_optinteger(L, 3, 0);
op = fseek(f, offset, mode[op]);
if (op)
return pushresult(L, 0, NULL); /* error */
else {
lua_pushinteger(L, ftell(f));
return 1;
}
}
static int f_setvbuf (lua_State *L) {
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, BUFSIZ);
int res = setvbuf(f, NULL, mode[op], sz);
return pushresult(L, res == 0, NULL);
}
static int io_flush (lua_State *L) {
return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
}
static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL);
}
static const luaL_Reg iolib[] = {
{"close", io_close},
{"flush", io_flush},
{"input", io_input},
{"lines", io_lines},
{"open", io_open},
{"output", io_output},
{"popen", io_popen},
{"read", io_read},
{"tmpfile", io_tmpfile},
{"type", io_type},
{"write", io_write},
{NULL, NULL}
};
static const luaL_Reg flib[] = {
{"close", io_close},
{"flush", f_flush},
{"lines", f_lines},
{"read", f_read},
{"seek", f_seek},
{"setvbuf", f_setvbuf},
{"write", f_write},
{"__gc", io_gc},
{"__tostring", io_tostring},
{NULL, NULL}
};
static void createmeta (lua_State *L) {
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_register(L, NULL, flib); /* file methods */
}
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f;
if (k > 0) {
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_ENVIRONINDEX, k);
}
lua_setfield(L, -2, fname);
}
LUALIB_API int luaopen_io (lua_State *L) {
createmeta(L);
/* create new (private) environment */
lua_newtable(L);
lua_replace(L, LUA_ENVIRONINDEX);
/* open library */
luaL_register(L, LUA_IOLIBNAME, iolib);
/* create (and set) default files */
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, 0, "stderr");
/* create environment for 'popen' */
lua_getfield(L, -1, "popen");
lua_newtable(L);
lua_pushcfunction(L, io_pclose);
lua_setfield(L, -2, "__close");
lua_setfenv(L, -2);
lua_pop(L, 1); /* pop 'popen' */
/* set default close function */
lua_pushcfunction(L, io_fclose);
lua_setfield(L, LUA_ENVIRONINDEX, "__close");
return 1;
}
+430
View File
@@ -0,0 +1,430 @@
/*
** $Id: llex.c,v 2.11 2005/05/16 21:19:00 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <string.h>
#define llex_c
#define LUA_CORE
#include "lua.h"
#include "ldo.h"
#include "llex.h"
#include "lobject.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "lzio.h"
#define next(ls) (ls->current = zgetc(ls->z))
#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
/* ORDER RESERVED */
const char *const luaX_tokens [] = {
"and", "break", "do", "else", "elseif",
"end", "false", "for", "function", "if",
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
"..", "...", "==", ">=", "<=", "~=",
"<number>", "<name>", "<string>", "<eof>",
NULL
};
#define save_and_next(ls) (save(ls, ls->current), next(ls))
static void save (LexState *ls, int c) {
Mbuffer *b = ls->buff;
if (b->n + 1 > b->buffsize) {
size_t newsize;
if (b->buffsize >= MAX_SIZET/2)
luaX_lexerror(ls, "lexical element too long", 0);
newsize = b->buffsize * 2;
luaZ_resizebuffer(ls->L, b, newsize);
}
b->buffer[b->n++] = cast(char, c);
}
void luaX_init (lua_State *L) {
int i;
for (i=0; i<NUM_RESERVED; i++) {
TString *ts = luaS_new(L, luaX_tokens[i]);
luaS_fix(ts); /* reserved words are never collected */
lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
ts->tsv.reserved = cast(lu_byte, i+1); /* reserved word */
}
}
#define MAXSRC 80
const char *luaX_token2str (LexState *ls, int token) {
if (token < FIRST_RESERVED) {
lua_assert(token == cast(unsigned char, token));
return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) :
luaO_pushfstring(ls->L, "%c", token);
}
else
return luaX_tokens[token-FIRST_RESERVED];
}
static const char *txtToken (LexState *ls, int token) {
switch (token) {
case TK_NAME:
case TK_STRING:
case TK_NUMBER:
save(ls, '\0');
return luaZ_buffer(ls->buff);
default:
return luaX_token2str(ls, token);
}
}
void luaX_lexerror (LexState *ls, const char *msg, int token) {
char buff[MAXSRC];
luaO_chunkid(buff, getstr(ls->source), MAXSRC);
msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
if (token)
luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token));
luaD_throw(ls->L, LUA_ERRSYNTAX);
}
void luaX_syntaxerror (LexState *ls, const char *msg) {
luaX_lexerror(ls, msg, ls->t.token);
}
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
lua_State *L = ls->L;
TString *ts = luaS_newlstr(L, str, l);
TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */
if (ttisnil(o))
setbvalue(o, 1); /* make sure `str' will not be collected */
return ts;
}
static void inclinenumber (LexState *ls) {
int old = ls->current;
lua_assert(currIsNewline(ls));
next(ls); /* skip `\n' or `\r' */
if (currIsNewline(ls) && ls->current != old)
next(ls); /* skip `\n\r' or `\r\n' */
if (++ls->linenumber >= MAX_INT)
luaX_syntaxerror(ls, "chunk has too many lines");
}
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
ls->L = L;
ls->lookahead.token = TK_EOS; /* no look-ahead token */
ls->z = z;
ls->fs = NULL;
ls->linenumber = 1;
ls->lastline = 1;
ls->source = source;
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
next(ls); /* read first char */
}
/*
** =======================================================
** LEXICAL ANALYZER
** =======================================================
*/
/* LUA_NUMBER */
static void read_numeral (LexState *ls, SemInfo *seminfo) {
while (isdigit(ls->current)) {
save_and_next(ls);
}
if (ls->current == '.') {
save_and_next(ls);
if (ls->current == '.') {
save_and_next(ls);
luaX_lexerror(ls,
"ambiguous syntax (decimal point x string concatenation)",
TK_NUMBER);
}
}
while (isdigit(ls->current)) {
save_and_next(ls);
}
if (ls->current == 'e' || ls->current == 'E') {
save_and_next(ls); /* read `E' */
if (ls->current == '+' || ls->current == '-')
save_and_next(ls); /* optional exponent sign */
while (isdigit(ls->current)) {
save_and_next(ls);
}
}
save(ls, '\0');
if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r))
luaX_lexerror(ls, "malformed number", TK_NUMBER);
}
static int skip_sep (LexState *ls) {
int count = 0;
int s = ls->current;
lua_assert(s == '[' || s == ']');
save_and_next(ls);
while (ls->current == '=') {
save_and_next(ls);
count++;
}
return (ls->current == s) ? count : (-count) - 1;
}
static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
int cont = 0;
(void)(cont); /* avoid warnings when `cont' is not used */
save_and_next(ls); /* skip 2nd `[' */
if (currIsNewline(ls)) /* string starts with a newline? */
inclinenumber(ls); /* skip it */
for (;;) {
switch (ls->current) {
case EOZ:
luaX_lexerror(ls, (seminfo) ? "unfinished long string" :
"unfinished long comment", TK_EOS);
break; /* to avoid warnings */
#if defined(LUA_COMPAT_LSTR)
case '[': {
if (skip_sep(ls) == sep) {
save_and_next(ls); /* skip 2nd `[' */
cont++;
#if LUA_COMPAT_LSTR == 1
if (sep == 0)
luaX_lexerror(ls, "nesting of [[...]] is deprecated", '[');
#endif
}
break;
}
#endif
case ']': {
if (skip_sep(ls) == sep) {
save_and_next(ls); /* skip 2nd `]' */
#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2
cont--;
if (sep == 0 && cont >= 0) break;
#endif
goto endloop;
}
break;
}
case '\n':
case '\r': {
save(ls, '\n');
inclinenumber(ls);
if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
break;
}
default: {
if (seminfo) save_and_next(ls);
else next(ls);
}
}
} endloop:
if (seminfo)
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
luaZ_bufflen(ls->buff) - 2*(2 + sep));
}
static void read_string (LexState *ls, int del, SemInfo *seminfo) {
save_and_next(ls);
while (ls->current != del) {
switch (ls->current) {
case EOZ:
luaX_lexerror(ls, "unfinished string", TK_EOS);
continue; /* to avoid warnings */
case '\n':
case '\r':
luaX_lexerror(ls, "unfinished string", TK_STRING);
continue; /* to avoid warnings */
case '\\': {
int c;
next(ls); /* do not save the `\' */
switch (ls->current) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case '\n': /* go through */
case '\r': save(ls, '\n'); inclinenumber(ls); continue;
case EOZ: continue; /* will raise an error next loop */
default: {
if (!isdigit(ls->current))
save_and_next(ls); /* handles \\, \", \', and \? */
else { /* \xxx */
int i = 0;
c = 0;
do {
c = 10*c + (ls->current-'0');
next(ls);
} while (++i<3 && isdigit(ls->current));
if (c > UCHAR_MAX)
luaX_lexerror(ls, "escape sequence too large", TK_STRING);
save(ls, c);
}
continue;
}
}
save(ls, c);
next(ls);
continue;
}
default:
save_and_next(ls);
}
}
save_and_next(ls); /* skip delimiter */
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
luaZ_bufflen(ls->buff) - 2);
}
int luaX_lex (LexState *ls, SemInfo *seminfo) {
luaZ_resetbuffer(ls->buff);
for (;;) {
switch (ls->current) {
case '\n':
case '\r': {
inclinenumber(ls);
continue;
}
case '-': {
next(ls);
if (ls->current != '-') return '-';
/* else is a comment */
next(ls);
if (ls->current == '[') {
int sep = skip_sep(ls);
luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
if (sep >= 0) {
read_long_string(ls, NULL, sep); /* long comment */
luaZ_resetbuffer(ls->buff);
continue;
}
}
/* else short comment */
while (!currIsNewline(ls) && ls->current != EOZ)
next(ls);
continue;
}
case '[': {
int sep = skip_sep(ls);
if (sep >= 0) {
read_long_string(ls, seminfo, sep);
return TK_STRING;
}
else if (sep == -1) return '[';
else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
}
case '=': {
next(ls);
if (ls->current != '=') return '=';
else { next(ls); return TK_EQ; }
}
case '<': {
next(ls);
if (ls->current != '=') return '<';
else { next(ls); return TK_LE; }
}
case '>': {
next(ls);
if (ls->current != '=') return '>';
else { next(ls); return TK_GE; }
}
case '~': {
next(ls);
if (ls->current != '=') return '~';
else { next(ls); return TK_NE; }
}
case '"':
case '\'': {
read_string(ls, ls->current, seminfo);
return TK_STRING;
}
case '.': {
save_and_next(ls);
if (ls->current == '.') {
next(ls);
if (ls->current == '.') {
next(ls);
return TK_DOTS; /* ... */
}
else return TK_CONCAT; /* .. */
}
else if (!isdigit(ls->current)) return '.';
else {
read_numeral(ls, seminfo);
return TK_NUMBER;
}
}
case EOZ: {
return TK_EOS;
}
default: {
if (isspace(ls->current)) {
lua_assert(!currIsNewline(ls));
next(ls);
continue;
}
else if (isdigit(ls->current)) {
read_numeral(ls, seminfo);
return TK_NUMBER;
}
else if (isalpha(ls->current) || ls->current == '_') {
/* identifier or reserved word */
TString *ts;
do {
save_and_next(ls);
} while (isalnum(ls->current) || ls->current == '_');
ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
luaZ_bufflen(ls->buff));
if (ts->tsv.reserved > 0) /* reserved word? */
return ts->tsv.reserved - 1 + FIRST_RESERVED;
else {
seminfo->ts = ts;
return TK_NAME;
}
}
else {
int c = ls->current;
next(ls);
return c; /* single-char tokens (+ - / ...) */
}
}
}
}
}
#undef next
+79
View File
@@ -0,0 +1,79 @@
/*
** $Id: llex.h,v 1.54 2005/04/25 19:24:10 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
#ifndef llex_h
#define llex_h
#include "lobject.h"
#include "lzio.h"
#define FIRST_RESERVED 257
/* maximum length of a reserved word */
#define TOKEN_LEN (sizeof("function")/sizeof(char))
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER RESERVED"
*/
enum RESERVED {
/* terminal symbols denoted by reserved words */
TK_AND = FIRST_RESERVED, TK_BREAK,
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
TK_NAME, TK_STRING, TK_EOS
};
/* number of reserved words */
#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
/* array with token `names' */
LUAI_DATA const char *const luaX_tokens [];
typedef union {
lua_Number r;
TString *ts;
} SemInfo; /* semantics information */
typedef struct Token {
int token;
SemInfo seminfo;
} Token;
typedef struct LexState {
int current; /* current character (charint) */
int linenumber; /* input line counter */
int lastline; /* line of last token `consumed' */
Token t; /* current token */
Token lookahead; /* look ahead token */
struct FuncState *fs; /* `FuncState' is private to the parser */
struct lua_State *L;
ZIO *z; /* input stream */
Mbuffer *buff; /* buffer for tokens */
TString *source; /* current source name */
} LexState;
LUAI_FUNC void luaX_init (lua_State *L);
LUAI_FUNC void luaX_setinput (lua_State *L, LexState *LS, ZIO *z,
TString *source);
LUAI_FUNC TString *luaX_newstring (LexState *LS, const char *str, size_t l);
LUAI_FUNC int luaX_lex (LexState *LS, SemInfo *seminfo);
LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
#endif
+115
View File
@@ -0,0 +1,115 @@
/*
** $Id: llimits.h,v 1.66 2005/08/04 13:37:10 roberto Exp roberto $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
#ifndef llimits_h
#define llimits_h
#include <limits.h>
#include <stddef.h>
#include "lua.h"
#define api_check luai_apicheck
typedef LUAI_UINT32 lu_int32;
typedef LUAI_UMEM lu_mem;
typedef LUAI_MEM l_mem;
/* chars used as small naturals (so that `char' is reserved for characters) */
typedef unsigned char lu_byte;
#define MAX_SIZET ((size_t)(~(size_t)0)-2)
#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
/*
** conversion of pointer to integer
** this is for hashing only; there is no problem if the integer
** cannot hold the whole pointer value
*/
#define IntPoint(p) ((unsigned int)(lu_mem)(p))
/* type to ensure maximum alignment */
typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
/* result of a `usual argument conversion' over lua_Number */
typedef LUAI_UACNUMBER l_uacNumber;
#define check_exp(c,e) (lua_assert(c), (e))
#ifndef UNUSED
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
#endif
#ifndef cast
#define cast(t, exp) ((t)(exp))
#endif
/*
** type for virtual-machine instructions
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
*/
typedef lu_int32 Instruction;
/* maximum stack for a Lua function */
#define MAXSTACK 250
/* minimum size for the string table (must be power of 2) */
#ifndef MINSTRTABSIZE
#define MINSTRTABSIZE 32
#endif
/* minimum size for string buffer */
#ifndef LUA_MINBUFFER
#define LUA_MINBUFFER 32
#endif
#ifndef lua_lock
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif
#ifndef luai_threadyield
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
#endif
/*
** macro to control inclusion of some hard tests on stack reallocation
*/
#ifndef HARDSTACKTESTS
#define condhardstacktests(x) ((void)0)
#else
#define condhardstacktests(x) x
#endif
#endif
+263
View File
@@ -0,0 +1,263 @@
/*
** $Id: lmathlib.c,v 1.66 2005/08/15 14:12:32 roberto Exp roberto $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <math.h>
#define lmathlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#undef PI
#define PI (3.14159265358979323846)
#define RADIANS_PER_DEGREE (PI/180.0)
static int math_abs (lua_State *L) {
lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
return 1;
}
static int math_sin (lua_State *L) {
lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
return 1;
}
static int math_sinh (lua_State *L) {
lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
return 1;
}
static int math_cos (lua_State *L) {
lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
return 1;
}
static int math_cosh (lua_State *L) {
lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
return 1;
}
static int math_tan (lua_State *L) {
lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
return 1;
}
static int math_tanh (lua_State *L) {
lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
return 1;
}
static int math_asin (lua_State *L) {
lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
return 1;
}
static int math_acos (lua_State *L) {
lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
return 1;
}
static int math_atan (lua_State *L) {
lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
return 1;
}
static int math_atan2 (lua_State *L) {
lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}
static int math_ceil (lua_State *L) {
lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
return 1;
}
static int math_floor (lua_State *L) {
lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
return 1;
}
static int math_fmod (lua_State *L) {
lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}
static int math_modf (lua_State *L) {
double ip;
double fp = modf(luaL_checknumber(L, 1), &ip);
lua_pushnumber(L, ip);
lua_pushnumber(L, fp);
return 2;
}
static int math_sqrt (lua_State *L) {
lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
return 1;
}
static int math_pow (lua_State *L) {
lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}
static int math_log (lua_State *L) {
lua_pushnumber(L, log(luaL_checknumber(L, 1)));
return 1;
}
static int math_log10 (lua_State *L) {
lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
return 1;
}
static int math_exp (lua_State *L) {
lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
return 1;
}
static int math_deg (lua_State *L) {
lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
return 1;
}
static int math_rad (lua_State *L) {
lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
return 1;
}
static int math_frexp (lua_State *L) {
int e;
lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
lua_pushinteger(L, e);
return 2;
}
static int math_ldexp (lua_State *L) {
lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
return 1;
}
static int math_min (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number dmin = luaL_checknumber(L, 1);
int i;
for (i=2; i<=n; i++) {
lua_Number d = luaL_checknumber(L, i);
if (d < dmin)
dmin = d;
}
lua_pushnumber(L, dmin);
return 1;
}
static int math_max (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number dmax = luaL_checknumber(L, 1);
int i;
for (i=2; i<=n; i++) {
lua_Number d = luaL_checknumber(L, i);
if (d > dmax)
dmax = d;
}
lua_pushnumber(L, dmax);
return 1;
}
static int math_random (lua_State *L) {
/* the `%' avoids the (rare) case of r==1, and is needed also because on
some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
switch (lua_gettop(L)) { /* check number of arguments */
case 0: { /* no arguments */
lua_pushnumber(L, r); /* Number between 0 and 1 */
break;
}
case 1: { /* only upper limit */
int u = luaL_checkint(L, 1);
luaL_argcheck(L, 1<=u, 1, "interval is empty");
lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
break;
}
case 2: { /* lower and upper limits */
int l = luaL_checkint(L, 1);
int u = luaL_checkint(L, 2);
luaL_argcheck(L, l<=u, 2, "interval is empty");
lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
break;
}
default: return luaL_error(L, "wrong number of arguments");
}
return 1;
}
static int math_randomseed (lua_State *L) {
srand(luaL_checkint(L, 1));
return 0;
}
static const luaL_Reg mathlib[] = {
{"abs", math_abs},
{"acos", math_acos},
{"asin", math_asin},
{"atan2", math_atan2},
{"atan", math_atan},
{"ceil", math_ceil},
{"cosh", math_cosh},
{"cos", math_cos},
{"deg", math_deg},
{"exp", math_exp},
{"floor", math_floor},
{"fmod", math_fmod},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
{"log10", math_log10},
{"log", math_log},
{"max", math_max},
{"min", math_min},
{"modf", math_modf},
{"pow", math_pow},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed},
{"sinh", math_sinh},
{"sin", math_sin},
{"sqrt", math_sqrt},
{"tanh", math_tanh},
{"tan", math_tan},
{NULL, NULL}
};
/*
** Open math library
*/
LUALIB_API int luaopen_math (lua_State *L) {
luaL_register(L, LUA_MATHLIBNAME, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
lua_pushnumber(L, HUGE_VAL);
lua_setfield(L, -2, "huge");
#if defined(LUA_COMPAT_MOD)
lua_getfield(L, -1, "fmod");
lua_setfield(L, -2, "mod");
#endif
return 1;
}
+102
View File
@@ -0,0 +1,102 @@
/*
** $Id: lmem.c,v 1.68 2005/01/14 14:21:16 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define lmem_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
/*
** About the realloc function:
** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
** (`osize' is the old size, `nsize' is the new size)
**
** Lua ensures that (ptr == NULL) iff (osize == 0).
**
** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
**
** * frealloc(ud, p, x, 0) frees the block `p'
** (in this specific case, frealloc must return NULL).
** particularly, frealloc(ud, NULL, 0, 0) does nothing
** (which is equivalent to free(NULL) in ANSI C)
**
** frealloc returns NULL if it cannot create or reallocate the area
** (any reallocation to an equal or smaller size cannot fail!)
*/
#define MINSIZEARRAY 4
void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
int limit, const char *errormsg) {
void *newblock;
int newsize;
if (*size >= limit/2) { /* cannot double it? */
if (*size >= limit) /* cannot grow even a little? */
luaG_runerror(L, errormsg);
newsize = limit; /* still have at least one free place */
}
else {
newsize = (*size)*2;
if (newsize < MINSIZEARRAY)
newsize = MINSIZEARRAY; /* minimum size */
}
newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
*size = newsize; /* update only when everything else is OK */
return newblock;
}
void *luaM_toobig (lua_State *L) {
luaG_runerror(L, "memory allocation error: block too big");
return NULL; /* to avoid warnings */
}
/*
** generic allocation routine.
*/
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
global_State *g = G(L);
lua_assert((osize == 0) == (block == NULL));
block = (*g->frealloc)(g->ud, block, osize, nsize);
if (block == NULL && nsize > 0)
luaD_throw(L, LUA_ERRMEM);
lua_assert((nsize == 0) == (block == NULL));
g->totalbytes = (g->totalbytes - osize) + nsize;
#if 0
{ /* auxiliar patch to monitor garbage collection */
static unsigned long total = 0; /* our "time" */
static lu_mem last = 0; /* last totalmem that generated an output */
static FILE *f = NULL; /* output file */
if (nsize <= osize) total += 1; /* "time" always grow */
else total += (nsize - osize);
if ((int)g->totalbytes - (int)last > 1000 ||
(int)g->totalbytes - (int)last < -1000) {
last = g->totalbytes;
if (f == NULL) f = fopen("trace", "w");
fprintf(f, "%lu %u %u %u %d\n", total, g->totalbytes, g->GCthreshold,
g->estimate, g->gcstate);
}
}
#endif
return block;
}
+49
View File
@@ -0,0 +1,49 @@
/*
** $Id: lmem.h,v 1.30 2005/03/18 16:38:02 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#ifndef lmem_h
#define lmem_h
#include <stddef.h>
#include "llimits.h"
#include "lua.h"
#define MEMERRMSG "not enough memory"
#define luaM_reallocv(L,b,on,n,e) \
((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
luaM_toobig(L))
#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t))
#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t))
#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
#define luaM_newvector(L,n,t) \
cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
#define luaM_growvector(L,v,nelems,size,t,limit,e) \
if ((nelems)+1 > (size)) \
((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
#define luaM_reallocvector(L, v,oldn,n,t) \
((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
size_t size);
LUAI_FUNC void *luaM_toobig (lua_State *L);
LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
size_t size_elem, int limit,
const char *errormsg);
#endif
+655
View File
@@ -0,0 +1,655 @@
/*
** $Id: loadlib.c,v 1.43 2005/08/31 23:17:29 roberto Exp roberto $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
** This module contains an implementation of loadlib for Unix systems
** that have dlfcn, an implementation for Darwin (Mac OS X), an
** implementation for Windows, and a stub for other systems.
*/
#include <stdlib.h>
#include <string.h>
#define loadlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/* environment variables that hold the search path for packages */
#define LUA_PATH "LUA_PATH"
#define LUA_CPATH "LUA_CPATH"
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
/* separator for open functions in C libraries */
#define LUA_OFSEP "_"
#define LIBPREFIX "LOADLIB: "
#define POF LUA_POF
#define LIB_FAIL "open"
/* error codes for ll_loadfunc */
#define ERRLIB 1
#define ERRFUNC 2
#define setprogdir(L) ((void)0)
static void ll_unloadlib (void *lib);
static void *ll_load (lua_State *L, const char *path);
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
#if defined(LUA_DL_DLOPEN)
/*
** {========================================================================
** This is an implementation of loadlib based on the dlfcn interface.
** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
** as an emulation layer on top of native functions.
** =========================================================================
*/
#include <dlfcn.h>
static void ll_unloadlib (void *lib) {
dlclose(lib);
}
static void *ll_load (lua_State *L, const char *path) {
void *lib = dlopen(path, RTLD_NOW);
if (lib == NULL) lua_pushstring(L, dlerror());
return lib;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
if (f == NULL) lua_pushstring(L, dlerror());
return f;
}
/* }====================================================== */
#elif defined(LUA_DL_DLL)
/*
** {======================================================================
** This is an implementation of loadlib for Windows using native functions.
** =======================================================================
*/
#include <windows.h>
#undef setprogdir
void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileName(NULL, buff, nsize);
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
*lb = '\0';
luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
lua_remove(L, -2); /* remove original string */
}
static void pusherror (lua_State *L) {
int error = GetLastError();
char buffer[128];
if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, buffer, sizeof(buffer), NULL))
lua_pushstring(L, buffer);
else
lua_pushfstring(L, "system error %d\n", error);
}
static void ll_unloadlib (void *lib) {
FreeLibrary((HINSTANCE)lib);
}
static void *ll_load (lua_State *L, const char *path) {
HINSTANCE lib = LoadLibrary(path);
if (lib == NULL) pusherror(L);
return lib;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
if (f == NULL) pusherror(L);
return f;
}
/* }====================================================== */
#elif defined(LUA_DL_DYLD)
/*
** {======================================================================
** Native Mac OS X / Darwin Implementation
** =======================================================================
*/
#include <mach-o/dyld.h>
/* Mac appends a `_' before C function names */
#undef POF
#define POF "_" LUA_POF
static void pusherror (lua_State *L) {
const char *err_str;
const char *err_file;
NSLinkEditErrors err;
int err_num;
NSLinkEditError(&err, &err_num, &err_file, &err_str);
lua_pushstring(L, err_str);
}
static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
switch (ret) {
case NSObjectFileImageInappropriateFile:
return "file is not a bundle";
case NSObjectFileImageArch:
return "library is for wrong CPU type";
case NSObjectFileImageFormat:
return "bad format";
case NSObjectFileImageAccess:
return "cannot access file";
case NSObjectFileImageFailure:
default:
return "unable to load library";
}
}
static void ll_unloadlib (void *lib) {
NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
}
static void *ll_load (lua_State *L, const char *path) {
NSObjectFileImage img;
NSObjectFileImageReturnCode ret;
/* this would be a rare case, but prevents crashing if it happens */
if(!_dyld_present()) {
lua_pushliteral(L, "dyld not present");
return NULL;
}
ret = NSCreateObjectFileImageFromFile(path, &img);
if (ret == NSObjectFileImageSuccess) {
NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
NSLINKMODULE_OPTION_RETURN_ON_ERROR);
NSDestroyObjectFileImage(img);
if (mod == NULL) pusherror(L);
return mod;
}
lua_pushstring(L, errorfromcode(ret));
return NULL;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
if (nss == NULL) {
lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
return NULL;
}
return (lua_CFunction)NSAddressOfSymbol(nss);
}
/* }====================================================== */
#else
/*
** {======================================================
** Fallback for other systems
** =======================================================
*/
#undef LIB_FAIL
#define LIB_FAIL "absent"
#if defined(__ELF__) || defined(__sun) || defined(sgi) || defined(__hpux)
#define DLMSG LUA_QL("loadlib") " not enabled; check your Lua installation"
#else
#define DLMSG LUA_QL("loadlib") " not supported"
#endif
static void ll_unloadlib (void *lib) {
(void)lib; /* to avoid warnings */
}
static void *ll_load (lua_State *L, const char *path) {
(void)path; /* to avoid warnings */
lua_pushliteral(L, DLMSG);
return NULL;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
(void)lib; (void)sym; /* to avoid warnings */
lua_pushliteral(L, DLMSG);
return NULL;
}
/* }====================================================== */
#endif
static void **ll_register (lua_State *L, const char *path) {
void **plib;
lua_pushfstring(L, "%s%s", LIBPREFIX, path);
lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
if (!lua_isnil(L, -1)) /* is there an entry? */
plib = (void **)lua_touserdata(L, -1);
else { /* no entry yet; create one */
lua_pop(L, 1);
plib = (void **)lua_newuserdata(L, sizeof(const void *));
*plib = NULL;
luaL_getmetatable(L, "_LOADLIB");
lua_setmetatable(L, -2);
lua_pushfstring(L, "%s%s", LIBPREFIX, path);
lua_pushvalue(L, -2);
lua_settable(L, LUA_REGISTRYINDEX);
}
return plib;
}
/*
** __gc tag method: calls library's `ll_unloadlib' function with the lib
** handle
*/
static int gctm (lua_State *L) {
void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
if (*lib) ll_unloadlib(*lib);
*lib = NULL; /* mark library as closed */
return 0;
}
static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
void **reg = ll_register(L, path);
if (*reg == NULL) *reg = ll_load(L, path);
if (*reg == NULL)
return ERRLIB; /* unable to load library */
else {
lua_CFunction f = ll_sym(L, *reg, sym);
if (f == NULL)
return ERRFUNC; /* unable to find function */
lua_pushcfunction(L, f);
return 0; /* return function */
}
}
static int ll_loadlib (lua_State *L) {
const char *path = luaL_checkstring(L, 1);
const char *init = luaL_checkstring(L, 2);
int stat = ll_loadfunc(L, path, init);
if (stat == 0) /* no errors? */
return 1; /* return the loaded function */
else { /* error; error message is on stack top */
lua_pushnil(L);
lua_insert(L, -2);
lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
return 3; /* return nil, error message, and where */
}
}
/*
** {======================================================
** 'require' function
** =======================================================
*/
static int readable (const char *filename) {
FILE *f = fopen(filename, "r"); /* try to open file */
if (f == NULL) return 0; /* open failed */
fclose(f);
return 1;
}
static const char *pushnexttemplate (lua_State *L, const char *path) {
const char *l;
while (*path == *LUA_PATHSEP) path++; /* skip separators */
if (*path == '\0') return NULL; /* no more templates */
l = strchr(path, *LUA_PATHSEP); /* find next separator */
if (l == NULL) l = path + strlen(path);
lua_pushlstring(L, path, l - path); /* template */
return l;
}
static const char *findfile (lua_State *L, const char *name,
const char *pname) {
const char *path;
name = luaL_gsub(L, name, ".", LUA_DIRSEP);
lua_getfield(L, LUA_ENVIRONINDEX, pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename;
filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
if (readable(filename)) /* does file exist and is readable? */
return filename; /* return that file name */
lua_pop(L, 2); /* remove path template and file name */
}
return NULL; /* not found */
}
static void loaderror (lua_State *L) {
luaL_error(L, "error loading module " LUA_QS " (%s)",
lua_tostring(L, 1), lua_tostring(L, -1));
}
static int loader_Lua (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
filename = findfile(L, name, "path");
if (filename == NULL) return 0; /* library not found in this path */
if (luaL_loadfile(L, filename) != 0)
loaderror(L);
return 1; /* library loaded successfully */
}
static const char *mkfuncname (lua_State *L, const char *modname) {
const char *funcname;
const char *mark = strchr(modname, *LUA_IGMARK);
if (mark) modname = mark + 1;
funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
funcname = lua_pushfstring(L, POF"%s", funcname);
lua_remove(L, -2); /* remove 'gsub' result */
return funcname;
}
static int loader_C (lua_State *L) {
const char *funcname;
const char *name = luaL_checkstring(L, 1);
const char *filename = findfile(L, name, "cpath");
if (filename == NULL) return 0; /* library not found in this path */
funcname = mkfuncname(L, name);
if (ll_loadfunc(L, filename, funcname) != 0)
loaderror(L);
return 1; /* library loaded successfully */
}
static int loader_Croot (lua_State *L) {
const char *funcname;
const char *filename;
const char *name = luaL_checkstring(L, 1);
const char *p = strchr(name, '.');
int stat;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name);
filename = findfile(L, lua_tostring(L, -1), "cpath");
if (filename == NULL) return 0; /* root not found */
funcname = mkfuncname(L, name);
if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
if (stat == ERRFUNC) return 0; /* function not found */
else
loaderror(L); /* real error */
}
return 1;
}
static int loader_preload (lua_State *L) {
lua_getfield(L, LUA_ENVIRONINDEX, "preload");
if (!lua_istable(L, -1))
luaL_error(L, LUA_QL("package.preload") " must be a table");
lua_getfield(L, -1, luaL_checkstring(L, 1));
return 1;
}
static const int sentinel = 0;
static int ll_require (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
int i;
lua_settop(L, 1); /* _LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, 2, name);
if (lua_toboolean(L, -1)) { /* is it there? */
if (lua_touserdata(L, -1) == &sentinel) /* check loops */
luaL_error(L, "loop or previous error loading module " LUA_QS, name);
return 1; /* package is already loaded */
}
/* else must load it; iterate over available loaders */
lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
if (!lua_istable(L, -1))
luaL_error(L, LUA_QL("package.loaders") " must be a table");
for (i=1; ; i++) {
lua_rawgeti(L, -1, i); /* get a loader */
if (lua_isnil(L, -1))
luaL_error(L, "module " LUA_QS " not found", name);
lua_pushstring(L, name);
lua_call(L, 1, 1); /* call it */
if (lua_isnil(L, -1)) lua_pop(L, 1); /* did not found module */
else break; /* module loaded successfully */
}
lua_pushlightuserdata(L, (void *)&sentinel);
lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
lua_pushstring(L, name); /* pass name as argument to module */
lua_call(L, 1, 1); /* run loaded module */
if (!lua_isnil(L, -1)) /* non-nil return? */
lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
lua_getfield(L, 2, name);
if (lua_touserdata(L, -1) == &sentinel) { /* module did not set a value? */
lua_pushboolean(L, 1); /* use true as result */
lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* _LOADED[name] = true */
}
return 1;
}
/* }====================================================== */
/*
** {======================================================
** 'module' function
** =======================================================
*/
static void setfenv (lua_State *L) {
lua_Debug ar;
lua_getstack(L, 1, &ar);
lua_getinfo(L, "f", &ar);
lua_pushvalue(L, -2);
lua_setfenv(L, -2);
lua_pop(L, 1);
}
static void dooptions (lua_State *L, int n) {
int i;
for (i = 2; i <= n; i++) {
lua_pushvalue(L, i); /* get option (a function) */
lua_pushvalue(L, -2); /* module */
lua_call(L, 1, 0);
}
}
static void modinit (lua_State *L, const char *modname) {
const char *dot;
lua_pushvalue(L, -1);
lua_setfield(L, -2, "_M"); /* module._M = module */
lua_pushstring(L, modname);
lua_setfield(L, -2, "_NAME");
dot = strrchr(modname, '.'); /* look for last dot in module name */
if (dot == NULL) dot = modname;
else dot++;
/* set _PACKAGE as package name (full module name minus last part) */
lua_pushlstring(L, modname, dot - modname);
lua_setfield(L, -2, "_PACKAGE");
}
static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
if (!lua_istable(L, -1)) { /* not found? */
lua_pop(L, 1); /* remove previous result */
/* try global variable (and create one if it does not exist) */
if (luaL_findtable(L, LUA_GLOBALSINDEX, modname) != NULL)
return luaL_error(L, "name conflict for module " LUA_QS, modname);
lua_pushvalue(L, -1);
lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
}
/* check whether table already has a _NAME field */
lua_getfield(L, -1, "_NAME");
if (!lua_isnil(L, -1)) /* is table an initialized module? */
lua_pop(L, 1);
else { /* no; initialize it */
lua_pop(L, 1);
modinit(L, modname);
}
lua_pushvalue(L, -1);
setfenv(L);
dooptions(L, loaded - 1);
return 0;
}
static int ll_seeall (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
if (!lua_getmetatable(L, 1)) {
lua_newtable(L); /* create new metatable */
lua_pushvalue(L, -1);
lua_setmetatable(L, 1);
}
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setfield(L, -2, "__index"); /* mt.__index = _G */
return 0;
}
/* }====================================================== */
/* auxiliary mark (for internal use) */
#define AUXMARK "\1"
static void setpath (lua_State *L, const char *fieldname, const char *envname,
const char *def) {
const char *path = getenv(envname);
if (path == NULL) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
LUA_PATHSEP AUXMARK LUA_PATHSEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2);
}
setprogdir(L);
lua_setfield(L, -2, fieldname);
}
static const luaL_Reg pk_funcs[] = {
{"loadlib", ll_loadlib},
{"seeall", ll_seeall},
{NULL, NULL}
};
static const luaL_Reg ll_funcs[] = {
{"module", ll_module},
{"require", ll_require},
{NULL, NULL}
};
static const lua_CFunction loaders[] =
{loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
LUALIB_API int luaopen_package (lua_State *L) {
int i;
/* create new type _LOADLIB */
luaL_newmetatable(L, "_LOADLIB");
lua_pushcfunction(L, gctm);
lua_setfield(L, -2, "__gc");
/* create `package' table */
luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
#if defined(LUA_COMPAT_LOADLIB)
lua_getfield(L, -1, "loadlib");
lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
#endif
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, "_PACKAGE");
lua_pushvalue(L, -1);
lua_replace(L, LUA_ENVIRONINDEX);
/* create `loaders' table */
lua_newtable(L);
/* fill it with pre-defined loaders */
for (i=0; loaders[i] != NULL; i++) {
lua_pushcfunction(L, loaders[i]);
lua_rawseti(L, -2, i+1);
}
lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
/* store config information */
lua_pushstring(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
LUA_EXECDIR "\n" LUA_IGMARK);
lua_setfield(L, -2, "config");
/* set field `loaded' */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_setfield(L, -2, "loaded");
/* set field `preload' */
lua_newtable(L);
lua_setfield(L, -2, "preload");
lua_pushvalue(L, LUA_GLOBALSINDEX);
luaL_register(L, NULL, ll_funcs); /* open lib into global table */
lua_pop(L, 1);
return 1; /* return 'package' table */
}
+212
View File
@@ -0,0 +1,212 @@
/*
** $Id: lobject.c,v 2.17 2005/07/31 17:11:50 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lobject_c
#define LUA_CORE
#include "lua.h"
#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "lvm.h"
const TValue luaO_nilobject = {{NULL}, LUA_TNIL};
/*
** converts an integer to a "floating point byte", represented as
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
** eeeee != 0 and (xxx) otherwise.
*/
int luaO_int2fb (unsigned int x) {
int e = 0; /* expoent */
while (x >= 16) {
x = (x+1) >> 1;
e++;
}
if (x < 8) return x;
else return ((e+1) << 3) | (cast(int, x) - 8);
}
/* converts back */
int luaO_fb2int (int x) {
int e = (x >> 3) & 31;
if (e == 0) return x;
else return ((x & 7)+8) << (e - 1);
}
int luaO_log2 (unsigned int x) {
static const lu_byte log_2[256] = {
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
int l = -1;
while (x >= 256) { l += 8; x >>= 8; }
return l + log_2[x];
}
int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
if (ttype(t1) != ttype(t2)) return 0;
else switch (ttype(t1)) {
case LUA_TNIL:
return 1;
case LUA_TNUMBER:
return luai_numeq(L, nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN:
return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
case LUA_TLIGHTUSERDATA:
return pvalue(t1) == pvalue(t2);
default:
lua_assert(iscollectable(t1));
return gcvalue(t1) == gcvalue(t2);
}
}
int luaO_str2d (const char *s, lua_Number *result) {
char *endptr;
*result = lua_str2number(s, &endptr);
if (endptr == s) return 0; /* conversion failed */
if (*endptr == '\0') return 1; /* most common case */
while (isspace(cast(unsigned char, *endptr))) endptr++;
if (*endptr != '\0') return 0; /* invalid trailing characters? */
return 1;
}
static void pushstr (lua_State *L, const char *str) {
setsvalue2s(L, L->top, luaS_new(L, str));
incr_top(L);
}
/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
int n = 1;
pushstr(L, "");
for (;;) {
const char *e = strchr(fmt, '%');
if (e == NULL) break;
setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
incr_top(L);
switch (*(e+1)) {
case 's': {
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
pushstr(L, s);
break;
}
case 'c': {
char buff[2];
buff[0] = cast(char, va_arg(argp, int));
buff[1] = '\0';
pushstr(L, buff);
break;
}
case 'd': {
setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));
incr_top(L);
break;
}
case 'f': {
setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));
incr_top(L);
break;
}
case 'p': {
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
sprintf(buff, "%p", va_arg(argp, void *));
pushstr(L, buff);
break;
}
case '%': {
pushstr(L, "%");
break;
}
default: {
char buff[3];
buff[0] = '%';
buff[1] = *(e+1);
buff[2] = '\0';
pushstr(L, buff);
break;
}
}
n += 2;
fmt = e+2;
}
pushstr(L, fmt);
luaV_concat(L, n+1, cast(int, L->top - L->base) - 1);
L->top -= n;
return svalue(L->top - 1);
}
const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
const char *msg;
va_list argp;
va_start(argp, fmt);
msg = luaO_pushvfstring(L, fmt, argp);
va_end(argp);
return msg;
}
void luaO_chunkid (char *out, const char *source, size_t bufflen) {
if (*source == '=') {
strncpy(out, source+1, bufflen); /* remove first char */
out[bufflen-1] = '\0'; /* ensures null termination */
}
else { /* out = "source", or "...source" */
if (*source == '@') {
size_t l;
source++; /* skip the `@' */
bufflen -= sizeof(" '...' ");
l = strlen(source);
strcpy(out, "");
if (l > bufflen) {
source += (l-bufflen); /* get last part of file name */
strcat(out, "...");
}
strcat(out, source);
}
else { /* out = [string "string"] */
size_t len = strcspn(source, "\n\r"); /* stop at first newline */
bufflen -= sizeof(" [string \"...\"] ");
if (len > bufflen) len = bufflen;
strcpy(out, "[string \"");
if (source[len] != '\0') { /* must truncate? */
strncat(out, source, len);
strcat(out, "...");
}
else
strcat(out, source);
strcat(out, "\"]");
}
}
}
+380
View File
@@ -0,0 +1,380 @@
/*
** $Id: lobject.h,v 2.16 2005/06/13 14:15:54 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
#ifndef lobject_h
#define lobject_h
#include <stdarg.h>
#include "llimits.h"
#include "lua.h"
/* tags for values visible from Lua */
#define LAST_TAG LUA_TTHREAD
#define NUM_TAGS (LAST_TAG+1)
/*
** Extra tags for non-values
*/
#define LUA_TPROTO (LAST_TAG+1)
#define LUA_TUPVAL (LAST_TAG+2)
#define LUA_TDEADKEY (LAST_TAG+3)
/*
** Union of all collectable objects
*/
typedef union GCObject GCObject;
/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
/*
** Common header in struct form
*/
typedef struct GCheader {
CommonHeader;
} GCheader;
/*
** Union of all Lua values
*/
typedef union {
GCObject *gc;
void *p;
lua_Number n;
int b;
} Value;
/*
** Tagged Values
*/
#define TValuefields Value value; int tt
typedef struct lua_TValue {
TValuefields;
} TValue;
/* Macros to test type */
#define ttisnil(o) (ttype(o) == LUA_TNIL)
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
#define ttisstring(o) (ttype(o) == LUA_TSTRING)
#define ttistable(o) (ttype(o) == LUA_TTABLE)
#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
/* Macros to access values */
#define ttype(o) ((o)->tt)
#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
#define tsvalue(o) (&rawtsvalue(o)->tsv)
#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
#define uvalue(o) (&rawuvalue(o)->uv)
#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
/*
** for internal debug only
*/
#define checkconsistency(obj) \
lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
#define checkliveness(g,obj) \
lua_assert(!iscollectable(obj) || \
((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
/* Macros to set values */
#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
#define setnvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
#define chgnvalue(obj,x) \
check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x))
#define setpvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
#define setbvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
#define setsvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
checkliveness(G(L),i_o); }
#define setuvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
checkliveness(G(L),i_o); }
#define setthvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
checkliveness(G(L),i_o); }
#define setclvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
checkliveness(G(L),i_o); }
#define sethvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
checkliveness(G(L),i_o); }
#define setptvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
checkliveness(G(L),i_o); }
#define setobj(L,obj1,obj2) \
{ const TValue *o2=(obj2); TValue *o1=(obj1); \
o1->value = o2->value; o1->tt=o2->tt; \
checkliveness(G(L),o1); }
/*
** different types of sets, according to destination
*/
/* from stack to (same) stack */
#define setobjs2s setobj
/* to stack (not from same stack) */
#define setobj2s setobj
#define setsvalue2s setsvalue
#define sethvalue2s sethvalue
#define setptvalue2s setptvalue
/* from table to same table */
#define setobjt2t setobj
/* to table */
#define setobj2t setobj
/* to new object */
#define setobj2n setobj
#define setsvalue2n setsvalue
#define setttype(obj, tt) (ttype(obj) = (tt))
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
typedef TValue *StkId; /* index to stack elements */
/*
** String headers for string table
*/
typedef union TString {
L_Umaxalign dummy; /* ensures maximum alignment for strings */
struct {
CommonHeader;
lu_byte reserved;
unsigned int hash;
size_t len;
} tsv;
} TString;
#define getstr(ts) cast(const char *, (ts) + 1)
#define svalue(o) getstr(tsvalue(o))
typedef union Udata {
L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct {
CommonHeader;
struct Table *metatable;
struct Table *env;
size_t len;
} uv;
} Udata;
/*
** Function Prototypes
*/
typedef struct Proto {
CommonHeader;
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines */
struct LocVar *locvars; /* information about local variables */
TString **upvalues; /* upvalue names */
TString *source;
int sizeupvalues;
int sizek; /* size of `k' */
int sizecode;
int sizelineinfo;
int sizep; /* size of `p' */
int sizelocvars;
int linedefined;
int lastlinedefined;
GCObject *gclist;
lu_byte nups; /* number of upvalues */
lu_byte numparams;
lu_byte is_vararg;
lu_byte maxstacksize;
} Proto;
/* masks for new-style vararg */
#define VARARG_HASARG 1
#define VARARG_ISVARARG 2
#define VARARG_NEEDSARG 4
typedef struct LocVar {
TString *varname;
int startpc; /* first point where variable is active */
int endpc; /* first point where variable is dead */
} LocVar;
/*
** Upvalues
*/
typedef struct UpVal {
CommonHeader;
TValue *v; /* points to stack or to its own value */
union {
TValue value; /* the value (when closed) */
struct { /* double linked list (when open) */
struct UpVal *prev;
struct UpVal *next;
} l;
} u;
} UpVal;
/*
** Closures
*/
#define ClosureHeader \
CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
struct Table *env
typedef struct CClosure {
ClosureHeader;
lua_CFunction f;
TValue upvalue[1];
} CClosure;
typedef struct LClosure {
ClosureHeader;
struct Proto *p;
UpVal *upvals[1];
} LClosure;
typedef union Closure {
CClosure c;
LClosure l;
} Closure;
#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
/*
** Tables
*/
typedef struct TKey {
TValuefields;
struct Node *next; /* for chaining */
} TKey;
typedef struct Node {
TValue i_val;
TKey i_key;
} Node;
typedef struct Table {
CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable;
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
GCObject *gclist;
int sizearray; /* size of `array' array */
} Table;
/*
** `module' operation for hashing (size is always a power of 2)
*/
#define lmod(s,size) \
check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))
#define twoto(x) (1<<(x))
#define sizenode(t) (twoto((t)->lsizenode))
LUAI_DATA const TValue luaO_nilobject;
#define ceillog2(x) (luaO_log2((x)-1) + 1)
LUAI_FUNC int luaO_log2 (unsigned int x);
LUAI_FUNC int luaO_int2fb (unsigned int x);
LUAI_FUNC int luaO_fb2int (int x);
LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
va_list argp);
LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
#endif
+104
View File
@@ -0,0 +1,104 @@
/*
** $Id: lopcodes.c,v 1.34 2005/05/20 15:53:42 roberto Exp $
** See Copyright Notice in lua.h
*/
#define lopcodes_c
#define LUA_CORE
#include "lua.h"
#include "lobject.h"
#include "lopcodes.h"
/* ORDER OP */
const char *const luaP_opnames[NUM_OPCODES+1] = {
"MOVE",
"LOADK",
"LOADBOOL",
"LOADNIL",
"GETUPVAL",
"GETGLOBAL",
"GETTABLE",
"SETGLOBAL",
"SETUPVAL",
"SETTABLE",
"NEWTABLE",
"SELF",
"ADD",
"SUB",
"MUL",
"DIV",
"MOD",
"POW",
"UNM",
"NOT",
"LEN",
"CONCAT",
"JMP",
"EQ",
"LT",
"LE",
"TEST",
"TESTSET",
"CALL",
"TAILCALL",
"RETURN",
"FORLOOP",
"FORPREP",
"TFORLOOP",
"SETLIST",
"CLOSE",
"CLOSURE",
"VARARG",
NULL
};
#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T A B C mode opcode */
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
,opmode(1, 0, OpArgR, OpArgU, iABC) /* OP_TEST */
,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
};
+268
View File
@@ -0,0 +1,268 @@
/*
** $Id: lopcodes.h,v 1.121 2005/06/06 13:30:25 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
#ifndef lopcodes_h
#define lopcodes_h
#include "llimits.h"
/*===========================================================================
We assume that instructions are unsigned numbers.
All instructions have an opcode in the first 6 bits.
Instructions can have the following fields:
`A' : 8 bits
`B' : 9 bits
`C' : 9 bits
`Bx' : 18 bits (`B' and `C' together)
`sBx' : signed Bx
A signed argument is represented in excess K; that is, the number
value is the unsigned value minus K. K is exactly the maximum value
for that argument (so that -max is represented by 0, and +max is
represented by 2*max), which is half the maximum for the corresponding
unsigned argument.
===========================================================================*/
enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
/*
** size and position of opcode arguments.
*/
#define SIZE_C 9
#define SIZE_B 9
#define SIZE_Bx (SIZE_C + SIZE_B)
#define SIZE_A 8
#define SIZE_OP 6
#define POS_OP 0
#define POS_A (POS_OP + SIZE_OP)
#define POS_C (POS_A + SIZE_A)
#define POS_B (POS_C + SIZE_C)
#define POS_Bx POS_C
/*
** limits for opcode arguments.
** we use (signed) int to manipulate most arguments,
** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
*/
#if SIZE_Bx < LUAI_BITSINT-1
#define MAXARG_Bx ((1<<SIZE_Bx)-1)
#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
#else
#define MAXARG_Bx MAX_INT
#define MAXARG_sBx MAX_INT
#endif
#define MAXARG_A ((1<<SIZE_A)-1)
#define MAXARG_B ((1<<SIZE_B)-1)
#define MAXARG_C ((1<<SIZE_C)-1)
/* creates a mask with `n' 1 bits at position `p' */
#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
/* creates a mask with `n' 0 bits at position `p' */
#define MASK0(n,p) (~MASK1(n,p))
/*
** the following macros help to manipulate instructions
*/
#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
| (cast(Instruction, a)<<POS_A) \
| (cast(Instruction, b)<<POS_B) \
| (cast(Instruction, c)<<POS_C))
#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
| (cast(Instruction, a)<<POS_A) \
| (cast(Instruction, bc)<<POS_Bx))
/*
** Macros to operate RK indices
*/
/* this bit 1 means constant (0 means register) */
#define BITRK (1 << (SIZE_B - 1))
/* test whether value is a constant */
#define ISK(x) ((x) & BITRK)
/* gets the index of the constant */
#define INDEXK(r) ((int)(r) & ~BITRK)
#define MAXINDEXRK (BITRK - 1)
/* code a constant index as a RK value */
#define RKASK(x) ((x) | BITRK)
/*
** invalid register that fits in 8 bits
*/
#define NO_REG MAXARG_A
/*
** R(x) - register
** Kst(x) - constant (in constant table)
** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
*/
/*
** grep "ORDER OP" if you change these enums
*/
typedef enum {
/*----------------------------------------------------------------------
name args description
------------------------------------------------------------------------*/
OP_MOVE,/* A B R(A) := R(B) */
OP_LOADK,/* A Bx R(A) := Kst(Bx) */
OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
OP_GETUPVAL,/* A B R(A) := UpValue[B] */
OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
OP_SETUPVAL,/* A B UpValue[B] := R(A) */
OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -R(B) */
OP_NOT,/* A B R(A) := not R(B) */
OP_LEN,/* A B R(A) := length of R(B) */
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
OP_JMP,/* sBx pc+=sBx */
OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then pc+=sBx */
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+2) ~= nil then pc++ */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
} OpCode;
#define NUM_OPCODES (cast(int, OP_VARARG+1))
/*===========================================================================
Notes:
(*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
and can be 0: OP_CALL then sets `top' to last_result+1, so
next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
(*) In OP_VARARG, if (B == 0) then use actual number of varargs and
set top (like in OP_CALL with C == 0).
(*) In OP_RETURN, if (B == 0) then return up to `top'
(*) In OP_SETLIST, if (B == 0) then B = `top';
if (C == 0) then next `instruction' is real C
(*) For comparisons, A specifies what condition the test should accept
(true or false).
(*) All `skips' (pc++) assume that next instruction is a jump
===========================================================================*/
/*
** masks for instruction properties. The format is:
** bits 0-1: op mode
** bits 2-3: C arg mode
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test
*/
enum OpArgMask {
OpArgN, /* argument is not used */
OpArgU, /* argument is used */
OpArgR, /* argument is a register or a jump offset */
OpArgK /* argument is a constant or register/constant */
};
LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
/* number of list items to accumulate before a SETLIST instruction */
#define LFIELDS_PER_FLUSH 50
#endif
+237
View File
@@ -0,0 +1,237 @@
/*
** $Id: loslib.c,v 1.12 2005/08/26 17:36:32 roberto Exp roberto $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
#include <errno.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define loslib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static int os_pushresult (lua_State *L, int i, const char *filename) {
if (i) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
if (filename)
lua_pushfstring(L, "%s: %s", filename, strerror(errno));
else
lua_pushfstring(L, "%s", strerror(errno));
lua_pushinteger(L, errno);
return 3;
}
}
static int io_execute (lua_State *L) {
lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
return 1;
}
static int io_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
return os_pushresult(L, remove(filename) == 0, filename);
}
static int io_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
return os_pushresult(L, rename(fromname, toname) == 0, fromname);
}
static int io_tmpname (lua_State *L) {
char buff[LUA_TMPNAMBUFSIZE];
int err;
lua_tmpnam(buff, err);
if (err)
return luaL_error(L, "unable to generate a unique filename");
lua_pushstring(L, buff);
return 1;
}
static int io_getenv (lua_State *L) {
lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
return 1;
}
static int io_clock (lua_State *L) {
lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
return 1;
}
/*
** {======================================================
** Time/Date operations
** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
** wday=%w+1, yday=%j, isdst=? }
** =======================================================
*/
static void setfield (lua_State *L, const char *key, int value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
}
static void setboolfield (lua_State *L, const char *key, int value) {
if (value < 0) /* undefined? */
return; /* does not set field */
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}
static int getboolfield (lua_State *L, const char *key) {
int res;
lua_getfield(L, -1, key);
res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
static int getfield (lua_State *L, const char *key, int d) {
int res;
lua_getfield(L, -1, key);
if (lua_isnumber(L, -1))
res = (int)lua_tointeger(L, -1);
else {
if (d < 0)
return luaL_error(L, "field " LUA_QS " missing in date table", key);
res = d;
}
lua_pop(L, 1);
return res;
}
static int io_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
lua_Number n = luaL_optnumber(L, 2, -1);
time_t t = (n == -1) ? time(NULL) : (time_t)n;
struct tm *stm;
if (*s == '!') { /* UTC? */
stm = gmtime(&t);
s++; /* skip `!' */
}
else
stm = localtime(&t);
if (stm == NULL) /* invalid date? */
lua_pushnil(L);
else if (strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
setfield(L, "sec", stm->tm_sec);
setfield(L, "min", stm->tm_min);
setfield(L, "hour", stm->tm_hour);
setfield(L, "day", stm->tm_mday);
setfield(L, "month", stm->tm_mon+1);
setfield(L, "year", stm->tm_year+1900);
setfield(L, "wday", stm->tm_wday+1);
setfield(L, "yday", stm->tm_yday+1);
setboolfield(L, "isdst", stm->tm_isdst);
}
else {
char b[256];
if (strftime(b, sizeof(b), s, stm))
lua_pushstring(L, b);
else
return luaL_error(L, LUA_QL("date") " format too long");
}
return 1;
}
static int io_time (lua_State *L) {
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL); /* get current time */
else {
struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); /* make sure table is at the top */
ts.tm_sec = getfield(L, "sec", 0);
ts.tm_min = getfield(L, "min", 0);
ts.tm_hour = getfield(L, "hour", 12);
ts.tm_mday = getfield(L, "day", -1);
ts.tm_mon = getfield(L, "month", -1) - 1;
ts.tm_year = getfield(L, "year", -1) - 1900;
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
}
if (t == (time_t)(-1))
lua_pushnil(L);
else
lua_pushnumber(L, t);
return 1;
}
static int io_difftime (lua_State *L) {
lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
(time_t)(luaL_optnumber(L, 2, 0))));
return 1;
}
/* }====================================================== */
static int io_setloc (lua_State *L) {
static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
LC_NUMERIC, LC_TIME};
static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
"numeric", "time", NULL};
const char *l = lua_tostring(L, 1);
int op = luaL_checkoption(L, 2, "all", catnames);
luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected");
lua_pushstring(L, setlocale(cat[op], l));
return 1;
}
static int io_exit (lua_State *L) {
exit(luaL_optint(L, 1, EXIT_SUCCESS));
return 0; /* to avoid warnings */
}
static const luaL_Reg syslib[] = {
{"clock", io_clock},
{"date", io_date},
{"difftime", io_difftime},
{"execute", io_execute},
{"exit", io_exit},
{"getenv", io_getenv},
{"remove", io_remove},
{"rename", io_rename},
{"setlocale", io_setloc},
{"time", io_time},
{"tmpname", io_tmpname},
{NULL, NULL}
};
/* }====================================================== */
LUALIB_API int luaopen_os (lua_State *L) {
luaL_register(L, LUA_OSLIBNAME, syslib);
return 1;
}
+1353
View File
File diff suppressed because it is too large Load Diff
+79
View File
@@ -0,0 +1,79 @@
/*
** $Id: lparser.h,v 1.54 2005/03/09 16:28:07 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
#ifndef lparser_h
#define lparser_h
#include "llimits.h"
#include "lobject.h"
#include "ltable.h"
#include "lzio.h"
/*
** Expression descriptor
*/
typedef enum {
VVOID, /* no value */
VNIL,
VTRUE,
VFALSE,
VK, /* info = index of constant in `k' */
VLOCAL, /* info = local register */
VUPVAL, /* info = index of upvalue in `upvalues' */
VGLOBAL, /* info = index of table; aux = index of global name in `k' */
VINDEXED, /* info = table register; aux = index register (or `k') */
VJMP, /* info = instruction pc */
VRELOCABLE, /* info = instruction pc */
VNONRELOC, /* info = result register */
VCALL, /* info = instruction pc */
VVARARG /* info = instruction pc */
} expkind;
typedef struct expdesc {
expkind k;
int info, aux;
int t; /* patch list of `exit when true' */
int f; /* patch list of `exit when false' */
} expdesc;
typedef struct upvaldesc {
lu_byte k;
lu_byte info;
} upvaldesc;
struct BlockCnt; /* defined in lparser.c */
/* state needed to generate code for a given function */
typedef struct FuncState {
Proto *f; /* current function header */
Table *h; /* table to find (and reuse) elements in `k' */
struct FuncState *prev; /* enclosing function */
struct LexState *ls; /* lexical state */
struct lua_State *L; /* copy of the Lua state */
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to `ncode') */
int lasttarget; /* `pc' of last `jump target' */
int jpc; /* list of pending jumps to `pc' */
int freereg; /* first free register */
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
short nlocvars; /* number of elements in `locvars' */
lu_byte nactvar; /* number of active local variables */
upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
} FuncState;
LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
const char *name);
#endif
+212
View File
@@ -0,0 +1,212 @@
/*
** $Id: lstate.c,v 2.32 2005/06/03 20:15:58 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define lstate_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
/*
** Main thread combines a thread state and the global state
*/
typedef struct LG {
lua_State l;
global_State g;
} LG;
static void stack_init (lua_State *L1, lua_State *L) {
/* initialize CallInfo array */
L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
L1->ci = L1->base_ci;
L1->size_ci = BASIC_CI_SIZE;
L1->end_ci = L1->base_ci + L1->size_ci - 1;
/* initialize stack array */
L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
L1->top = L1->stack;
L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
/* initialize first ci */
L1->ci->func = L1->top;
setnilvalue(L1->top++); /* `function' entry for this `ci' */
L1->base = L1->ci->base = L1->top;
L1->ci->top = L1->top + LUA_MINSTACK;
}
static void freestack (lua_State *L, lua_State *L1) {
luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
luaM_freearray(L, L1->stack, L1->stacksize, TValue);
}
/*
** open parts that may cause memory-allocation errors
*/
static void f_luaopen (lua_State *L, void *ud) {
global_State *g = G(L);
UNUSED(ud);
stack_init(L, L); /* init stack */
sethvalue(L, gt(L), luaH_new(L, 0, 20)); /* table of globals */
sethvalue(L, registry(L), luaH_new(L, 6, 20)); /* registry */
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
luaX_init(L);
luaS_fix(luaS_newliteral(L, MEMERRMSG));
g->GCthreshold = 4*g->totalbytes;
}
static void preinit_state (lua_State *L, global_State *g) {
G(L) = g;
L->stack = NULL;
L->stacksize = 0;
L->errorJmp = NULL;
L->hook = NULL;
L->hookmask = 0;
L->basehookcount = 0;
L->allowhook = 1;
resethookcount(L);
L->openupval = NULL;
L->size_ci = 0;
L->nCcalls = 0;
L->status = 0;
L->base_ci = L->ci = NULL;
L->savedpc = NULL;
L->errfunc = 0;
setnilvalue(gt(L));
}
static void close_state (lua_State *L) {
global_State *g = G(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_freeall(L); /* collect all objects */
lua_assert(g->rootgc == obj2gco(L));
lua_assert(g->strt.nuse == 0);
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
luaZ_freebuffer(L, &g->buff);
freestack(L, L);
lua_assert(g->totalbytes == sizeof(LG));
(*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
}
lua_State *luaE_newthread (lua_State *L) {
lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
luaC_link(L, obj2gco(L1), LUA_TTHREAD);
preinit_state(L1, G(L));
stack_init(L1, L); /* init stack */
setobj2n(L, gt(L1), gt(L)); /* share table of globals */
L1->hookmask = L->hookmask;
L1->basehookcount = L->basehookcount;
L1->hook = L->hook;
resethookcount(L1);
lua_assert(iswhite(obj2gco(L1)));
return L1;
}
void luaE_freethread (lua_State *L, lua_State *L1) {
luaF_close(L1, L1->stack); /* close all upvalues for this thread */
lua_assert(L1->openupval == NULL);
freestack(L, L1);
luaM_freemem(L, fromstate(L1), state_size(lua_State));
}
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
int i;
lua_State *L;
global_State *g;
void *l = (*f)(ud, NULL, 0, state_size(LG));
if (l == NULL) return NULL;
L = tostate(l);
g = &((LG *)L)->g;
L->next = NULL;
L->tt = LUA_TTHREAD;
g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
L->marked = luaC_white(g);
set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
preinit_state(L, g);
g->frealloc = f;
g->ud = ud;
g->mainthread = L;
g->uvhead.u.l.prev = &g->uvhead;
g->uvhead.u.l.next = &g->uvhead;
g->GCthreshold = 0; /* mark it as unfinished state */
g->strt.size = 0;
g->strt.nuse = 0;
g->strt.hash = NULL;
setnilvalue(registry(L));
luaZ_initbuffer(L, &g->buff);
g->panic = NULL;
g->gcstate = GCSpause;
g->rootgc = obj2gco(L);
g->sweepstrgc = 0;
g->sweepgc = &g->rootgc;
g->gray = NULL;
g->grayagain = NULL;
g->weak = NULL;
g->tmudata = NULL;
g->totalbytes = sizeof(LG);
g->gcpause = LUAI_GCPAUSE;
g->gcstepmul = LUAI_GCMUL;
g->gcdept = 0;
for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
/* memory allocation error: free partial state */
close_state(L);
L = NULL;
}
else
luai_userstateopen(L);
return L;
}
static void callallgcTM (lua_State *L, void *ud) {
UNUSED(ud);
luaC_callGCTM(L); /* call GC metamethods for all udata */
}
LUA_API void lua_close (lua_State *L) {
lua_lock(L);
L = G(L)->mainthread; /* only the main thread can be closed */
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
L->errfunc = 0; /* no error function during GC metamethods */
do { /* repeat until no more errors */
L->ci = L->base_ci;
L->base = L->top = L->ci->base;
L->nCcalls = 0;
} while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
lua_assert(G(L)->tmudata == NULL);
close_state(L);
}
+168
View File
@@ -0,0 +1,168 @@
/*
** $Id: lstate.h,v 2.22 2005/06/03 20:15:58 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
#ifndef lstate_h
#define lstate_h
#include "lua.h"
#include "lobject.h"
#include "ltm.h"
#include "lzio.h"
struct lua_longjmp; /* defined in ldo.c */
/* table of globals */
#define gt(L) (&L->l_gt)
/* registry */
#define registry(L) (&G(L)->l_registry)
/* extra stack space to handle TM calls and some other extras */
#define EXTRA_STACK 5
#define BASIC_CI_SIZE 8
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
typedef struct stringtable {
GCObject **hash;
lu_int32 nuse; /* number of elements */
int size;
} stringtable;
/*
** informations about a call
*/
typedef struct CallInfo {
StkId base; /* base for this function */
StkId func; /* function index in the stack */
StkId top; /* top for this function */
int nresults; /* expected number of results from this function */
const Instruction *savedpc;
int tailcalls; /* number of tail calls lost under this entry */
} CallInfo;
#define curr_func(L) (clvalue(L->ci->func))
#define ci_func(ci) (clvalue((ci)->func))
#define f_isLua(ci) (!ci_func(ci)->c.isC)
#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
/*
** `global state', shared by all threads of this state
*/
typedef struct global_State {
stringtable strt; /* hash table for strings */
lua_Alloc frealloc; /* function to reallocate memory */
void *ud; /* auxiliary data to `frealloc' */
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
GCObject *rootgc; /* list of all collectable objects */
GCObject **sweepgc; /* position of sweep in `rootgc' */
int sweepstrgc; /* position of sweep in `strt' */
GCObject *gray; /* list of gray objects */
GCObject *grayagain; /* list of objects to be traversed atomically */
GCObject *weak; /* list of weak tables (to be cleared) */
GCObject *tmudata; /* last element of list of userdata to be GC */
Mbuffer buff; /* temporary buffer for string concatentation */
lu_mem GCthreshold;
lu_mem totalbytes; /* number of bytes currently allocated */
lu_mem estimate; /* an estimate of number of bytes actually in use */
lu_mem gcdept; /* how much GC is `behind schedule' */
int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC `granularity' */
lua_CFunction panic; /* to be called in unprotected errors */
TValue l_registry;
struct lua_State *mainthread;
UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */
} global_State;
/*
** `per thread' state
*/
struct lua_State {
CommonHeader;
StkId top; /* first free slot in the stack */
StkId base; /* base of current function */
global_State *l_G;
CallInfo *ci; /* call info for current function */
const Instruction *savedpc; /* `savedpc' of current function */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
int stacksize;
CallInfo *end_ci; /* points after end of ci array*/
CallInfo *base_ci; /* array of CallInfo's */
int size_ci; /* size of array `base_ci' */
unsigned short nCcalls; /* number of nested C calls */
lu_byte hookmask;
lu_byte allowhook;
lu_byte status;
int basehookcount;
int hookcount;
lua_Hook hook;
TValue l_gt; /* table of globals */
TValue env; /* temporary place for environments */
GCObject *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
struct lua_longjmp *errorJmp; /* current error recover point */
ptrdiff_t errfunc; /* current error handling function (stack index) */
};
#define G(L) (L->l_G)
/*
** Union of all collectable objects
*/
union GCObject {
GCheader gch;
union TString ts;
union Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct UpVal uv;
struct lua_State th; /* thread */
};
/* macros to convert a GCObject into a specific value */
#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
#define gco2ts(o) (&rawgco2ts(o)->tsv)
#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
#define gco2u(o) (&rawgco2u(o)->uv)
#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
#define ngcotouv(o) \
check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
/* macro to convert any Lua object into a GCObject */
#define obj2gco(v) (cast(GCObject *, (v)))
LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
#endif
+111
View File
@@ -0,0 +1,111 @@
/*
** $Id: lstring.c,v 2.6 2005/01/18 17:18:09 roberto Exp roberto $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
#include <string.h>
#define lstring_c
#define LUA_CORE
#include "lua.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
void luaS_resize (lua_State *L, int newsize) {
GCObject **newhash;
stringtable *tb;
int i;
if (G(L)->gcstate == GCSsweepstring)
return; /* cannot resize during GC traverse */
newhash = luaM_newvector(L, newsize, GCObject *);
tb = &G(L)->strt;
for (i=0; i<newsize; i++) newhash[i] = NULL;
/* rehash */
for (i=0; i<tb->size; i++) {
GCObject *p = tb->hash[i];
while (p) { /* for each node in the list */
GCObject *next = p->gch.next; /* save next */
unsigned int h = gco2ts(p)->hash;
int h1 = lmod(h, newsize); /* new position */
lua_assert(cast(int, h%newsize) == lmod(h, newsize));
p->gch.next = newhash[h1]; /* chain it */
newhash[h1] = p;
p = next;
}
}
luaM_freearray(L, tb->hash, tb->size, TString *);
tb->size = newsize;
tb->hash = newhash;
}
static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h) {
TString *ts;
stringtable *tb;
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L);
ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
ts->tsv.len = l;
ts->tsv.hash = h;
ts->tsv.marked = luaC_white(G(L));
ts->tsv.tt = LUA_TSTRING;
ts->tsv.reserved = 0;
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
tb = &G(L)->strt;
h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h]; /* chain new entry */
tb->hash[h] = obj2gco(ts);
tb->nuse++;
if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */
return ts;
}
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
GCObject *o;
unsigned int h = cast(unsigned int, l); /* seed */
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
size_t l1;
for (l1=l; l1>=step; l1-=step) /* compute hash */
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
o != NULL;
o = o->gch.next) {
TString *ts = rawgco2ts(o);
if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
/* string may be dead */
if (isdead(G(L), o)) changewhite(o);
return ts;
}
}
return newlstr(L, str, l, h); /* not found */
}
Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
Udata *u;
if (s > MAX_SIZET - sizeof(Udata))
luaM_toobig(L);
u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
u->uv.marked = luaC_white(G(L)); /* is not finalized */
u->uv.tt = LUA_TUSERDATA;
u->uv.len = s;
u->uv.metatable = NULL;
u->uv.env = e;
/* chain it on udata list (after main thread) */
u->uv.next = G(L)->mainthread->next;
G(L)->mainthread->next = obj2gco(u);
return u;
}
+31
View File
@@ -0,0 +1,31 @@
/*
** $Id: lstring.h,v 1.42 2005/02/23 17:30:22 roberto Exp roberto $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
#ifndef lstring_h
#define lstring_h
#include "lgc.h"
#include "lobject.h"
#include "lstate.h"
#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
#endif
+829
View File
@@ -0,0 +1,829 @@
/*
** $Id: lstrlib.c,v 1.122 2005/08/15 14:12:32 roberto Exp roberto $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lstrlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))
static int str_len (lua_State *L) {
size_t l;
luaL_checklstring(L, 1, &l);
lua_pushinteger(L, l);
return 1;
}
static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
/* relative string position: negative means back from end */
return (pos>=0) ? pos : (ptrdiff_t)len+pos+1;
}
static int str_sub (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
if (start < 1) start = 1;
if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
if (start <= end)
lua_pushlstring(L, s+start-1, end-start+1);
else lua_pushliteral(L, "");
return 1;
}
static int str_reverse (lua_State *L) {
size_t l;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &l);
luaL_buffinit(L, &b);
while (l--) luaL_addchar(&b, s[l]);
luaL_pushresult(&b);
return 1;
}
static int str_lower (lua_State *L) {
size_t l;
size_t i;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &l);
luaL_buffinit(L, &b);
for (i=0; i<l; i++)
luaL_addchar(&b, tolower(uchar(s[i])));
luaL_pushresult(&b);
return 1;
}
static int str_upper (lua_State *L) {
size_t l;
size_t i;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &l);
luaL_buffinit(L, &b);
for (i=0; i<l; i++)
luaL_addchar(&b, toupper(uchar(s[i])));
luaL_pushresult(&b);
return 1;
}
static int str_rep (lua_State *L) {
size_t l;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &l);
int n = luaL_checkint(L, 2);
luaL_buffinit(L, &b);
while (n-- > 0)
luaL_addlstring(&b, s, l);
luaL_pushresult(&b);
return 1;
}
static int str_byte (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
int n, i;
if (posi <= 0) posi = 1;
if ((size_t)pose > l) pose = l;
if (posi > pose) return 0; /* empty interval; return no values */
n = pose - posi + 1;
luaL_checkstack(L, n, "string slice too long");
for (i=0; i<n; i++)
lua_pushinteger(L, uchar(s[posi+i-1]));
return n;
}
static int str_char (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
luaL_Buffer b;
luaL_buffinit(L, &b);
for (i=1; i<=n; i++) {
int c = luaL_checkint(L, i);
luaL_argcheck(L, uchar(c) == c, i, "invalid value");
luaL_addchar(&b, uchar(c));
}
luaL_pushresult(&b);
return 1;
}
static int writer (lua_State *L, const void* b, size_t size, void* B) {
(void)L;
luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
return 0;
}
static int str_dump (lua_State *L) {
luaL_Buffer b;
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, 1);
luaL_buffinit(L,&b);
if (lua_dump(L, writer, &b) != 0)
luaL_error(L, "unable to dump given function");
luaL_pushresult(&b);
return 1;
}
/*
** {======================================================
** PATTERN MATCHING
** =======================================================
*/
#define CAP_UNFINISHED (-1)
#define CAP_POSITION (-2)
typedef struct MatchState {
const char *src_init; /* init of source string */
const char *src_end; /* end (`\0') of source string */
lua_State *L;
int level; /* total number of captures (finished or unfinished) */
struct {
const char *init;
ptrdiff_t len;
} capture[LUA_MAXCAPTURES];
} MatchState;
#define L_ESC '%'
#define SPECIALS "^$*+?.([%-"
static int check_capture (MatchState *ms, int l) {
l -= '1';
if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
return luaL_error(ms->L, "invalid capture index");
return l;
}
static int capture_to_close (MatchState *ms) {
int level = ms->level;
for (level--; level>=0; level--)
if (ms->capture[level].len == CAP_UNFINISHED) return level;
return luaL_error(ms->L, "invalid pattern capture");
}
static const char *classend (MatchState *ms, const char *p) {
switch (*p++) {
case L_ESC: {
if (*p == '\0')
luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
return p+1;
}
case '[': {
if (*p == '^') p++;
do { /* look for a `]' */
if (*p == '\0')
luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
if (*(p++) == L_ESC && *p != '\0')
p++; /* skip escapes (e.g. `%]') */
} while (*p != ']');
return p+1;
}
default: {
return p;
}
}
}
static int match_class (int c, int cl) {
int res;
switch (tolower(cl)) {
case 'a' : res = isalpha(c); break;
case 'c' : res = iscntrl(c); break;
case 'd' : res = isdigit(c); break;
case 'l' : res = islower(c); break;
case 'p' : res = ispunct(c); break;
case 's' : res = isspace(c); break;
case 'u' : res = isupper(c); break;
case 'w' : res = isalnum(c); break;
case 'x' : res = isxdigit(c); break;
case 'z' : res = (c == 0); break;
default: return (cl == c);
}
return (islower(cl) ? res : !res);
}
static int matchbracketclass (int c, const char *p, const char *ec) {
int sig = 1;
if (*(p+1) == '^') {
sig = 0;
p++; /* skip the `^' */
}
while (++p < ec) {
if (*p == L_ESC) {
p++;
if (match_class(c, uchar(*p)))
return sig;
}
else if ((*(p+1) == '-') && (p+2 < ec)) {
p+=2;
if (uchar(*(p-2)) <= c && c <= uchar(*p))
return sig;
}
else if (uchar(*p) == c) return sig;
}
return !sig;
}
static int singlematch (int c, const char *p, const char *ep) {
switch (*p) {
case '.': return 1; /* matches any char */
case L_ESC: return match_class(c, uchar(*(p+1)));
case '[': return matchbracketclass(c, p, ep-1);
default: return (uchar(*p) == c);
}
}
static const char *match (MatchState *ms, const char *s, const char *p);
static const char *matchbalance (MatchState *ms, const char *s,
const char *p) {
if (*p == 0 || *(p+1) == 0)
luaL_error(ms->L, "unbalanced pattern");
if (*s != *p) return NULL;
else {
int b = *p;
int e = *(p+1);
int cont = 1;
while (++s < ms->src_end) {
if (*s == e) {
if (--cont == 0) return s+1;
}
else if (*s == b) cont++;
}
}
return NULL; /* string ends out of balance */
}
static const char *max_expand (MatchState *ms, const char *s,
const char *p, const char *ep) {
ptrdiff_t i = 0; /* counts maximum expand for item */
while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
i++;
/* keeps trying to match with the maximum repetitions */
while (i>=0) {
const char *res = match(ms, (s+i), ep+1);
if (res) return res;
i--; /* else didn't match; reduce 1 repetition to try again */
}
return NULL;
}
static const char *min_expand (MatchState *ms, const char *s,
const char *p, const char *ep) {
for (;;) {
const char *res = match(ms, s, ep+1);
if (res != NULL)
return res;
else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
s++; /* try with one more repetition */
else return NULL;
}
}
static const char *start_capture (MatchState *ms, const char *s,
const char *p, int what) {
const char *res;
int level = ms->level;
if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
ms->capture[level].init = s;
ms->capture[level].len = what;
ms->level = level+1;
if ((res=match(ms, s, p)) == NULL) /* match failed? */
ms->level--; /* undo capture */
return res;
}
static const char *end_capture (MatchState *ms, const char *s,
const char *p) {
int l = capture_to_close(ms);
const char *res;
ms->capture[l].len = s - ms->capture[l].init; /* close capture */
if ((res = match(ms, s, p)) == NULL) /* match failed? */
ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
return res;
}
static const char *match_capture (MatchState *ms, const char *s, int l) {
size_t len;
l = check_capture(ms, l);
len = ms->capture[l].len;
if ((size_t)(ms->src_end-s) >= len &&
memcmp(ms->capture[l].init, s, len) == 0)
return s+len;
else return NULL;
}
static const char *match (MatchState *ms, const char *s, const char *p) {
init: /* using goto's to optimize tail recursion */
switch (*p) {
case '(': { /* start capture */
if (*(p+1) == ')') /* position capture? */
return start_capture(ms, s, p+2, CAP_POSITION);
else
return start_capture(ms, s, p+1, CAP_UNFINISHED);
}
case ')': { /* end capture */
return end_capture(ms, s, p+1);
}
case L_ESC: {
switch (*(p+1)) {
case 'b': { /* balanced string? */
s = matchbalance(ms, s, p+2);
if (s == NULL) return NULL;
p+=4; goto init; /* else return match(ms, s, p+4); */
}
case 'f': { /* frontier? */
const char *ep; char previous;
p += 2;
if (*p != '[')
luaL_error(ms->L, "missing " LUA_QL("[") " after "
LUA_QL("%%f") " in pattern");
ep = classend(ms, p); /* points to what is next */
previous = (s == ms->src_init) ? '\0' : *(s-1);
if (matchbracketclass(uchar(previous), p, ep-1) ||
!matchbracketclass(uchar(*s), p, ep-1)) return NULL;
p=ep; goto init; /* else return match(ms, s, ep); */
}
default: {
if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
s = match_capture(ms, s, uchar(*(p+1)));
if (s == NULL) return NULL;
p+=2; goto init; /* else return match(ms, s, p+2) */
}
goto dflt; /* case default */
}
}
}
case '\0': { /* end of pattern */
return s; /* match succeeded */
}
case '$': {
if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
return (s == ms->src_end) ? s : NULL; /* check end of string */
else goto dflt;
}
default: dflt: { /* it is a pattern item */
const char *ep = classend(ms, p); /* points to what is next */
int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
switch (*ep) {
case '?': { /* optional */
const char *res;
if (m && ((res=match(ms, s+1, ep+1)) != NULL))
return res;
p=ep+1; goto init; /* else return match(ms, s, ep+1); */
}
case '*': { /* 0 or more repetitions */
return max_expand(ms, s, p, ep);
}
case '+': { /* 1 or more repetitions */
return (m ? max_expand(ms, s+1, p, ep) : NULL);
}
case '-': { /* 0 or more repetitions (minimum) */
return min_expand(ms, s, p, ep);
}
default: {
if (!m) return NULL;
s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
}
}
}
}
}
static const char *lmemfind (const char *s1, size_t l1,
const char *s2, size_t l2) {
if (l2 == 0) return s1; /* empty strings are everywhere */
else if (l2 > l1) return NULL; /* avoids a negative `l1' */
else {
const char *init; /* to search for a `*s2' inside `s1' */
l2--; /* 1st char will be checked by `memchr' */
l1 = l1-l2; /* `s2' cannot be found after that */
while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
init++; /* 1st char is already checked */
if (memcmp(init, s2+1, l2) == 0)
return init-1;
else { /* correct `l1' and `s1' to try again */
l1 -= init-s1;
s1 = init;
}
}
return NULL; /* not found */
}
}
static void push_onecapture (MatchState *ms, int i) {
ptrdiff_t l = ms->capture[i].len;
if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
if (l == CAP_POSITION)
lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
else
lua_pushlstring(ms->L, ms->capture[i].init, l);
}
static int push_captures (MatchState *ms, const char *s, const char *e) {
int i;
luaL_checkstack(ms->L, ms->level, "too many captures");
if (ms->level == 0 && s) { /* no explicit captures? */
lua_pushlstring(ms->L, s, e-s); /* return whole match */
return 1;
}
else { /* return all captures */
for (i=0; i<ms->level; i++)
push_onecapture(ms, i);
return ms->level; /* number of strings pushed */
}
}
static int str_find_aux (lua_State *L, int find) {
size_t l1, l2;
const char *s = luaL_checklstring(L, 1, &l1);
const char *p = luaL_checklstring(L, 2, &l2);
ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
if (init < 0) init = 0;
else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
if (find && (lua_toboolean(L, 4) || /* explicit request? */
strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
/* do a plain search */
const char *s2 = lmemfind(s+init, l1-init, p, l2);
if (s2) {
lua_pushinteger(L, s2-s+1);
lua_pushinteger(L, s2-s+l2);
return 2;
}
}
else {
MatchState ms;
int anchor = (*p == '^') ? (p++, 1) : 0;
const char *s1=s+init;
ms.L = L;
ms.src_init = s;
ms.src_end = s+l1;
do {
const char *res;
ms.level = 0;
if ((res=match(&ms, s1, p)) != NULL) {
if (find) {
lua_pushinteger(L, s1-s+1); /* start */
lua_pushinteger(L, res-s); /* end */
#if defined(LUA_COMPAT_FIND)
return push_captures(&ms, NULL, 0) + 2;
#else
return 2;
#endif
}
else
return push_captures(&ms, s1, res);
}
} while (s1++ < ms.src_end && !anchor);
}
lua_pushnil(L); /* not found */
return 1;
}
static int str_find (lua_State *L) {
return str_find_aux(L, 1);
}
static int str_match (lua_State *L) {
return str_find_aux(L, 0);
}
static int gmatch_aux (lua_State *L) {
MatchState ms;
size_t ls;
const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
const char *p = lua_tostring(L, lua_upvalueindex(2));
const char *src;
ms.L = L;
ms.src_init = s;
ms.src_end = s+ls;
for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
src <= ms.src_end;
src++) {
const char *e;
ms.level = 0;
if ((e = match(&ms, src, p)) != NULL) {
lua_Integer newstart = e-s;
if (e == src) newstart++; /* empty match? go at least one position */
lua_pushinteger(L, newstart);
lua_replace(L, lua_upvalueindex(3));
return push_captures(&ms, src, e);
}
}
return 0; /* not found */
}
static int gmatch (lua_State *L) {
luaL_checkstring(L, 1);
luaL_checkstring(L, 2);
lua_settop(L, 2);
lua_pushinteger(L, 0);
lua_pushcclosure(L, gmatch_aux, 3);
return 1;
}
static int gfind_nodef (lua_State *L) {
return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
LUA_QL("string.gmatch"));
}
static void add_s (MatchState *ms, luaL_Buffer *b,
const char *s, const char *e) {
lua_State *L = ms->L;
if (lua_isstring(L, 3)) {
size_t l;
const char *news = lua_tolstring(L, 3, &l);
size_t i;
for (i=0; i<l; i++) {
if (news[i] != L_ESC)
luaL_addchar(b, news[i]);
else {
i++; /* skip ESC */
if (!isdigit(uchar(news[i])))
luaL_addchar(b, news[i]);
else {
if (news[i] == '0')
lua_pushlstring(L, s, e - s); /* add whole match */
else {
int level = check_capture(ms, news[i]);
push_onecapture(ms, level);
}
luaL_addvalue(b); /* add capture to accumulated result */
}
}
}
}
else { /* is a function */
int n;
lua_pushvalue(L, 3);
n = push_captures(ms, s, e);
lua_call(L, n, 1);
if (lua_isstring(L, -1))
luaL_addvalue(b); /* add return to accumulated result */
else
lua_pop(L, 1); /* function result is not a string: pop it */
}
}
static int str_gsub (lua_State *L) {
size_t srcl;
const char *src = luaL_checklstring(L, 1, &srcl);
const char *p = luaL_checkstring(L, 2);
int max_s = luaL_optint(L, 4, srcl+1);
int anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0;
MatchState ms;
luaL_Buffer b;
luaL_argcheck(L,
lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
3, "string or function expected");
luaL_buffinit(L, &b);
ms.L = L;
ms.src_init = src;
ms.src_end = src+srcl;
while (n < max_s) {
const char *e;
ms.level = 0;
e = match(&ms, src, p);
if (e) {
n++;
add_s(&ms, &b, src, e);
}
if (e && e>src) /* non empty match? */
src = e; /* skip it */
else if (src < ms.src_end)
luaL_addchar(&b, *src++);
else break;
if (anchor) break;
}
luaL_addlstring(&b, src, ms.src_end-src);
luaL_pushresult(&b);
lua_pushinteger(L, n); /* number of substitutions */
return 2;
}
/* }====================================================== */
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
#define MAX_ITEM 512
/* maximum size of each format specification (such as '%-099.99d') */
#define MAX_FORMAT 20
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
luaL_addchar(b, '"');
while (l--) {
switch (*s) {
case '"': case '\\': case '\n': {
luaL_addchar(b, '\\');
luaL_addchar(b, *s);
break;
}
case '\0': {
luaL_addlstring(b, "\\000", 4);
break;
}
default: {
luaL_addchar(b, *s);
break;
}
}
s++;
}
luaL_addchar(b, '"');
}
static const char *scanformat (lua_State *L, const char *strfrmt,
char *form, int *hasprecision) {
const char *p = strfrmt;
while (strchr("-+ #0", *p)) p++; /* skip flags */
if (isdigit(uchar(*p))) p++; /* skip width */
if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
if (*p == '.') {
p++;
*hasprecision = 1;
if (isdigit(uchar(*p))) p++; /* skip precision */
if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
}
if (isdigit(uchar(*p)))
luaL_error(L, "invalid format (width or precision too long)");
if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */
luaL_error(L, "invalid format (too long)");
form[0] = L_ESC;
strncpy(form+1, strfrmt, p-strfrmt+1);
form[p-strfrmt+2] = 0;
return p;
}
static int str_format (lua_State *L) {
int arg = 1;
size_t sfl;
const char *strfrmt = luaL_checklstring(L, arg, &sfl);
const char *strfrmt_end = strfrmt+sfl;
luaL_Buffer b;
luaL_buffinit(L, &b);
while (strfrmt < strfrmt_end) {
if (*strfrmt != L_ESC)
luaL_addchar(&b, *strfrmt++);
else if (*++strfrmt == L_ESC)
luaL_addchar(&b, *strfrmt++); /* %% */
else { /* format item */
char form[MAX_FORMAT]; /* to store the format (`%...') */
char buff[MAX_ITEM]; /* to store the formatted item */
int hasprecision = 0;
arg++;
strfrmt = scanformat(L, strfrmt, form, &hasprecision);
switch (*strfrmt++) {
case 'c': case 'd': case 'i': {
sprintf(buff, form, luaL_checkint(L, arg));
break;
}
case 'o': case 'u': case 'x': case 'X': {
sprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg)));
break;
}
case 'e': case 'E': case 'f':
case 'g': case 'G': {
sprintf(buff, form, luaL_checknumber(L, arg));
break;
}
case 'q': {
addquoted(L, &b, arg);
continue; /* skip the 'addsize' at the end */
}
case 's': {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
if (!hasprecision && l >= 100) {
/* no precision and string is too long to be formatted;
keep original string */
lua_pushvalue(L, arg);
luaL_addvalue(&b);
continue; /* skip the `addsize' at the end */
}
else {
sprintf(buff, form, s);
break;
}
}
default: { /* also treat cases `pnLlh' */
return luaL_error(L, "invalid option to " LUA_QL("format"));
}
}
luaL_addlstring(&b, buff, strlen(buff));
}
}
luaL_pushresult(&b);
return 1;
}
static const luaL_Reg strlib[] = {
{"byte", str_byte},
{"char", str_char},
{"dump", str_dump},
{"find", str_find},
{"format", str_format},
{"gfind", gfind_nodef},
{"gmatch", gmatch},
{"gsub", str_gsub},
{"len", str_len},
{"lower", str_lower},
{"match", str_match},
{"rep", str_rep},
{"reverse", str_reverse},
{"sub", str_sub},
{"upper", str_upper},
{NULL, NULL}
};
static void createmetatable (lua_State *L) {
lua_newtable(L); /* create metatable for strings */
lua_pushliteral(L, ""); /* dummy string */
lua_pushvalue(L, -2);
lua_setmetatable(L, -2); /* set string metatable */
lua_pop(L, 1); /* pop dummy string */
lua_pushvalue(L, -2); /* string library... */
lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
lua_pop(L, 1); /* pop metatable */
}
/*
** Open string library
*/
LUALIB_API int luaopen_string (lua_State *L) {
luaL_register(L, LUA_STRLIBNAME, strlib);
#if defined(LUA_COMPAT_GFIND)
lua_getfield(L, -1, "gmatch");
lua_setfield(L, -2, "gfind");
#endif
createmetatable(L);
return 1;
}
+574
View File
@@ -0,0 +1,574 @@
/*
** $Id: ltable.c,v 2.25 2005/05/31 14:25:18 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
/*
** Implementation of tables (aka arrays, objects, or hash tables).
** Tables keep its elements in two parts: an array part and a hash part.
** Non-negative integer keys are all candidates to be kept in the array
** part. The actual size of the array is the largest `n' such that at
** least half the slots between 0 and n are in use.
** Hash uses a mix of chained scatter table with Brent's variation.
** A main invariant of these tables is that, if an element is not
** in its main position (i.e. the `original' position that its hash gives
** to it), then the colliding element is in its own main position.
** Hence even when the load factor reaches 100%, performance remains good.
*/
#include <math.h>
#include <string.h>
#define ltable_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "ltable.h"
/*
** max size of array part is 2^MAXBITS
*/
#if LUAI_BITSINT > 26
#define MAXBITS 26
#else
#define MAXBITS (LUAI_BITSINT-2)
#endif
#define MAXASIZE (1 << MAXBITS)
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
#define hashboolean(t,p) hashpow2(t, p)
/*
** for some types, it is better to avoid modulus by power of 2, as
** they tend to have many 2 factors.
*/
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
#define hashpointer(t,p) hashmod(t, IntPoint(p))
/*
** number of ints inside a lua_Number
*/
#define numints cast(int, sizeof(lua_Number)/sizeof(int))
const Node luaH_dummynode = {
{{NULL}, LUA_TNIL}, /* value */
{{NULL}, LUA_TNIL, NULL} /* key */
};
/*
** hash for lua_Numbers
*/
static Node *hashnum (const Table *t, lua_Number n) {
unsigned int a[numints];
int i;
n += 1; /* normalize number (avoid -0) */
lua_assert(sizeof(a) <= sizeof(n));
memcpy(a, &n, sizeof(a));
for (i = 1; i < numints; i++) a[0] += a[i];
return hashmod(t, a[0]);
}
/*
** returns the `main' position of an element in a table (that is, the index
** of its hash value)
*/
Node *luaH_mainposition (const Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNUMBER:
return hashnum(t, nvalue(key));
case LUA_TSTRING:
return hashstr(t, rawtsvalue(key));
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
case LUA_TLIGHTUSERDATA:
return hashpointer(t, pvalue(key));
default:
return hashpointer(t, gcvalue(key));
}
}
/*
** returns the index for `key' if `key' is an appropriate key to live in
** the array part of the table, -1 otherwise.
*/
static int arrayindex (const TValue *key) {
if (ttisnumber(key)) {
lua_Number n = nvalue(key);
int k;
lua_number2int(k, n);
if (luai_numeq(L, cast(lua_Number, k), nvalue(key)))
return k;
}
return -1; /* `key' did not match some condition */
}
/*
** returns the index of a `key' for table traversals. First goes all
** elements in the array part, then elements in the hash part. The
** beginning of a traversal is signalled by -1.
*/
static int findindex (lua_State *L, Table *t, StkId key) {
int i;
if (ttisnil(key)) return -1; /* first iteration */
i = arrayindex(key);
if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
return i-1; /* yes; that's the index (corrected to C) */
else {
Node *n = luaH_mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
/* key may be dead already, but it is ok to use it in `next' */
if (luaO_rawequalObj(key2tval(n), key) ||
(ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
gcvalue(gkey(n)) == gcvalue(key))) {
i = cast(int, n - gnode(t, 0)); /* key index in hash table */
/* hash elements are numbered after array ones */
return i + t->sizearray;
}
else n = gnext(n);
} while (n);
luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
return 0; /* to avoid warnings */
}
}
int luaH_next (lua_State *L, Table *t, StkId key) {
int i = findindex(L, t, key); /* find original element */
for (i++; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setnvalue(key, cast(lua_Number, i+1));
setobj2s(L, key+1, &t->array[i]);
return 1;
}
}
for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
setobj2s(L, key, key2tval(gnode(t, i)));
setobj2s(L, key+1, gval(gnode(t, i)));
return 1;
}
}
return 0; /* no more elements */
}
/*
** {=============================================================
** Rehash
** ==============================================================
*/
static int computesizes (int nums[], int *narray) {
int i;
int twotoi; /* 2^i */
int a = 0; /* number of elements smaller than 2^i */
int na = 0; /* number of elements to go to array part */
int n = 0; /* optimal size for array part */
for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
if (nums[i] > 0) {
a += nums[i];
if (a > twotoi/2) { /* more than half elements present? */
n = twotoi; /* optimal size (till now) */
na = a; /* all elements smaller than n will go to array part */
}
}
if (a == *narray) break; /* all elements already counted */
}
*narray = n;
lua_assert(*narray/2 <= na && na <= *narray);
return na;
}
static int countint (const TValue *key, int *nums) {
int k = arrayindex(key);
if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
nums[ceillog2(k)]++; /* count as such */
return 1;
}
else
return 0;
}
static int numusearray (const Table *t, int *nums) {
int lg;
int ttlg; /* 2^lg */
int ause = 0; /* summation of `nums' */
int i = 1; /* count to traverse all array keys */
for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
int lc = 0; /* counter */
int lim = ttlg;
if (lim > t->sizearray) {
lim = t->sizearray; /* adjust upper limit */
if (i > lim)
break; /* no more elements to count */
}
/* count elements in range (2^(lg-1), 2^lg] */
for (; i <= lim; i++) {
if (!ttisnil(&t->array[i-1]))
lc++;
}
nums[lg] += lc;
ause += lc;
}
return ause;
}
static int numusehash (const Table *t, int *nums, int *pnasize) {
int totaluse = 0; /* total number of elements */
int ause = 0; /* summation of `nums' */
int i = sizenode(t);
while (i--) {
Node *n = &t->node[i];
if (!ttisnil(gval(n))) {
ause += countint(key2tval(n), nums);
totaluse++;
}
}
*pnasize += ause;
return totaluse;
}
static void setarrayvector (lua_State *L, Table *t, int size) {
int i;
luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
for (i=t->sizearray; i<size; i++)
setnilvalue(&t->array[i]);
t->sizearray = size;
}
static void setnodevector (lua_State *L, Table *t, int size) {
int lsize;
if (size == 0) { /* no elements to hash part? */
t->node = cast(Node *, &luaH_dummynode); /* use common `dummynode' */
lsize = 0;
}
else {
int i;
lsize = ceillog2(size);
if (lsize > MAXBITS)
luaG_runerror(L, "table overflow");
size = twoto(lsize);
t->node = luaM_newvector(L, size, Node);
for (i=0; i<size; i++) {
gnext(&t->node[i]) = NULL;
setnilvalue(gkey(gnode(t, i)));
setnilvalue(gval(gnode(t, i)));
}
}
t->lsizenode = cast(lu_byte, lsize);
t->lastfree = gnode(t, size); /* all positions are free */
}
static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
int i;
int oldasize = t->sizearray;
int oldhsize = t->lsizenode;
Node *nold = t->node; /* save old hash ... */
if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize);
/* create new hash part with appropriate size */
setnodevector(L, t, nhsize);
if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize;
/* re-insert elements from vanishing slice */
for (i=nasize; i<oldasize; i++) {
if (!ttisnil(&t->array[i]))
setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
}
/* shrink array */
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
}
/* re-insert elements from hash part */
for (i = twoto(oldhsize) - 1; i >= 0; i--) {
Node *old = nold+i;
if (!ttisnil(gval(old)))
setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
}
if (nold != &luaH_dummynode)
luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
}
void luaH_resizearray (lua_State *L, Table *t, int nasize) {
int nsize = (t->node == &luaH_dummynode) ? 0 : sizenode(t);
resize(L, t, nasize, nsize);
}
static void rehash (lua_State *L, Table *t, const TValue *ek) {
int nasize, na;
int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
int i;
int totaluse;
for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
nasize = numusearray(t, nums); /* count keys in array part */
totaluse = nasize; /* all those keys are integer keys */
totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
/* count extra key */
nasize += countint(ek, nums);
totaluse++;
/* compute new size for array part */
na = computesizes(nums, &nasize);
/* resize the table to new computed sizes */
resize(L, t, nasize, totaluse - na);
}
/*
** }=============================================================
*/
Table *luaH_new (lua_State *L, int narray, int nhash) {
Table *t = luaM_new(L, Table);
luaC_link(L, obj2gco(t), LUA_TTABLE);
t->metatable = NULL;
t->flags = cast(lu_byte, ~0);
/* temporary values (kept only if some malloc fails) */
t->array = NULL;
t->sizearray = 0;
t->lsizenode = 0;
t->node = cast(Node *, &luaH_dummynode);
setarrayvector(L, t, narray);
setnodevector(L, t, nhash);
return t;
}
void luaH_free (lua_State *L, Table *t) {
if (t->node != &luaH_dummynode)
luaM_freearray(L, t->node, sizenode(t), Node);
luaM_freearray(L, t->array, t->sizearray, TValue);
luaM_free(L, t);
}
static Node *getfreepos (Table *t) {
while (t->lastfree-- > t->node) {
if (ttisnil(gkey(t->lastfree)))
return t->lastfree;
}
return NULL; /* could not find a free place */
}
/*
** inserts a new key into a hash table; first, check whether key's main
** position is free. If not, check whether colliding node is in its main
** position or not: if it is not, move colliding node to an empty place and
** put new key in its main position; otherwise (colliding node is in its main
** position), new key goes to an empty position.
*/
static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp = luaH_mainposition(t, key);
if (!ttisnil(gval(mp)) || mp == &luaH_dummynode) {
Node *othern;
Node *n = getfreepos(t); /* get a free place */
if (n == NULL) { /* cannot find a free place? */
rehash(L, t, key); /* grow table */
return luaH_set(L, t, key); /* re-insert key into grown table */
}
lua_assert(n != &luaH_dummynode);
othern = luaH_mainposition(t, key2tval(mp));
if (othern != mp) { /* is colliding node out of its main position? */
/* yes; move colliding node into free position */
while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
*n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
gnext(mp) = NULL; /* now `mp' is free */
setnilvalue(gval(mp));
}
else { /* colliding node is in its own main position */
/* new node will go into free position */
gnext(n) = gnext(mp); /* chain new position */
gnext(mp) = n;
mp = n;
}
}
gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
luaC_barriert(L, t, key);
lua_assert(ttisnil(gval(mp)));
return gval(mp);
}
/*
** search function for integers
*/
const TValue *luaH_getnum (Table *t, int key) {
/* (1 <= key && key <= t->sizearray) */
if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
return &t->array[key-1];
else {
lua_Number nk = cast(lua_Number, key);
Node *n = hashnum(t, nk);
do { /* check whether `key' is somewhere in the chain */
if (ttisnumber(gkey(n)) && luai_numeq(L, nvalue(gkey(n)), nk))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return &luaO_nilobject;
}
}
/*
** search function for strings
*/
const TValue *luaH_getstr (Table *t, TString *key) {
Node *n = hashstr(t, key);
do { /* check whether `key' is somewhere in the chain */
if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return &luaO_nilobject;
}
/*
** main search function
*/
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNIL: return &luaO_nilobject;
case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(L, cast(lua_Number, k), nvalue(key))) /* index is int? */
return luaH_getnum(t, k); /* use specialized version */
/* else go through */
}
default: {
Node *n = luaH_mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(key2tval(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return &luaO_nilobject;
}
}
}
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key);
t->flags = 0;
if (p != &luaO_nilobject)
return cast(TValue *, p);
else {
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
else if (ttisnumber(key) && !luai_numeq(L, nvalue(key), nvalue(key)))
luaG_runerror(L, "table index is NaN");
return newkey(L, t, key);
}
}
TValue *luaH_setnum (lua_State *L, Table *t, int key) {
const TValue *p = luaH_getnum(t, key);
if (p != &luaO_nilobject)
return cast(TValue *, p);
else {
TValue k;
setnvalue(&k, cast(lua_Number, key));
return newkey(L, t, &k);
}
}
TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
const TValue *p = luaH_getstr(t, key);
if (p != &luaO_nilobject)
return cast(TValue *, p);
else {
TValue k;
setsvalue(L, &k, key);
return newkey(L, t, &k);
}
}
static int unbound_search (Table *t, unsigned int j) {
unsigned int i = j; /* i is zero or a present index */
j = j+1;
/* find `i' and `j' such that i is present and j is not */
while (!ttisnil(luaH_getnum(t, j))) {
i = j;
j = i*2;
if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
/* table was built with bad purposes: resort to linear search */
i = 1;
while (!ttisnil(luaH_getnum(t, i))) i++;
return i - 1;
}
}
/* now do a binary search between them */
while (i < j-1) {
unsigned int m = (i+j)/2;
if (ttisnil(luaH_getnum(t, m))) j = m;
else i = m;
}
return i;
}
/*
** Try to find a boundary in table `t'. A `boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
int luaH_getn (Table *t) {
unsigned int j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */
unsigned int i = 0;
while (j - i > 1) {
unsigned int m = (i+j)/2;
if (ttisnil(&t->array[m - 1])) j = m;
else i = m;
}
return i;
}
/* else must find a boundary in hash part */
else if (t->node == &luaH_dummynode) /* hash part is empty? */
return j; /* that is easy... */
else return unbound_search(t, j);
}
+39
View File
@@ -0,0 +1,39 @@
/*
** $Id: ltable.h,v 2.7 2005/04/25 19:24:10 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
#ifndef ltable_h
#define ltable_h
#include "lobject.h"
#define gnode(t,i) (&(t)->node[i])
#define gkey(n) (&(n)->i_key)
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->i_key.next)
#define key2tval(n) (cast(const TValue *, gkey(n)))
LUAI_DATA const Node luaH_dummynode;
LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t);
/* exported only for debugging */
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
#endif
+256
View File
@@ -0,0 +1,256 @@
/*
** $Id: ltablib.c,v 1.34 2005/08/15 14:12:32 roberto Exp roberto $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define ltablib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
static int foreachi (lua_State *L) {
int i;
int n = aux_getn(L, 1);
luaL_checktype(L, 2, LUA_TFUNCTION);
for (i=1; i <= n; i++) {
lua_pushvalue(L, 2); /* function */
lua_pushinteger(L, i); /* 1st argument */
lua_rawgeti(L, 1, i); /* 2nd argument */
lua_call(L, 2, 1);
if (!lua_isnil(L, -1))
return 1;
lua_pop(L, 1); /* remove nil result */
}
return 0;
}
static int foreach (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_pushnil(L); /* first key */
for (;;) {
if (lua_next(L, 1) == 0)
return 0;
lua_pushvalue(L, 2); /* function */
lua_pushvalue(L, -3); /* key */
lua_pushvalue(L, -3); /* value */
lua_call(L, 2, 1);
if (!lua_isnil(L, -1))
return 1;
lua_pop(L, 2); /* remove value and result */
}
}
static int getn (lua_State *L) {
lua_pushinteger(L, aux_getn(L, 1));
return 1;
}
static int setn (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
#ifndef luaL_setn
luaL_setn(L, 1, luaL_checkint(L, 2));
#else
luaL_error(L, LUA_QL("setn") " is obsolete");
#endif
lua_pushvalue(L, 1);
return 1;
}
static int tinsert (lua_State *L) {
int e = aux_getn(L, 1) + 1; /* first empty element */
int pos; /* where to insert new element */
if (lua_isnone(L, 3)) /* called with only 2 arguments */
pos = e; /* insert new element at the end */
else {
int i;
pos = luaL_checkint(L, 2); /* 2nd argument is the position */
if (pos > e) e = pos; /* `grow' array if necessary */
lua_settop(L, 3); /* function may be called with more than 3 args */
for (i = e; i > pos; i--) { /* move up elements */
lua_rawgeti(L, 1, i-1);
lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
}
}
luaL_setn(L, 1, e); /* new size */
lua_rawseti(L, 1, pos); /* t[pos] = v */
return 0;
}
static int tremove (lua_State *L) {
int e = aux_getn(L, 1);
int pos = luaL_optint(L, 2, e);
if (e == 0) return 0; /* table is `empty' */
luaL_setn(L, 1, e - 1); /* t.n = n-1 */
lua_rawgeti(L, 1, pos); /* result = t[pos] */
for ( ;pos<e; pos++) {
lua_rawgeti(L, 1, pos+1);
lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
}
lua_pushnil(L);
lua_rawseti(L, 1, e); /* t[e] = nil */
return 1;
}
static int tconcat (lua_State *L) {
luaL_Buffer b;
size_t lsep;
const char *sep = luaL_optlstring(L, 2, "", &lsep);
int i = luaL_optint(L, 3, 1);
int last = luaL_optint(L, 4, -2);
luaL_checktype(L, 1, LUA_TTABLE);
if (last == -2)
last = luaL_getn(L, 1);
luaL_buffinit(L, &b);
for (; i <= last; i++) {
lua_rawgeti(L, 1, i);
luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings");
luaL_addvalue(&b);
if (i != last)
luaL_addlstring(&b, sep, lsep);
}
luaL_pushresult(&b);
return 1;
}
/*
** {======================================================
** Quicksort
** (based on `Algorithms in MODULA-3', Robert Sedgewick;
** Addison-Wesley, 1993.)
*/
static void set2 (lua_State *L, int i, int j) {
lua_rawseti(L, 1, i);
lua_rawseti(L, 1, j);
}
static int sort_comp (lua_State *L, int a, int b) {
if (!lua_isnil(L, 2)) { /* function? */
int res;
lua_pushvalue(L, 2);
lua_pushvalue(L, a-1); /* -1 to compensate function */
lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
lua_call(L, 2, 1);
res = lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
else /* a < b? */
return lua_lessthan(L, a, b);
}
static void auxsort (lua_State *L, int l, int u) {
while (l < u) { /* for tail recursion */
int i, j;
/* sort elements a[l], a[(l+u)/2] and a[u] */
lua_rawgeti(L, 1, l);
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
set2(L, l, u); /* swap a[l] - a[u] */
else
lua_pop(L, 2);
if (u-l == 1) break; /* only 2 elements */
i = (l+u)/2;
lua_rawgeti(L, 1, i);
lua_rawgeti(L, 1, l);
if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
set2(L, i, l);
else {
lua_pop(L, 1); /* remove a[l] */
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
set2(L, i, u);
else
lua_pop(L, 2);
}
if (u-l == 2) break; /* only 3 elements */
lua_rawgeti(L, 1, i); /* Pivot */
lua_pushvalue(L, -1);
lua_rawgeti(L, 1, u-1);
set2(L, i, u-1);
/* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
i = l; j = u-1;
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
/* repeat ++i until a[i] >= P */
while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
if (i>u) luaL_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[i] */
}
/* repeat --j until a[j] <= P */
while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
if (j<l) luaL_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[j] */
}
if (j<i) {
lua_pop(L, 3); /* pop pivot, a[i], a[j] */
break;
}
set2(L, i, j);
}
lua_rawgeti(L, 1, u-1);
lua_rawgeti(L, 1, i);
set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
/* adjust so that smaller half is in [j..i] and larger one in [l..u] */
if (i-l < u-i) {
j=l; i=i-1; l=i+2;
}
else {
j=i+1; i=u; u=j-2;
}
auxsort(L, j, i); /* call recursively the smaller one */
} /* repeat the routine for the larger one */
}
static int sort (lua_State *L) {
int n = aux_getn(L, 1);
luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_settop(L, 2); /* make sure there is two arguments */
auxsort(L, 1, n);
return 0;
}
/* }====================================================== */
static const luaL_Reg tab_funcs[] = {
{"concat", tconcat},
{"foreach", foreach},
{"foreachi", foreachi},
{"getn", getn},
{"insert", tinsert},
{"remove", tremove},
{"setn", setn},
{"sort", sort},
{NULL, NULL}
};
LUALIB_API int luaopen_table (lua_State *L) {
luaL_register(L, LUA_TABLIBNAME, tab_funcs);
return 1;
}
+1159
View File
File diff suppressed because it is too large Load Diff
+90
View File
@@ -0,0 +1,90 @@
/*
** $Id: ltests.h,v 2.14 2005/05/03 19:01:17 roberto Exp roberto $
** Internal Header for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
#ifndef ltests_h
#define ltests_h
#include <stdlib.h>
#define LUA_DEBUG
#undef NDEBUG
#include <assert.h>
#undef lua_assert
#define lua_assert(c) assert(c)
/* to avoid warnings, and to make sure value is really unused */
#define UNUSED(x) (x=0, (void)(x))
/* memory allocator control variables */
typedef struct Memcontrol {
unsigned long numblocks;
unsigned long total;
unsigned long maxmem;
unsigned long memlimit;
} Memcontrol;
LUAI_DATA Memcontrol memcontrol;
/*
** generic variable for debug tricks
*/
LUAI_DATA int Trick;
void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize);
#ifdef lua_c
#define luaL_newstate() lua_newstate(debug_realloc, &memcontrol)
#endif
typedef struct CallInfo *pCallInfo;
int lua_checkmemory (lua_State *L);
int lua_checkpc (lua_State *L, pCallInfo ci);
/* test for lock/unlock */
#undef luai_userstateopen
#undef lua_lock
#undef lua_unlock
#undef LUAI_EXTRASPACE
LUAI_DATA int islocked;
#define LUAI_EXTRASPACE sizeof(double)
#define getlock(l) (*(cast(int **, l) - 1))
#define luai_userstateopen(l) getlock(l) = &islocked;
#define lua_lock(l) lua_assert((*getlock(l))++ == 0)
#define lua_unlock(l) lua_assert(--(*getlock(l)) == 0)
int luaB_opentests (lua_State *L);
#ifdef lua_c
#define luaL_openlibs(L) { (luaL_openlibs)(L); luaB_opentests(L); }
#endif
/* real main will be defined at `ltests.c' */
int l_main (int argc, char *argv[]);
#define main l_main
/* change some sizes to give some bugs a chance */
#undef LUAL_BUFFERSIZE
#define LUAL_BUFFERSIZE 27
#define MINSTRTABSIZE 2
#endif
+75
View File
@@ -0,0 +1,75 @@
/*
** $Id: ltm.c,v 2.5 2005/05/05 15:34:03 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
#include <string.h>
#define ltm_c
#define LUA_CORE
#include "lua.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
const char *const luaT_typenames[] = {
"nil", "boolean", "userdata", "number",
"string", "table", "function", "userdata", "thread",
"proto", "upval"
};
void luaT_init (lua_State *L) {
static const char *const luaT_eventname[] = { /* ORDER TM */
"__index", "__newindex",
"__gc", "__mode", "__eq",
"__add", "__sub", "__mul", "__div", "__mod",
"__pow", "__unm", "__len", "__lt", "__le",
"__concat", "__call"
};
int i;
for (i=0; i<TM_N; i++) {
G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
luaS_fix(G(L)->tmname[i]); /* never collect these names */
}
}
/*
** function to be used with macro "fasttm": optimized for absence of
** tag methods
*/
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *tm = luaH_getstr(events, ename);
lua_assert(event <= TM_EQ);
if (ttisnil(tm)) { /* no tag method? */
events->flags |= cast(lu_byte, 1u<<event); /* cache this fact */
return NULL;
}
else return tm;
}
const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt;
switch (ttype(o)) {
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(o)->metatable;
break;
default:
mt = G(L)->mt[ttype(o)];
}
return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : &luaO_nilobject);
}
+54
View File
@@ -0,0 +1,54 @@
/*
** $Id: ltm.h,v 2.5 2005/05/20 15:53:42 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
#ifndef ltm_h
#define ltm_h
#include "lobject.h"
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM"
*/
typedef enum {
TM_INDEX,
TM_NEWINDEX,
TM_GC,
TM_MODE,
TM_EQ, /* last tag method with `fast' access */
TM_ADD,
TM_SUB,
TM_MUL,
TM_DIV,
TM_MOD,
TM_POW,
TM_UNM,
TM_LEN,
TM_LT,
TM_LE,
TM_CONCAT,
TM_CALL,
TM_N /* number of elements in the enum */
} TMS;
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
#define fasttm(l,et,e) gfasttm(G(l), et, e)
LUAI_DATA const char *const luaT_typenames[];
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
TMS event);
LUAI_FUNC void luaT_init (lua_State *L);
#endif
+354 -18
View File
@@ -1,31 +1,367 @@
/*
** lua.c
** Linguagem para Usuarios de Aplicacao
** $Id: lua.c,v 1.149 2005/08/26 17:32:05 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
char *rcs_lua="$Id: $";
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lua_c
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
void main (int argc, char *argv[])
{
int i;
iolib_open ();
strlib_open ();
mathlib_open ();
if (argc < 2)
{
char buffer[250];
while (gets(buffer) != 0)
lua_dostring(buffer);
}
else
for (i=1; i<argc; i++)
lua_dofile (argv[i]);
static lua_State *globalL = NULL;
static const char *progname = LUA_PROGNAME;
static void lstop (lua_State *L, lua_Debug *ar) {
(void)ar; /* unused arg. */
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "interrupted!");
}
static void laction (int i) {
signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
terminate process (default action) */
lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
static void print_usage (void) {
fprintf(stderr,
"usage: %s [options] [script [args]].\n"
"Available options are:\n"
" - execute stdin as a file\n"
" -e stat execute string " LUA_QL("stat") "\n"
" -i enter interactive mode after executing " LUA_QL("script") "\n"
" -l name require library " LUA_QL("name") "\n"
" -v show version information\n"
" -- stop handling options\n" ,
progname);
fflush(stderr);
}
static void l_message (const char *pname, const char *msg) {
if (pname) fprintf(stderr, "%s: ", pname);
fprintf(stderr, "%s\n", msg);
fflush(stderr);
}
static int report (lua_State *L, int status) {
if (status && !lua_isnil(L, -1)) {
const char *msg = lua_tostring(L, -1);
if (msg == NULL) msg = "(error object is not a string)";
l_message(progname, msg);
lua_pop(L, 1);
}
return status;
}
static int traceback (lua_State *L) {
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
return 1;
}
lua_getfield(L, -1, "traceback");
if (!lua_isfunction(L, -1)) {
lua_pop(L, 2);
return 1;
}
lua_pushvalue(L, 1); /* pass error message */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback */
return 1;
}
static int docall (lua_State *L, int narg, int clear) {
int status;
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, traceback); /* push traceback function */
lua_insert(L, base); /* put it under chunk and args */
signal(SIGINT, laction);
status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
signal(SIGINT, SIG_DFL);
lua_remove(L, base); /* remove traceback function */
return status;
}
static void print_version (void) {
l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT);
}
static int getargs (lua_State *L, int argc, char **argv, int n) {
int narg = argc - (n + 1); /* number of arguments to the script */
int i;
luaL_checkstack(L, narg + 3, "too many arguments to script");
for (i=n+1; i < argc; i++)
lua_pushstring(L, argv[i]);
lua_newtable(L);
for (i=0; i < argc; i++) {
lua_pushstring(L, argv[i]);
lua_rawseti(L, -2, i - n);
}
return narg;
}
static int dofile (lua_State *L, const char *name) {
int status = luaL_loadfile(L, name) || docall(L, 0, 1);
return report(L, status);
}
static int dostring (lua_State *L, const char *s, const char *name) {
int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
return report(L, status);
}
static int dolibrary (lua_State *L, const char *name) {
lua_getglobal(L, "require");
lua_pushstring(L, name);
return report(L, lua_pcall(L, 1, 0, 0));
}
static const char *get_prompt (lua_State *L, int firstline) {
const char *p;
lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
p = lua_tostring(L, -1);
if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
lua_pop(L, 1); /* remove global */
return p;
}
static int incomplete (lua_State *L, int status) {
if (status == LUA_ERRSYNTAX) {
size_t lmsg;
const char *msg = lua_tolstring(L, -1, &lmsg);
const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
if (strstr(msg, LUA_QL("<eof>")) == tp) {
lua_pop(L, 1);
return 1;
}
}
return 0; /* else... */
}
static int pushline (lua_State *L, int firstline) {
char buffer[LUA_MAXINPUT];
char *b = buffer;
size_t l;
const char *prmt = get_prompt(L, firstline);
if (lua_readline(L, b, prmt) == 0)
return 0; /* no input */
l = strlen(b);
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
b[l-1] = '\0'; /* remove it */
if (firstline && b[0] == '=') /* first line starts with `=' ? */
lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
else
lua_pushstring(L, b);
lua_freeline(L, b);
return 1;
}
static int loadline (lua_State *L) {
int status;
lua_settop(L, 0);
if (!pushline(L, 1))
return -1; /* no input */
for (;;) { /* repeat until gets a complete line */
status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
if (!incomplete(L, status)) break; /* cannot try to add lines? */
if (!pushline(L, 0)) /* no more input? */
return -1;
lua_pushliteral(L, "\n"); /* add a new line... */
lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */
}
lua_saveline(L, 1);
lua_remove(L, 1); /* remove line */
return status;
}
static void dotty (lua_State *L) {
int status;
const char *oldprogname = progname;
progname = NULL;
print_version();
while ((status = loadline(L)) != -1) {
if (status == 0) status = docall(L, 0, 0);
report(L, status);
if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
l_message(progname, lua_pushfstring(L,
"error calling " LUA_QL("print") " (%s)",
lua_tostring(L, -1)));
}
}
lua_settop(L, 0); /* clear stack */
fputs("\n", stdout);
fflush(stdout);
progname = oldprogname;
}
#define clearinteractive(i) (*i &= 2)
static int handle_argv (lua_State *L, int argc, char **argv, int *interactive) {
if (argv[1] == NULL) { /* no arguments? */
*interactive = 0;
if (lua_stdin_is_tty())
dotty(L);
else
dofile(L, NULL); /* executes stdin as a file */
}
else { /* other arguments; loop over them */
int i;
for (i = 1; argv[i] != NULL; i++) {
if (argv[i][0] != '-') break; /* not an option? */
switch (argv[i][1]) { /* option */
case '-': { /* `--' */
if (argv[i][2] != '\0') {
print_usage();
return 1;
}
i++; /* skip this argument */
goto endloop; /* stop handling arguments */
}
case '\0': {
clearinteractive(interactive);
dofile(L, NULL); /* executes stdin as a file */
break;
}
case 'i': {
*interactive = 2; /* force interactive mode after arguments */
break;
}
case 'v': {
clearinteractive(interactive);
print_version();
break;
}
case 'e': {
const char *chunk = argv[i] + 2;
clearinteractive(interactive);
if (*chunk == '\0') chunk = argv[++i];
if (chunk == NULL) {
print_usage();
return 1;
}
if (dostring(L, chunk, "=(command line)") != 0)
return 1;
break;
}
case 'l': {
const char *filename = argv[i] + 2;
if (*filename == '\0') filename = argv[++i];
if (filename == NULL) {
print_usage();
return 1;
}
if (dolibrary(L, filename))
return 1; /* stop if file fails */
break;
}
default: {
clearinteractive(interactive);
print_usage();
return 1;
}
}
} endloop:
if (argv[i] != NULL) {
int status;
const char *filename = argv[i];
int narg = getargs(L, argc, argv, i); /* collect arguments */
lua_setglobal(L, "arg");
clearinteractive(interactive);
status = luaL_loadfile(L, filename);
lua_insert(L, -(narg+1));
if (status == 0)
status = docall(L, narg, 0);
else
lua_pop(L, narg);
return report(L, status);
}
}
return 0;
}
static int handle_luainit (lua_State *L) {
const char *init = getenv("LUA_INIT");
if (init == NULL) return 0; /* status OK */
else if (init[0] == '@')
return dofile(L, init+1);
else
return dostring(L, init, "=LUA_INIT");
}
struct Smain {
int argc;
char **argv;
int status;
};
static int pmain (lua_State *L) {
struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
int status;
int interactive = 1;
if (s->argv[0] && s->argv[0][0]) progname = s->argv[0];
globalL = L;
luaL_openlibs(L); /* open libraries */
status = handle_luainit(L);
if (status == 0) {
status = handle_argv(L, s->argc, s->argv, &interactive);
if (status == 0 && interactive) dotty(L);
}
s->status = status;
return 0;
}
int main (int argc, char **argv) {
int status;
struct Smain s;
lua_State *L = lua_open(); /* create state */
if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
}
s.argc = argc;
s.argv = argv;
status = lua_cpcall(L, &pmain, &s);
report(L, status);
lua_close(L);
return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
}
+366 -38
View File
@@ -1,54 +1,382 @@
/*
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: $
** $Id: lua.h,v 1.211 2005/08/12 13:34:15 roberto Exp roberto $
** Lua - An Extensible Extension Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
*/
#ifndef lua_h
#define lua_h
typedef void (*lua_CFunction) (void);
typedef struct Object *lua_Object;
#define lua_register(n,f) (lua_pushcfunction(f), lua_storeglobal(n))
#include <stdarg.h>
#include <stddef.h>
void lua_errorfunction (void (*fn) (char *s));
void lua_error (char *s);
int lua_dofile (char *filename);
int lua_dostring (char *string);
int lua_call (char *functionname, int nparam);
#include "luaconf.h"
lua_Object lua_getparam (int number);
float lua_getnumber (lua_Object object);
char *lua_getstring (lua_Object object);
char *lua_copystring (lua_Object object);
lua_CFunction lua_getcfunction (lua_Object object);
void *lua_getuserdata (lua_Object object);
lua_Object lua_getfield (lua_Object object, char *field);
lua_Object lua_getindexed (lua_Object object, float index);
lua_Object lua_getglobal (char *name);
lua_Object lua_pop (void);
#define LUA_VERSION "Lua 5.1"
#define LUA_VERSION_NUM 501
#define LUA_COPYRIGHT "Copyright (C) 1994-2005 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
int lua_pushnil (void);
int lua_pushnumber (float n);
int lua_pushstring (char *s);
int lua_pushcfunction (lua_CFunction fn);
int lua_pushuserdata (void *u);
int lua_pushobject (lua_Object object);
int lua_storeglobal (char *name);
int lua_storefield (lua_Object object, char *field);
int lua_storeindexed (lua_Object object, float index);
/* mark for precompiled code (`<esc>Lua') */
#define LUA_SIGNATURE "\033Lua"
/* option for multiple returns in `lua_pcall' and `lua_call' */
#define LUA_MULTRET (-1)
/*
** pseudo-indices
*/
#define LUA_REGISTRYINDEX (-10000)
#define LUA_ENVIRONINDEX (-10001)
#define LUA_GLOBALSINDEX (-10002)
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
/* thread status; 0 is OK */
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
#define LUA_ERRMEM 4
#define LUA_ERRERR 5
typedef struct lua_State lua_State;
typedef int (*lua_CFunction) (lua_State *L);
/*
** functions that read/write blocks when loading/dumping Lua chunks
*/
typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
/*
** prototype for memory-allocation functions
*/
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
/*
** basic types
*/
#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
/* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20
/*
** generic extra include file
*/
#if defined(LUA_USER_H)
#include LUA_USER_H
#endif
/* type of numbers in Lua */
typedef LUA_NUMBER lua_Number;
/* type for integer functions */
typedef LUA_INTEGER lua_Integer;
/*
** state manipulation
*/
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
LUA_API void (lua_close) (lua_State *L);
LUA_API lua_State *(lua_newthread) (lua_State *L);
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
/*
** basic stack manipulation
*/
LUA_API int (lua_gettop) (lua_State *L);
LUA_API void (lua_settop) (lua_State *L, int idx);
LUA_API void (lua_pushvalue) (lua_State *L, int idx);
LUA_API void (lua_remove) (lua_State *L, int idx);
LUA_API void (lua_insert) (lua_State *L, int idx);
LUA_API void (lua_replace) (lua_State *L, int idx);
LUA_API int (lua_checkstack) (lua_State *L, int sz);
LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
/*
** access functions (stack -> C)
*/
LUA_API int (lua_isnumber) (lua_State *L, int idx);
LUA_API int (lua_isstring) (lua_State *L, int idx);
LUA_API int (lua_iscfunction) (lua_State *L, int idx);
LUA_API int (lua_isuserdata) (lua_State *L, int idx);
LUA_API int (lua_type) (lua_State *L, int idx);
LUA_API const char *(lua_typename) (lua_State *L, int tp);
LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
LUA_API int (lua_toboolean) (lua_State *L, int idx);
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
LUA_API size_t (lua_objlen) (lua_State *L, int idx);
LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
LUA_API void *(lua_touserdata) (lua_State *L, int idx);
LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
LUA_API const void *(lua_topointer) (lua_State *L, int idx);
/*
** push functions (C -> stack)
*/
LUA_API void (lua_pushnil) (lua_State *L);
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp);
LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
LUA_API void (lua_pushboolean) (lua_State *L, int b);
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
LUA_API int (lua_pushthread) (lua_State *L);
/*
** get functions (Lua -> stack)
*/
LUA_API void (lua_gettable) (lua_State *L, int idx);
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawget) (lua_State *L, int idx);
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
LUA_API void (lua_getfenv) (lua_State *L, int idx);
/*
** set functions (stack -> Lua)
*/
LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawset) (lua_State *L, int idx);
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
LUA_API int (lua_setfenv) (lua_State *L, int idx);
/*
** `load' and `call' functions (load and run Lua code)
*/
LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
const char *chunkname);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
/*
** coroutine functions
*/
LUA_API int (lua_yield) (lua_State *L, int nresults);
LUA_API int (lua_resume) (lua_State *L, int narg);
LUA_API int (lua_status) (lua_State *L);
/*
** garbage-collection function and options
*/
#define LUA_GCSTOP 0
#define LUA_GCRESTART 1
#define LUA_GCCOLLECT 2
#define LUA_GCCOUNT 3
#define LUA_GCSTEP 4
#define LUA_GCSETPAUSE 5
#define LUA_GCSETSTEPMUL 6
LUA_API int (lua_gc) (lua_State *L, int what, int data);
/*
** miscellaneous functions
*/
LUA_API int (lua_error) (lua_State *L);
LUA_API int (lua_next) (lua_State *L, int idx);
LUA_API void (lua_concat) (lua_State *L, int n);
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
/*
** ===============================================================
** some useful macros
** ===============================================================
*/
#define lua_pop(L,n) lua_settop(L, -(n)-1)
#define lua_newtable(L) lua_createtable(L, 0, 0)
#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
#define lua_strlen(L,i) lua_objlen(L, (i))
#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
#define lua_pushliteral(L, s) \
lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
/*
** compatibility macros and functions
*/
#define lua_open() luaL_newstate()
#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
#define lua_Chunkreader lua_Reader
#define lua_Chunkwriter lua_Writer
/*
** {======================================================================
** Debug API
** =======================================================================
*/
/*
** Event codes
*/
#define LUA_HOOKCALL 0
#define LUA_HOOKRET 1
#define LUA_HOOKLINE 2
#define LUA_HOOKCOUNT 3
#define LUA_HOOKTAILRET 4
/*
** Event masks
*/
#define LUA_MASKCALL (1 << LUA_HOOKCALL)
#define LUA_MASKRET (1 << LUA_HOOKRET)
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
typedef struct lua_Debug lua_Debug; /* activation record */
/* Functions to be called by the debuger in specific events */
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
LUA_API lua_Hook lua_gethook (lua_State *L);
LUA_API int lua_gethookmask (lua_State *L);
LUA_API int lua_gethookcount (lua_State *L);
struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) `global', `local', `field', `method' */
const char *what; /* (S) `Lua', `C', `main', `tail' */
const char *source; /* (S) */
int currentline; /* (l) */
int nups; /* (u) number of upvalues */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
int i_ci; /* active function */
};
/* }====================================================================== */
/******************************************************************************
* Copyright (C) 1994-2005 Lua.org, PUC-Rio. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
int lua_isnil (lua_Object object);
int lua_isnumber (lua_Object object);
int lua_isstring (lua_Object object);
int lua_istable (lua_Object object);
int lua_iscfunction (lua_Object object);
int lua_isuserdata (lua_Object object);
#endif
-85
View File
@@ -1,85 +0,0 @@
%{
char *rcs_lualex = "$Id: $";
#include <stdlib.h>
#include <string.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "y.tab.h"
#undef input
#undef unput
static Input input;
static Unput unput;
void lua_setinput (Input fn)
{
input = fn;
}
void lua_setunput (Unput fn)
{
unput = fn;
}
char *lua_lasttext (void)
{
return yytext;
}
%}
%%
[ \t]* ;
^"$debug" {yylval.vInt = 1; return DEBUG;}
^"$nodebug" {yylval.vInt = 0; return DEBUG;}
\n lua_linenumber++;
"--".* ;
"local" return LOCAL;
"if" return IF;
"then" return THEN;
"else" return ELSE;
"elseif" return ELSEIF;
"while" return WHILE;
"do" return DO;
"repeat" return REPEAT;
"until" return UNTIL;
"function" {
yylval.vWord = lua_nfile-1;
return FUNCTION;
}
"end" return END;
"return" return RETURN;
"local" return LOCAL;
"nil" return NIL;
"and" return AND;
"or" return OR;
"not" return NOT;
"~=" return NE;
"<=" return LE;
">=" return GE;
".." return CONC;
\"[^\"]*\" |
\'[^\']*\' {
yylval.vWord = lua_findenclosedconstant (yytext);
return STRING;
}
[0-9]+("."[0-9]*)? |
([0-9]+)?"."[0-9]+ |
[0-9]+("."[0-9]*)?[dDeEgG][+-]?[0-9]+ |
([0-9]+)?"."[0-9]+[dDeEgG][+-]?[0-9]+ {
yylval.vFloat = atof(yytext);
return NUMBER;
}
[a-zA-Z_][a-zA-Z0-9_]* {
yylval.vWord = lua_findsymbol (yytext);
return NAME;
}
. return *yytext;
-954
View File
@@ -1,954 +0,0 @@
%{
char *rcs_luastx = "$Id: lua.stx,v 2.4 1994/04/20 16:22:21 celes Exp celes $";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mm.h"
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "lua.h"
#define LISTING 0
#ifndef CODE_BLOCK
#define CODE_BLOCK 256
#endif
static Long maxcode;
static Long maxmain;
static Long maxcurr ;
static Byte *code = NULL;
static Byte *initcode;
static Byte *basepc;
static Long maincode;
static Long pc;
#define MAXVAR 32
static long varbuffer[MAXVAR]; /* variables in an assignment list;
it's long to store negative Word values */
static int nvarbuffer=0; /* number of variables at a list */
static Word localvar[STACKGAP]; /* store local variable names */
static int nlocalvar=0; /* number of local variables */
#define MAXFIELDS FIELDS_PER_FLUSH*2
static Word fields[MAXFIELDS]; /* fieldnames to be flushed */
static int nfields=0;
static int ntemp; /* number of temporary var into stack */
static int err; /* flag to indicate error */
/* Internal functions */
static void code_byte (Byte c)
{
if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */
{
maxcurr *= 2;
basepc = (Byte *)realloc(basepc, maxcurr*sizeof(Byte));
if (basepc == NULL)
{
lua_error ("not enough memory");
err = 1;
}
}
basepc[pc++] = c;
}
static void code_word (Word n)
{
CodeWord code;
code.w = n;
code_byte(code.m.c1);
code_byte(code.m.c2);
}
static void code_float (float n)
{
CodeFloat code;
code.f = n;
code_byte(code.m.c1);
code_byte(code.m.c2);
code_byte(code.m.c3);
code_byte(code.m.c4);
}
static void code_word_at (Byte *p, Word n)
{
CodeWord code;
code.w = n;
*p++ = code.m.c1;
*p++ = code.m.c2;
}
static void push_field (Word name)
{
if (nfields < STACKGAP-1)
fields[nfields++] = name;
else
{
lua_error ("too many fields in a constructor");
err = 1;
}
}
static void flush_record (int n)
{
int i;
if (n == 0) return;
code_byte(STORERECORD);
code_byte(n);
for (i=0; i<n; i++)
code_word(fields[--nfields]);
ntemp -= n;
}
static void flush_list (int m, int n)
{
if (n == 0) return;
if (m == 0)
code_byte(STORELIST0);
else
{
code_byte(STORELIST);
code_byte(m);
}
code_byte(n);
ntemp-=n;
}
static void incr_ntemp (void)
{
if (ntemp+nlocalvar+MAXVAR+1 < STACKGAP)
ntemp++;
else
{
lua_error ("stack overflow");
err = 1;
}
}
static void add_nlocalvar (int n)
{
if (ntemp+nlocalvar+MAXVAR+n < STACKGAP)
nlocalvar += n;
else
{
lua_error ("too many local variables or expression too complicate");
err = 1;
}
}
static void incr_nvarbuffer (void)
{
if (nvarbuffer < MAXVAR-1)
nvarbuffer++;
else
{
lua_error ("variable buffer overflow");
err = 1;
}
}
static void code_number (float f)
{
Word i = (Word)f;
if (f == (float)i) /* f has an (short) integer value */
{
if (i <= 2) code_byte(PUSH0 + i);
else if (i <= 255)
{
code_byte(PUSHBYTE);
code_byte(i);
}
else
{
code_byte(PUSHWORD);
code_word(i);
}
}
else
{
code_byte(PUSHFLOAT);
code_float(f);
}
incr_ntemp();
}
%}
%union
{
int vInt;
float vFloat;
char *pChar;
Word vWord;
Long vLong;
Byte *pByte;
}
%start functionlist
%token WRONGTOKEN
%token NIL
%token IF THEN ELSE ELSEIF WHILE DO REPEAT UNTIL END
%token RETURN
%token LOCAL
%token <vFloat> NUMBER
%token <vWord> FUNCTION STRING
%token <pChar> NAME
%token <vInt> DEBUG
%type <vLong> PrepJump
%type <vInt> expr, exprlist, exprlist1, varlist1, typeconstructor
%type <vInt> fieldlist, localdeclist
%type <vInt> ffieldlist, ffieldlist1
%type <vInt> lfieldlist, lfieldlist1
%type <vLong> var, objectname
%left AND OR
%left '=' NE '>' '<' LE GE
%left CONC
%left '+' '-'
%left '*' '/'
%left UNARY NOT
%% /* beginning of rules section */
functionlist : /* empty */
| functionlist
{
pc=maincode; basepc=initcode; maxcurr=maxmain;
nlocalvar=0;
}
stat sc
{
maincode=pc; initcode=basepc; maxmain=maxcurr;
}
| functionlist function
| functionlist setdebug
;
function : FUNCTION NAME
{
if (code == NULL) /* first function */
{
code = (Byte *) calloc(CODE_BLOCK, sizeof(Byte));
if (code == NULL)
{
lua_error("not enough memory");
err = 1;
}
maxcode = CODE_BLOCK;
}
pc=0; basepc=code; maxcurr=maxcode;
nlocalvar=0;
$<vWord>$ = lua_findsymbol($2);
}
'(' parlist ')'
{
if (lua_debug)
{
code_byte(SETFUNCTION);
code_word(lua_nfile-1);
code_word($<vWord>3);
}
lua_codeadjust (0);
}
block
END
{
if (lua_debug) code_byte(RESET);
code_byte(RETCODE); code_byte(nlocalvar);
s_tag($<vWord>3) = T_FUNCTION;
s_bvalue($<vWord>3) = calloc (pc, sizeof(Byte));
if (s_bvalue($<vWord>3) == NULL)
{
lua_error("not enough memory");
err = 1;
}
memcpy (s_bvalue($<vWord>3), basepc, pc*sizeof(Byte));
code = basepc; maxcode=maxcurr;
#if LISTING
PrintCode(code,code+pc);
#endif
}
;
statlist : /* empty */
| statlist stat sc
;
stat : {
ntemp = 0;
if (lua_debug)
{
code_byte(SETLINE); code_word(lua_linenumber);
}
}
stat1
sc : /* empty */ | ';' ;
stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
{
{
Long elseinit = $6+sizeof(Word)+1;
if (pc - elseinit == 0) /* no else */
{
pc -= sizeof(Word)+1;
elseinit = pc;
}
else
{
basepc[$6] = JMP;
code_word_at(basepc+$6+1, pc - elseinit);
}
basepc[$4] = IFFJMP;
code_word_at(basepc+$4+1,elseinit-($4+sizeof(Word)+1));
}
}
| WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END
{
basepc[$5] = IFFJMP;
code_word_at(basepc+$5+1, pc - ($5 + sizeof(Word)+1));
basepc[$7] = UPJMP;
code_word_at(basepc+$7+1, pc - ($<vLong>2));
}
| REPEAT {$<vLong>$=pc;} block UNTIL expr1 PrepJump
{
basepc[$6] = IFFUPJMP;
code_word_at(basepc+$6+1, pc - ($<vLong>2));
}
| varlist1 '=' exprlist1
{
{
int i;
if ($3 == 0 || nvarbuffer != ntemp - $1 * 2)
lua_codeadjust ($1 * 2 + nvarbuffer);
for (i=nvarbuffer-1; i>=0; i--)
lua_codestore (i);
if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0))
lua_codeadjust (0);
}
}
| functioncall { lua_codeadjust (0); }
| typeconstructor { lua_codeadjust (0); }
| LOCAL localdeclist decinit { add_nlocalvar($2); lua_codeadjust (0); }
;
elsepart : /* empty */
| ELSE block
| ELSEIF expr1 THEN PrepJump block PrepJump elsepart
{
{
Long elseinit = $6+sizeof(Word)+1;
if (pc - elseinit == 0) /* no else */
{
pc -= sizeof(Word)+1;
elseinit = pc;
}
else
{
basepc[$6] = JMP;
code_word_at(basepc+$6+1, pc - elseinit);
}
basepc[$4] = IFFJMP;
code_word_at(basepc+$4+1, elseinit - ($4 + sizeof(Word)+1));
}
}
;
block : {$<vInt>$ = nlocalvar;} statlist {ntemp = 0;} ret
{
if (nlocalvar != $<vInt>1)
{
nlocalvar = $<vInt>1;
lua_codeadjust (0);
}
}
;
ret : /* empty */
| { if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}}
RETURN exprlist sc
{
if (lua_debug) code_byte(RESET);
code_byte(RETCODE); code_byte(nlocalvar);
}
;
PrepJump : /* empty */
{
$$ = pc;
code_byte(0); /* open space */
code_word (0);
}
expr1 : expr { if ($1 == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}}
;
expr : '(' expr ')' { $$ = $2; }
| expr1 '=' expr1 { code_byte(EQOP); $$ = 1; ntemp--;}
| expr1 '<' expr1 { code_byte(LTOP); $$ = 1; ntemp--;}
| expr1 '>' expr1 { code_byte(LEOP); code_byte(NOTOP); $$ = 1; ntemp--;}
| expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; ntemp--;}
| expr1 LE expr1 { code_byte(LEOP); $$ = 1; ntemp--;}
| expr1 GE expr1 { code_byte(LTOP); code_byte(NOTOP); $$ = 1; ntemp--;}
| expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; ntemp--;}
| expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; ntemp--;}
| expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; ntemp--;}
| expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; ntemp--;}
| expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; ntemp--;}
| '+' expr1 %prec UNARY { $$ = 1; }
| '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;}
| typeconstructor { $$ = $1; }
| '@' '(' dimension ')'
{
code_byte(CREATEARRAY);
$$ = 1;
}
| var { lua_pushvar ($1); $$ = 1;}
| NUMBER { code_number($1); $$ = 1; }
| STRING
{
code_byte(PUSHSTRING);
code_word($1);
$$ = 1;
incr_ntemp();
}
| NIL {code_byte(PUSHNIL); $$ = 1; incr_ntemp();}
| functioncall
{
$$ = 0;
if (lua_debug)
{
code_byte(SETLINE); code_word(lua_linenumber);
}
}
| NOT expr1 { code_byte(NOTOP); $$ = 1;}
| expr1 AND PrepJump {code_byte(POP); ntemp--;} expr1
{
basepc[$3] = ONFJMP;
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
$$ = 1;
}
| expr1 OR PrepJump {code_byte(POP); ntemp--;} expr1
{
basepc[$3] = ONTJMP;
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
$$ = 1;
}
;
typeconstructor: '@'
{
code_byte(PUSHBYTE);
$<vLong>$ = pc; code_byte(0);
incr_ntemp();
code_byte(CREATEARRAY);
}
objectname fieldlist
{
basepc[$<vLong>2] = $4;
if ($3 < 0) /* there is no function to be called */
{
$$ = 1;
}
else
{
lua_pushvar ($3+1);
code_byte(PUSHMARK);
incr_ntemp();
code_byte(PUSHOBJECT);
incr_ntemp();
code_byte(CALLFUNC);
ntemp -= 4;
$$ = 0;
if (lua_debug)
{
code_byte(SETLINE); code_word(lua_linenumber);
}
}
}
;
dimension : /* empty */ { code_byte(PUSHNIL); incr_ntemp();}
| expr1
;
functioncall : functionvalue {code_byte(PUSHMARK); $<vInt>$ = ntemp; incr_ntemp();}
'(' exprlist ')' { code_byte(CALLFUNC); ntemp = $<vInt>2-1;}
functionvalue : var {lua_pushvar ($1); }
;
exprlist : /* empty */ { $$ = 1; }
| exprlist1 { $$ = $1; }
;
exprlist1 : expr { $$ = $1; }
| exprlist1 ',' {if (!$1){lua_codeadjust (ntemp+1); incr_ntemp();}}
expr {$$ = $4;}
;
parlist : /* empty */
| parlist1
;
parlist1 : NAME
{
localvar[nlocalvar]=lua_findsymbol($1);
add_nlocalvar(1);
}
| parlist1 ',' NAME
{
localvar[nlocalvar]=lua_findsymbol($3);
add_nlocalvar(1);
}
;
objectname : /* empty */ {$$=-1;}
| NAME {$$=lua_findsymbol($1);}
;
fieldlist : '{' ffieldlist '}'
{
flush_record($2%FIELDS_PER_FLUSH);
$$ = $2;
}
| '[' lfieldlist ']'
{
flush_list($2/FIELDS_PER_FLUSH, $2%FIELDS_PER_FLUSH);
$$ = $2;
}
;
ffieldlist : /* empty */ { $$ = 0; }
| ffieldlist1 { $$ = $1; }
;
ffieldlist1 : ffield {$$=1;}
| ffieldlist1 ',' ffield
{
$$=$1+1;
if ($$%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH);
}
;
ffield : NAME {$<vWord>$ = lua_findconstant($1);} '=' expr1
{
push_field($<vWord>2);
}
;
lfieldlist : /* empty */ { $$ = 0; }
| lfieldlist1 { $$ = $1; }
;
lfieldlist1 : expr1 {$$=1;}
| lfieldlist1 ',' expr1
{
$$=$1+1;
if ($$%FIELDS_PER_FLUSH == 0)
flush_list($$/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH);
}
;
varlist1 : var
{
nvarbuffer = 0;
varbuffer[nvarbuffer] = $1; incr_nvarbuffer();
$$ = ($1 == 0) ? 1 : 0;
}
| varlist1 ',' var
{
varbuffer[nvarbuffer] = $3; incr_nvarbuffer();
$$ = ($3 == 0) ? $1 + 1 : $1;
}
;
var : NAME
{
Word s = lua_findsymbol($1);
int local = lua_localname (s);
if (local == -1) /* global var */
$$ = s + 1; /* return positive value */
else
$$ = -(local+1); /* return negative value */
}
| var {lua_pushvar ($1);} '[' expr1 ']'
{
$$ = 0; /* indexed variable */
}
| var {lua_pushvar ($1);} '.' NAME
{
code_byte(PUSHSTRING);
code_word(lua_findconstant($4)); incr_ntemp();
$$ = 0; /* indexed variable */
}
;
localdeclist : NAME {localvar[nlocalvar]=lua_findsymbol($1); $$ = 1;}
| localdeclist ',' NAME
{
localvar[nlocalvar+$1]=lua_findsymbol($3);
$$ = $1+1;
}
;
decinit : /* empty */
| '=' exprlist1
;
setdebug : DEBUG {lua_debug = $1;}
%%
/*
** Search a local name and if find return its index. If do not find return -1
*/
static int lua_localname (Word n)
{
int i;
for (i=nlocalvar-1; i >= 0; i--)
if (n == localvar[i]) return i; /* local var */
return -1; /* global var */
}
/*
** Push a variable given a number. If number is positive, push global variable
** indexed by (number -1). If negative, push local indexed by ABS(number)-1.
** Otherwise, if zero, push indexed variable (record).
*/
static void lua_pushvar (long number)
{
if (number > 0) /* global var */
{
code_byte(PUSHGLOBAL);
code_word(number-1);
incr_ntemp();
}
else if (number < 0) /* local var */
{
number = (-number) - 1;
if (number < 10) code_byte(PUSHLOCAL0 + number);
else
{
code_byte(PUSHLOCAL);
code_byte(number);
}
incr_ntemp();
}
else
{
code_byte(PUSHINDEXED);
ntemp--;
}
}
static void lua_codeadjust (int n)
{
code_byte(ADJUST);
code_byte(n + nlocalvar);
}
static void lua_codestore (int i)
{
if (varbuffer[i] > 0) /* global var */
{
code_byte(STOREGLOBAL);
code_word(varbuffer[i]-1);
}
else if (varbuffer[i] < 0) /* local var */
{
int number = (-varbuffer[i]) - 1;
if (number < 10) code_byte(STORELOCAL0 + number);
else
{
code_byte(STORELOCAL);
code_byte(number);
}
}
else /* indexed var */
{
int j;
int upper=0; /* number of indexed variables upper */
int param; /* number of itens until indexed expression */
for (j=i+1; j <nvarbuffer; j++)
if (varbuffer[j] == 0) upper++;
param = upper*2 + i;
if (param == 0)
code_byte(STOREINDEXED0);
else
{
code_byte(STOREINDEXED);
code_byte(param);
}
}
}
void yyerror (char *s)
{
static char msg[256];
sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"",
s, lua_lasttext (), lua_linenumber, lua_filename());
lua_error (msg);
err = 1;
}
int yywrap (void)
{
return 1;
}
/*
** Parse LUA code and execute global statement.
** Return 0 on success or 1 on error.
*/
int lua_parse (void)
{
Byte *init = initcode = (Byte *) calloc(CODE_BLOCK, sizeof(Byte));
maincode = 0;
maxmain = CODE_BLOCK;
if (init == NULL)
{
lua_error("not enough memory");
return 1;
}
err = 0;
if (yyparse () || (err==1)) return 1;
initcode[maincode++] = HALT;
init = initcode;
#if LISTING
PrintCode(init,init+maincode);
#endif
if (lua_execute (init)) return 1;
free(init);
return 0;
}
#if LISTING
static void PrintCode (Byte *code, Byte *end)
{
Byte *p = code;
printf ("\n\nCODE\n");
while (p != end)
{
switch ((OpCode)*p)
{
case PUSHNIL: printf ("%d PUSHNIL\n", (p++)-code); break;
case PUSH0: case PUSH1: case PUSH2:
printf ("%d PUSH%c\n", p-code, *p-PUSH0+'0');
p++;
break;
case PUSHBYTE:
printf ("%d PUSHBYTE %d\n", p-code, *(++p));
p++;
break;
case PUSHWORD:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d PUSHWORD %d\n", n, c.w);
}
break;
case PUSHFLOAT:
{
CodeFloat c;
int n = p-code;
p++;
get_float(c,p);
printf ("%d PUSHFLOAT %f\n", n, c.f);
}
break;
case PUSHSTRING:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d PUSHSTRING %d\n", n, c.w);
}
break;
case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3:
case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7:
case PUSHLOCAL8: case PUSHLOCAL9:
printf ("%d PUSHLOCAL%c\n", p-code, *p-PUSHLOCAL0+'0');
p++;
break;
case PUSHLOCAL: printf ("%d PUSHLOCAL %d\n", p-code, *(++p));
p++;
break;
case PUSHGLOBAL:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d PUSHGLOBAL %d\n", n, c.w);
}
break;
case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break;
case PUSHMARK: printf ("%d PUSHMARK\n", (p++)-code); break;
case PUSHOBJECT: printf ("%d PUSHOBJECT\n", (p++)-code); break;
case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3:
case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7:
case STORELOCAL8: case STORELOCAL9:
printf ("%d STORELOCAL%c\n", p-code, *p-STORELOCAL0+'0');
p++;
break;
case STORELOCAL:
printf ("%d STORELOCAL %d\n", p-code, *(++p));
p++;
break;
case STOREGLOBAL:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d STOREGLOBAL %d\n", n, c.w);
}
break;
case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break;
case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p));
p++;
break;
case STORELIST0:
printf("%d STORELIST0 %d\n", p-code, *(++p));
p++;
break;
case STORELIST:
printf("%d STORELIST %d %d\n", p-code, *(p+1), *(p+2));
p+=3;
break;
case STORERECORD:
printf("%d STORERECORD %d\n", p-code, *(++p));
p += *p*sizeof(Word) + 1;
break;
case ADJUST:
printf ("%d ADJUST %d\n", p-code, *(++p));
p++;
break;
case CREATEARRAY: printf ("%d CREATEARRAY\n", (p++)-code); break;
case EQOP: printf ("%d EQOP\n", (p++)-code); break;
case LTOP: printf ("%d LTOP\n", (p++)-code); break;
case LEOP: printf ("%d LEOP\n", (p++)-code); break;
case ADDOP: printf ("%d ADDOP\n", (p++)-code); break;
case SUBOP: printf ("%d SUBOP\n", (p++)-code); break;
case MULTOP: printf ("%d MULTOP\n", (p++)-code); break;
case DIVOP: printf ("%d DIVOP\n", (p++)-code); break;
case CONCOP: printf ("%d CONCOP\n", (p++)-code); break;
case MINUSOP: printf ("%d MINUSOP\n", (p++)-code); break;
case NOTOP: printf ("%d NOTOP\n", (p++)-code); break;
case ONTJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d ONTJMP %d\n", n, c.w);
}
break;
case ONFJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d ONFJMP %d\n", n, c.w);
}
break;
case JMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d JMP %d\n", n, c.w);
}
break;
case UPJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d UPJMP %d\n", n, c.w);
}
break;
case IFFJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d IFFJMP %d\n", n, c.w);
}
break;
case IFFUPJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d IFFUPJMP %d\n", n, c.w);
}
break;
case POP: printf ("%d POP\n", (p++)-code); break;
case CALLFUNC: printf ("%d CALLFUNC\n", (p++)-code); break;
case RETCODE:
printf ("%d RETCODE %d\n", p-code, *(++p));
p++;
break;
case HALT: printf ("%d HALT\n", (p++)-code); break;
case SETFUNCTION:
{
CodeWord c1, c2;
int n = p-code;
p++;
get_word(c1,p);
get_word(c2,p);
printf ("%d SETFUNCTION %d %d\n", n, c1.w, c2.w);
}
break;
case SETLINE:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d SETLINE %d\n", n, c.w);
}
break;
case RESET: printf ("%d RESET\n", (p++)-code); break;
default: printf ("%d Cannot happen: code %d\n", (p++)-code, *(p-1)); break;
}
}
}
#endif
+695
View File
@@ -0,0 +1,695 @@
/*
** $Id: luaconf.h,v 1.64 2005/09/06 17:21:03 roberto Exp roberto $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
#ifndef lconfig_h
#define lconfig_h
#include <limits.h>
#include <stddef.h>
/*
** ==================================================================
** Search for "@@" to find all configurable definitions.
** ===================================================================
*/
/*
@@ LUA_ANSI controls the use of non-ansi features.
** CHANGE it (define it) if you want Lua to avoid the use of any
** non-ansi feature or library.
*/
#if defined(__STRICT_ANSI__)
#define LUA_ANSI
#endif
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
@* Lua libraries.
@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
@* C libraries.
** CHANGE them if your machine has a non-conventional directory
** hierarchy or if you want to install your libraries in
** non-conventional directories.
*/
#if defined(_WIN32)
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
*/
#define LUA_LDIR "!\\lua\\"
#define LUA_CDIR "!\\"
#define LUA_PATH_DEFAULT \
".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
#define LUA_CPATH_DEFAULT \
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
#else
#define LUA_ROOT "/usr/local/"
#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
#define LUA_PATH_DEFAULT \
"./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
#define LUA_CPATH_DEFAULT \
"./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
#endif
/*
@@ LUA_DIRSEP is the directory separator (for submodules).
** CHANGE it if your machine does not use "/" as the directory separator
** and is not Windows. (On Windows Lua automatically uses "\".)
*/
#if defined(_WIN32)
#define LUA_DIRSEP "\\"
#else
#define LUA_DIRSEP "/"
#endif
/*
@@ LUA_PATHSEP is the character that separates templates in a path.
@@ LUA_PATH_MARK is the string that marks the substitution points in a
@* template.
@@ LUA_EXECDIR in a Windows path is replaced by the executable's
@* directory.
@@ LUA_IGMARK is a mark to ignore all before it when bulding the
@* luaopen_ function name.
** CHANGE them if for some reason your system cannot use those
** characters. (E.g., if one of those characters is a common character
** in file/directory names.) Probably you do not need to change them.
*/
#define LUA_PATHSEP ";"
#define LUA_PATH_MARK "?"
#define LUA_EXECDIR "!"
#define LUA_IGMARK ":"
/*
@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
** machines, ptrdiff_t gives a good choice between int or long.)
*/
#define LUA_INTEGER ptrdiff_t
/*
@@ LUA_API is a mark for all core API functions.
@@ LUALIB_API is a mark for all standard library functions.
** CHANGE them if you need to define those functions in some special way.
** For instance, if you want to create one Windows DLL with the core and
** the libraries, you may want to use the following definition (define
** LUA_BUILD_AS_DLL to get it).
*/
#if defined(LUA_BUILD_AS_DLL)
#if defined(LUA_CORE) || defined(LUA_LIB)
#define LUA_API __declspec(dllexport)
#else
#define LUA_API __declspec(dllimport)
#endif
#else
#define LUA_API extern
#endif
/* more often than not the libs go together with the core */
#define LUALIB_API LUA_API
/*
@@ LUAI_FUNC is a mark for all extern functions that are not to be
@* exported to outside modules.
@@ LUAI_DATA is a mark for all extern (const) variables that are not to
@* be exported to outside modules.
** CHANGE them if you need to mark them in some special way. Elf/gcc
** (versions 3.2 and later) mark them as "hidden" to optimize access
** when Lua is compiled as a shared library.
*/
#if defined(luaall_c)
#define LUAI_FUNC static
#define LUAI_DATA /* empty */
#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
defined(__ELF__)
#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
#define LUAI_DATA LUAI_FUNC
#else
#define LUAI_FUNC extern
#define LUAI_DATA extern
#endif
/*
@@ lua_assert describes the internal assertions in Lua.
** CHANGE that only if you need to debug Lua.
*/
#define lua_assert(c) ((void)0)
/*
@@ LUA_QL describes how error messages quote program elements.
** CHANGE it if you want a different appearance.
*/
#define LUA_QL(x) "'" x "'"
#define LUA_QS LUA_QL("%s")
/*
@@ LUA_IDSIZE gives the maximum size for the description of the source
@* of a function in debug information.
** CHANGE it if you want a different size.
*/
#define LUA_IDSIZE 60
/*
** {==================================================================
** Stand-alone configuration
** ===================================================================
*/
#if defined(lua_c) || defined(luaall_c)
/*
@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
@* is, whether we're running lua interactively).
** CHANGE it if you have a better definition for non-POSIX/non-Windows
** systems.
*/
#if !defined(LUA_ANSI) && defined(_POSIX_C_SOURCE)
#include <unistd.h>
#define lua_stdin_is_tty() isatty(0)
#elif !defined(LUA_ANSI) && defined(_WIN32)
#include <io.h>
#include <stdio.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else
#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
#endif
/*
@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
** CHANGE them if you want different prompts. (You can also change the
** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
*/
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
/*
@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
** CHANGE it if your stand-alone interpreter has a different name and
** your system is not able to detect that name automatically.
*/
#define LUA_PROGNAME "lua"
/*
@@ LUA_MAXINPUT is the maximum length for an input line in the
@* stand-alone interpreter.
** CHANGE it if you need longer lines.
*/
#define LUA_MAXINPUT 512
/*
@@ lua_readline defines how to show a prompt and then read a line from
@* the standard input.
@@ lua_saveline defines how to "save" a read line in a "history".
@@ lua_freeline defines how to free a line read by lua_readline.
** CHANGE them if you want to improve this functionality (e.g., by using
** GNU readline and history facilities).
*/
#if defined(LUA_USE_READLINE)
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#define lua_readline(L,b,p) (((b)=readline(p)) != NULL)
#define lua_saveline(L,idx) \
if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
add_history(lua_tostring(L, idx)); /* add it to history */
#define lua_freeline(L,b) free(b)
#else
#define lua_readline(L,b,p) \
(fputs(p, stdout), fflush(stdout), /* show prompt */ \
fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
#define lua_saveline(L,idx) ((void)0)
#define lua_freeline(L,b) ((void)0)
#endif
#endif
/* }================================================================== */
/*
@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
@* as a percentage.
** CHANGE it if you want the GC to run faster or slower (higher values
** mean larger pauses which mean slower collection.) You can also change
** this value dynamically.
*/
#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
/*
@@ LUAI_GCMUL defines the default speed of garbage collection relative to
@* memory allocation as a percentage.
** CHANGE it if you want to change the granularity of the garbage
** collection. (Higher values mean coarser collections. 0 represents
** infinity, where each step performs a full collection.) You can also
** change this value dynamically.
*/
#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
/*
@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
** CHANGE it (define it) if you want exact compatibility with the
** behavior of setn/getn in Lua 5.0.
*/
#undef LUA_COMPAT_GETN
/*
@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
** CHANGE it to undefined as soon as you do not need a global 'loadlib'
** function (the function is still available as 'package.loadlib').
*/
#undef LUA_COMPAT_LOADLIB
/*
@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
** CHANGE it to undefined as soon as your programs use only '...' to
** access vararg parameters (instead of the old 'arg' table).
*/
#define LUA_COMPAT_VARARG
/*
@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
** CHANGE it to undefined as soon as your programs use 'math.fmod' or
** the new '%' operator instead of 'math.mod'.
*/
#define LUA_COMPAT_MOD
/*
@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
@* facility.
** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
** off the advisory error when nesting [[...]].
*/
#define LUA_COMPAT_LSTR 1
/*
@@ LUA_COMPAT_FIND controls compatibility with old 'string.find' behavior.
** CHANGE it to undefined as soon as your programs use 'string.find' only
** to find patterns.
*/
#define LUA_COMPAT_FIND
/*
@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
** CHANGE it to undefined as soon as you rename 'string.gfind' to
** 'string.gmatch'.
*/
#define LUA_COMPAT_GFIND
/*
@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
@* behavior.
** CHANGE it to undefined as soon as you replace to 'luaL_registry'
** your uses of 'luaL_openlib'
*/
#define LUA_COMPAT_OPENLIB
/*
@@ luai_apicheck is the assert macro used by the Lua-C API.
** CHANGE luai_apicheck if you want Lua to perform some checks in the
** parameters it gets from API calls. This may slow down the interpreter
** a bit, but may be quite useful when debugging C code that interfaces
** with Lua. A useful redefinition is to use assert.h.
*/
#if defined(LUA_USE_APICHECK)
#include <assert.h>
#define luai_apicheck(L,o) assert(o)
#else
/* (By default lua_assert is empty, so luai_apicheck is also empty.) */
#define luai_apicheck(L,o) lua_assert(o)
#endif
/*
@@ LUAI_BITSINT defines the number of bits in an int.
** CHANGE here if Lua cannot automatically detect the number of bits of
** your machine. Probably you do not need to change this.
*/
/* avoid overflows in comparison */
#if INT_MAX-20 < 32760
#define LUAI_BITSINT 16
#elif INT_MAX > 2147483640L
/* int has at least 32 bits */
#define LUAI_BITSINT 32
#else
#error "you must define LUA_BITSINT with number of bits in an integer"
#endif
/*
@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
@@ LUAI_INT32 is an signed integer with at least 32 bits.
@@ LUAI_UMEM is an unsigned integer big enough to count the total
@* memory used by Lua.
@@ LUAI_MEM is a signed integer big enough to count the total memory
@* used by Lua.
** CHANGE here if for some weird reason the default definitions are not
** good enough for your machine. (The definitions in the 'else'
** part always works, but may waste space on machines with 64-bit
** longs.) Probably you do not need to change this.
*/
#if LUAI_BITSINT >= 32
#define LUAI_UINT32 unsigned int
#define LUAI_INT32 int
#define LUAI_MAXINT32 INT_MAX
#define LUAI_UMEM size_t
#define LUAI_MEM ptrdiff_t
#else
/* 16-bit ints */
#define LUAI_UINT32 unsigned long
#define LUAI_INT32 long
#define LUAI_MAXINT32 LONG_MAX
#define LUAI_UMEM unsigned long
#define LUAI_MEM long
#endif
/*
@@ LUAI_MAXCALLS limits the number of nested calls.
** CHANGE it if you need really deep recursive calls. This limit is
** arbitrary; its only purpose is to stop infinite recursion before
** exhausting memory.
*/
#define LUAI_MAXCALLS 20000
/*
@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
@* can use.
** CHANGE it if you need lots of (Lua) stack space for your C
** functions. This limit is arbitrary; its only purpose is to stop C
** functions to consume unlimited stack space.
*/
#define LUAI_MAXCSTACK 2048
/*
** {==================================================================
** CHANGE (to smaller values) the following definitions if your system
** has a small C stack. (Or you may want to change them to larger
** values if your system has a large C stack and these limits are
** too rigid for you.) Some of these constants control the size of
** stack-allocated arrays used by the compiler or the interpreter, while
** others limit the maximum number of recursive calls that the compiler
** or the interpreter can perform. Values too large may cause a C stack
** overflow for some forms of deep constructs.
** ===================================================================
*/
/*
@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
@* syntactical nested non-terminals in a program.
*/
#define LUAI_MAXCCALLS 200
/*
@@ LUAI_MAXVARS is the maximum number of local variables per function
@* (must be smaller than 250).
*/
#define LUAI_MAXVARS 200
/*
@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
@* (must be smaller than 250).
*/
#define LUAI_MAXUPVALUES 60
/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
*/
#define LUAL_BUFFERSIZE BUFSIZ
/* }================================================================== */
/*
@@ lua_number2int is a macro to convert lua_Number to int.
@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
** CHANGE them if you know a faster way to convert a lua_Number to
** int (with any rounding method and without throwing errors) in your
** system. In Pentium machines, a naive typecast from double to int
** in C is extremely slow, so any alternative is worth trying.
*/
/* On a Pentium, resort to a trick */
#if !defined(LUA_ANSI) && !defined(__SSE2__) && \
(defined(__i386) || defined (_M_IX86))
union luai_Cast { double l_d; long l_l; };
#define lua_number2int(i,d) \
{ volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
#define lua_number2integer(i,n) lua_number2int(i, n)
/* this option always works, but may be slow */
#else
#define lua_number2int(i,d) ((i)=(int)(d))
#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
#endif
/*
** {==================================================================
@@ LUA_NUMBER is the type of numbers in Lua.
** CHANGE the following definitions only if you want to build Lua
** with a number type different from double. You may also need to
** change lua_number2int & lua_number2integer.
** ===================================================================
*/
#define LUA_NUMBER double
/*
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@* over a number.
*/
#define LUAI_UACNUMBER double
/*
@@ LUA_NUMBER_SCAN is the format for reading numbers.
@@ LUA_NUMBER_FMT is the format for writing numbers.
@@ lua_number2str converts a number to a string.
@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
@@ lua_str2number converts a string to a number.
*/
#define LUA_NUMBER_SCAN "%lf"
#define LUA_NUMBER_FMT "%.14g"
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
#define lua_str2number(s,p) strtod((s), (p))
/*
@@ The luai_num* macros define the primitive operations over numbers.
*/
#define luai_numadd(L,a,b) ((a)+(b))
#define luai_numsub(L,a,b) ((a)-(b))
#define luai_nummul(L,a,b) ((a)*(b))
#define luai_numdiv(L,a,b) ((a)/(b))
#define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b))
#define luai_numpow(L,a,b) pow(a,b)
#define luai_numunm(L,a) (-(a))
#define luai_numeq(L,a,b) ((a)==(b))
#define luai_numlt(L,a,b) ((a)<(b))
#define luai_numle(L,a,b) ((a)<=(b))
/* }================================================================== */
/*
@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
** CHANGE it if your system requires alignments larger than double. (For
** instance, if your system supports long doubles and they must be
** aligned in 16-byte boundaries, then you should add long double in the
** union.) Probably you do not need to change this.
*/
#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
/*
@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
** CHANGE them if you prefer to use longjmp/setjmp even with C++
** or if want/don't to use _longjmp/_setjmp instead of regular
** longjmp/setjmp. By default, Lua handles errors with exceptions when
** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
** and with longjmp/setjmp otherwise.
*/
#if defined(__cplusplus)
/* C++ exceptions */
#define LUAI_THROW(L,c) throw(c)
#define LUAI_TRY(L,c,a) try { a } catch(...) \
{ if ((c)->status == 0) (c)->status = -1; }
#define luai_jmpbuf int /* dummy variable */
#elif defined(LUA_USE_ULONGJMP)
/* in Unix, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#else
/* default handling with long jumps */
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#endif
/*
@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
@* can do during pattern-matching.
** CHANGE it if you need more captures. This limit is arbitrary.
*/
#define LUA_MAXCAPTURES 32
/*
@@ lua_tmpnam is the function that the OS library uses to create a
@* temporary name.
@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
** CHANGE them if you have an alternative to tmpnam (which is considered
** insecure) or if you want the original tmpnam anyway. By default, Lua
** uses tmpnam except when POSIX is available, where it uses mkstemp.
*/
#if defined(loslib_c) || defined(luaall_c)
#if !defined(LUA_ANSI) && defined(_POSIX_C_SOURCE)
#include <unistd.h>
#define LUA_TMPNAMBUFSIZE 32
#define lua_tmpnam(b,e) { \
strcpy(b, "/tmp/lua_XXXXXX"); \
e = mkstemp(b); \
if (e != -1) close(e); \
e = (e == -1); }
#else
#define LUA_TMPNAMBUFSIZE L_tmpnam
#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
#endif
#endif
/*
@@ lua_popen spawns a new process connected to the current one through
@* the file streams.
** CHANGE it if you have a way to implement it in your system.
*/
#if !defined(LUA_ANSI) && defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 2
#define lua_popen(L,c,m) popen(c,m)
#define lua_pclose(L,file) (pclose(file) != -1)
#elif !defined(LUA_ANSI) && defined(_WIN32)
#define lua_popen(L,c,m) _popen(c,m)
#define lua_pclose(L,file) (_pclose(file) != -1)
#else
#define lua_popen(L,c,m) \
((void)c, (void)m, luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
#define lua_pclose(L,file) ((void)file, 0)
#endif
/*
@@ LUA_DL_* define which dynamic-library system Lua should use.
** CHANGE here if Lua has problems choosing the appropriate
** dynamic-library system for your platform (either Windows' DLL, Mac's
** dyld, or Unix's dlopen). If your system is some kind of Unix, there
** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
** it. To use dlopen you also need to adapt the src/Makefile (probably
** adding -ldl to the linker options), so Lua does not select it
** automatically. (When you change the makefile to add -ldl, you must
** also add -DLUA_USE_DLOPEN.)
** If you do not want any kind of dynamic library, undefine all these
** options (or just remove these definitions).
*/
#if !defined(LUA_ANSI)
#if defined(_WIN32)
#define LUA_DL_DLL
#elif defined(__APPLE__) && defined(__MACH__)
#define LUA_DL_DYLD
#elif defined(LUA_USE_DLOPEN)
#define LUA_DL_DLOPEN
#endif
#endif
/*
@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
@* (the data goes just *before* the lua_State pointer).
** CHANGE (define) this if you really need that. This value must be
** a multiple of the maximum alignment required for your machine.
*/
#define LUAI_EXTRASPACE 0
/*
@@ luai_userstate* allow user-specific actions on threads.
** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
** extra when a thread is created/deleted/resumed/yielded.
*/
#define luai_userstateopen(L) ((void)0)
#define luai_userstatefree(L) ((void)0)
#define luai_userstateresume(L,n) ((void)0)
#define luai_userstateyield(L,n) ((void)0)
/* =================================================================== */
/*
** Local configuration. You can use this space to add your redefinitions
** without modifying the main part of the file.
*/
#endif
+39 -8
View File
@@ -1,16 +1,47 @@
/*
** Libraries to be used in LUA programs
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: $
** $Id: lualib.h,v 1.34 2005/04/13 17:24:20 roberto Exp roberto $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
#ifndef lualib_h
#define lualib_h
void iolib_open (void);
void strlib_open (void);
void mathlib_open (void);
#include "lua.h"
/* Key to file-handle type */
#define LUA_FILEHANDLE "FILE*"
#define LUA_COLIBNAME "coroutine"
LUALIB_API int (luaopen_base) (lua_State *L);
#define LUA_TABLIBNAME "table"
LUALIB_API int (luaopen_table) (lua_State *L);
#define LUA_IOLIBNAME "io"
LUALIB_API int (luaopen_io) (lua_State *L);
#define LUA_OSLIBNAME "os"
LUALIB_API int (luaopen_os) (lua_State *L);
#define LUA_STRLIBNAME "string"
LUALIB_API int (luaopen_string) (lua_State *L);
#define LUA_MATHLIBNAME "math"
LUALIB_API int (luaopen_math) (lua_State *L);
#define LUA_DBLIBNAME "debug"
LUALIB_API int (luaopen_debug) (lua_State *L);
#define LUA_LOADLIBNAME "package"
LUALIB_API int (luaopen_package) (lua_State *L);
/* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L);
#endif
+296
View File
@@ -0,0 +1,296 @@
/*
** $Id: lundump.c,v 2.4 2005/05/05 20:47:02 roberto Exp roberto $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
#define lundump_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lmem.h"
#include "lopcodes.h"
#include "lstring.h"
#include "lundump.h"
#include "lzio.h"
#define LoadByte (lu_byte) ezgetc
typedef struct {
lua_State* L;
ZIO* Z;
Mbuffer* b;
int swap;
const char* name;
} LoadState;
static void unexpectedEOZ (LoadState* S)
{
luaG_runerror(S->L,"unexpected end of file in %s",S->name);
}
static int ezgetc (LoadState* S)
{
int c=zgetc(S->Z);
if (c==EOZ) unexpectedEOZ(S);
return c;
}
static void ezread (LoadState* S, void* b, size_t n)
{
size_t r=luaZ_read(S->Z,b,n);
if (r!=0) unexpectedEOZ(S);
}
static void LoadBlock (LoadState* S, void* b, size_t size)
{
if (S->swap)
{
char* p=(char*) b+size-1;
size_t n=size;
while (n--) *p--=(char)ezgetc(S);
}
else
ezread(S,b,size);
}
static void LoadVector (LoadState* S, void* b, int m, size_t size)
{
if (S->swap)
{
char* q=(char*) b;
while (m--)
{
char* p=q+size-1;
size_t n=size;
while (n--) *p--=(char)ezgetc(S);
q+=size;
}
}
else
ezread(S,b,m*size);
}
static int LoadInt (LoadState* S)
{
int x;
LoadBlock(S,&x,sizeof(x));
if (x<0) luaG_runerror(S->L,"bad integer in %s",S->name);
return x;
}
static size_t LoadSize (LoadState* S)
{
size_t x;
LoadBlock(S,&x,sizeof(x));
return x;
}
static lua_Number LoadNumber (LoadState* S)
{
lua_Number x;
LoadBlock(S,&x,sizeof(x));
return x;
}
static TString* LoadString (LoadState* S)
{
size_t size=LoadSize(S);
if (size==0)
return NULL;
else
{
char* s=luaZ_openspace(S->L,S->b,size);
ezread(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
}
}
static void LoadCode (LoadState* S, Proto* f)
{
int size=LoadInt(S);
f->code=luaM_newvector(S->L,size,Instruction);
f->sizecode=size;
LoadVector(S,f->code,size,sizeof(*f->code));
}
static void LoadLocals (LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
f->locvars=luaM_newvector(S->L,n,LocVar);
f->sizelocvars=n;
for (i=0; i<n; i++) f->locvars[i].varname=NULL;
for (i=0; i<n; i++)
{
f->locvars[i].varname=LoadString(S);
f->locvars[i].startpc=LoadInt(S);
f->locvars[i].endpc=LoadInt(S);
}
}
static void LoadLines (LoadState* S, Proto* f)
{
int size=LoadInt(S);
f->lineinfo=luaM_newvector(S->L,size,int);
f->sizelineinfo=size;
LoadVector(S,f->lineinfo,size,sizeof(*f->lineinfo));
}
static void LoadUpvalues (LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
if (n!=0 && n!=f->nups)
luaG_runerror(S->L,"bad nupvalues in %s: read %d; expected %d",
S->name,n,f->nups);
f->upvalues=luaM_newvector(S->L,n,TString*);
f->sizeupvalues=n;
for (i=0; i<n; i++) f->upvalues[i]=NULL;
for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
}
static Proto* LoadFunction (LoadState* S, TString* p);
static void LoadConstants (LoadState* S, Proto* f)
{
int i,n;
lua_State *L=S->L;
n=LoadInt(S);
f->k=luaM_newvector(L,n,TValue);
f->sizek=n;
for (i=0; i<n; i++) setnilvalue(&f->k[i]);
for (i=0; i<n; i++)
{
TValue* o=&f->k[i];
int t=LoadByte(S);
switch (t)
{
case LUA_TNUMBER:
setnvalue(o,LoadNumber(S));
break;
case LUA_TSTRING:
setsvalue2n(L, o,LoadString(S));
break;
case LUA_TNIL:
setnilvalue(o);
break;
case LUA_TBOOLEAN:
setbvalue(o, LoadByte(S));
break;
default:
luaG_runerror(L,"bad constant type (%d) in %s",t,S->name);
break;
}
}
n=LoadInt(S);
f->p=luaM_newvector(L,n,Proto*);
f->sizep=n;
for (i=0; i<n; i++) f->p[i]=NULL;
for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
}
static Proto* LoadFunction (LoadState* S, TString* p)
{
lua_State *L=S->L;
Proto* f=luaF_newproto(L);
setptvalue2s(L, L->top, f);
incr_top(L);
f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->linedefined=LoadInt(S);
f->lastlinedefined=LoadInt(S);
f->nups=LoadByte(S);
f->numparams=LoadByte(S);
f->is_vararg=LoadByte(S);
f->maxstacksize=LoadByte(S);
LoadLines(S,f);
LoadLocals(S,f);
LoadUpvalues(S,f);
LoadConstants(S,f);
LoadCode(S,f);
#ifndef TRUST_BINARIES
if (!luaG_checkcode(f)) luaG_runerror(L,"bad code in %s",S->name);
#endif
L->top--;
return f;
}
static void LoadSignature (LoadState* S)
{
const char* s=LUA_SIGNATURE;
while (*s!=0 && ezgetc(S)==*s)
++s;
if (*s!=0) luaG_runerror(S->L,"bad signature in %s",S->name);
}
static void TestSize (LoadState* S, int s, const char* what)
{
int r=LoadByte(S);
if (r!=s)
luaG_runerror(S->L,"virtual machine mismatch in %s: "
"size of %s is %d but read %d",S->name,what,s,r);
}
#define TESTSIZE(s,w) TestSize(S,s,w)
#define V(v) v/16,v%16
static void LoadHeader (LoadState* S)
{
int version;
lua_Number x,tx=TEST_NUMBER;
LoadSignature(S);
version=LoadByte(S);
if (version>VERSION)
luaG_runerror(S->L,"%s too new: "
"read version %d.%d; expected at most %d.%d",
S->name,V(version),V(VERSION));
if (version<VERSION0) /* check last major change */
luaG_runerror(S->L,"%s too old: "
"read version %d.%d; expected at least %d.%d",
S->name,V(version),V(VERSION0));
S->swap=(luaU_endianness()!=LoadByte(S)); /* need to swap bytes? */
TESTSIZE(sizeof(int),"int");
TESTSIZE(sizeof(size_t), "size_t");
TESTSIZE(sizeof(Instruction), "Instruction");
TESTSIZE(sizeof(lua_Number), "number");
x=LoadNumber(S);
if ((long)x!=(long)tx) /* disregard errors in last bits of fraction */
luaG_runerror(S->L,"unknown number format in %s",S->name);
}
static Proto* LoadChunk (LoadState* S)
{
LoadHeader(S);
return LoadFunction(S,NULL);
}
/*
** load precompiled chunk
*/
Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char *s)
{
LoadState S;
if (*s=='@' || *s=='=')
S.name=s+1;
else if (*s==LUA_SIGNATURE[0])
S.name="binary string";
else
S.name=s;
S.L=L;
S.Z=Z;
S.b=buff;
return LoadChunk(&S);
}
/*
** find byte order
*/
int luaU_endianness (void)
{
int x=1;
return *(char*)&x;
}
+35
View File
@@ -0,0 +1,35 @@
/*
** $Id: lundump.h,v 1.35 2005/04/25 19:24:10 roberto Exp roberto $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
#ifndef lundump_h
#define lundump_h
#include "lobject.h"
#include "lzio.h"
/* load one chunk; from lundump.c */
LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff,
const char *name);
/* find byte order; from lundump.c */
LUAI_FUNC int luaU_endianness (void);
/* dump one chunk; from ldump.c */
LUAI_FUNC int luaU_dump (lua_State* L, const Proto* Main, lua_Writer w,
void* data, int strip);
/* print one chunk; from print.c */
LUAI_FUNC void luaU_print (const Proto* Main);
/* definitions for headers of binary files */
#define VERSION 0x50 /* last format change was in 5.0 */
#define VERSION0 0x50 /* last major change was in 5.0 */
/* a multiple of PI for testing native format */
/* multiplying by 1E7 gives non-trivial integer values */
#define TEST_NUMBER ((lua_Number)3.14159265358979323846E7)
#endif
+792
View File
@@ -0,0 +1,792 @@
/*
** $Id: lvm.c,v 2.54 2005/08/29 20:49:21 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lvm_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"
/* limit for table tag-method chains (to avoid loops) */
#define MAXTAGLOOP 100
const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
lua_Number num;
if (ttisnumber(obj)) return obj;
if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
setnvalue(n, num);
return n;
}
else
return NULL;
}
int luaV_tostring (lua_State *L, StkId obj) {
if (!ttisnumber(obj))
return 0;
else {
char s[LUAI_MAXNUMBER2STR];
lua_Number n = nvalue(obj);
lua_number2str(s, n);
setsvalue2s(L, obj, luaS_new(L, s));
return 1;
}
}
static void traceexec (lua_State *L, const Instruction *pc) {
lu_byte mask = L->hookmask;
const Instruction *oldpc = L->savedpc;
L->savedpc = pc;
if (mask > LUA_MASKLINE) { /* instruction-hook set? */
if (L->hookcount == 0) {
resethookcount(L);
luaD_callhook(L, LUA_HOOKCOUNT, -1);
return;
}
}
if (mask & LUA_MASKLINE) {
Proto *p = ci_func(L->ci)->l.p;
int npc = pcRel(pc, p);
int newline = getline(p, npc);
/* call linehook when enter a new function, when jump back (loop),
or when enter a new line */
if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
luaD_callhook(L, LUA_HOOKLINE, newline);
}
}
static void callTMres (lua_State *L, StkId res, const TValue *f,
const TValue *p1, const TValue *p2) {
ptrdiff_t result = savestack(L, res);
setobj2s(L, L->top, f); /* push function */
setobj2s(L, L->top+1, p1); /* 1st argument */
setobj2s(L, L->top+2, p2); /* 2nd argument */
luaD_checkstack(L, 3);
L->top += 3;
luaD_call(L, L->top - 3, 1);
res = restorestack(L, result);
L->top--;
setobjs2s(L, res, L->top);
}
static void callTM (lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, const TValue *p3) {
setobj2s(L, L->top, f); /* push function */
setobj2s(L, L->top+1, p1); /* 1st argument */
setobj2s(L, L->top+2, p2); /* 2nd argument */
setobj2s(L, L->top+3, p3); /* 3th argument */
luaD_checkstack(L, 4);
L->top += 4;
luaD_call(L, L->top - 4, 0);
}
void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
int loop;
for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
}
/* else will try the tag method */
}
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
luaG_typeerror(L, t, "index");
if (ttisfunction(tm)) {
callTMres(L, val, tm, t, key);
return;
}
t = tm; /* else repeat with `tm' */
}
luaG_runerror(L, "loop in gettable");
}
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
int loop;
for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
if (!ttisnil(oldval) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
setobj2t(L, oldval, val);
luaC_barriert(L, h, val);
return;
}
/* else will try the tag method */
}
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
luaG_typeerror(L, t, "index");
if (ttisfunction(tm)) {
callTM(L, tm, t, key, val);
return;
}
t = tm; /* else repeat with `tm' */
}
luaG_runerror(L, "loop in settable");
}
static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
StkId res, TMS event) {
const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
if (ttisnil(tm))
tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
if (!ttisfunction(tm)) return 0;
callTMres(L, res, tm, p1, p2);
return 1;
}
static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
TMS event) {
const TValue *tm1 = fasttm(L, mt1, event);
const TValue *tm2;
if (tm1 == NULL) return NULL; /* no metamethod */
if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
tm2 = fasttm(L, mt2, event);
if (tm2 == NULL) return NULL; /* no metamethod */
if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
return tm1;
return NULL;
}
static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
TMS event) {
const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
const TValue *tm2;
if (ttisnil(tm1)) return -1; /* no metamethod? */
tm2 = luaT_gettmbyobj(L, p2, event);
if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
return -1;
callTMres(L, L->top, tm1, p1, p2);
return !l_isfalse(L->top);
}
static int l_strcmp (const TString *ls, const TString *rs) {
const char *l = getstr(ls);
size_t ll = ls->tsv.len;
const char *r = getstr(rs);
size_t lr = rs->tsv.len;
for (;;) {
int temp = strcoll(l, r);
if (temp != 0) return temp;
else { /* strings are equal up to a `\0' */
size_t len = strlen(l); /* index of first `\0' in both strings */
if (len == lr) /* r is finished? */
return (len == ll) ? 0 : 1;
else if (len == ll) /* l is finished? */
return -1; /* l is smaller than r (because r is not finished) */
/* both strings longer than `len'; go on comparing (after the `\0') */
len++;
l += len; ll -= len; r += len; lr -= len;
}
}
}
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
int res;
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
return luai_numlt(L, nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
return res;
return luaG_ordererror(L, l, r);
}
static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
int res;
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
return luai_numle(L, nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
return res;
else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
return !res;
return luaG_ordererror(L, l, r);
}
int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
const TValue *tm;
lua_assert(ttype(t1) == ttype(t2));
switch (ttype(t1)) {
case LUA_TNIL: return 1;
case LUA_TNUMBER: return luai_numeq(L, nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
case LUA_TUSERDATA: {
if (uvalue(t1) == uvalue(t2)) return 1;
tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
TM_EQ);
break; /* will try TM */
}
case LUA_TTABLE: {
if (hvalue(t1) == hvalue(t2)) return 1;
tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
break; /* will try TM */
}
default: return gcvalue(t1) == gcvalue(t2);
}
if (tm == NULL) return 0; /* no TM? */
callTMres(L, L->top, tm, t1, t2); /* call TM */
return !l_isfalse(L->top);
}
void luaV_concat (lua_State *L, int total, int last) {
do {
StkId top = L->base + last + 1;
int n = 2; /* number of elements handled in this pass (at least 2) */
if (!tostring(L, top-2) || !tostring(L, top-1)) {
if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
luaG_concaterror(L, top-2, top-1);
} else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */
/* at least two string values; get as many as possible */
size_t tl = tsvalue(top-1)->len;
char *buffer;
int i;
/* collect total length */
for (n = 1; n < total && tostring(L, top-n-1); n++) {
size_t l = tsvalue(top-n-1)->len;
if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
tl += l;
}
buffer = luaZ_openspace(L, &G(L)->buff, tl);
tl = 0;
for (i=n; i>0; i--) { /* concat all strings */
size_t l = tsvalue(top-i)->len;
memcpy(buffer+tl, svalue(top-i), l);
tl += l;
}
setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
}
total -= n-1; /* got `n' strings to create 1 new */
last -= n-1;
} while (total > 1); /* repeat until only 1 result left */
}
static void Arith (lua_State *L, StkId ra, const TValue *rb,
const TValue *rc, TMS op) {
TValue tempb, tempc;
const TValue *b, *c;
if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
(c = luaV_tonumber(rc, &tempc)) != NULL) {
lua_Number nb = nvalue(b), nc = nvalue(c);
switch (op) {
case TM_ADD: setnvalue(ra, luai_numadd(L, nb, nc)); break;
case TM_SUB: setnvalue(ra, luai_numsub(L, nb, nc)); break;
case TM_MUL: setnvalue(ra, luai_nummul(L, nb, nc)); break;
case TM_DIV: setnvalue(ra, luai_numdiv(L, nb, nc)); break;
case TM_MOD: setnvalue(ra, luai_nummod(L, nb, nc)); break;
case TM_POW: setnvalue(ra, luai_numpow(L, nb, nc)); break;
case TM_UNM: setnvalue(ra, luai_numunm(L, nb)); break;
default: lua_assert(0); break;
}
}
else if (!call_binTM(L, rb, rc, ra, op))
luaG_aritherror(L, rb, rc);
}
/*
** some macros for common tasks in `luaV_execute'
*/
#define runtime_check(L, c) { if (!(c)) break; }
#define RA(i) (base+GETARG_A(i))
/* to be used after possible stack reallocation */
#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl;
StkId base;
TValue *k;
const Instruction *pc;
reentry: /* entry point */
pc = L->savedpc;
cl = &clvalue(L->ci->func)->l;
base = L->base;
k = cl->p->k;
/* main loop of interpreter */
for (;;) {
const Instruction i = *pc++;
StkId ra;
if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
traceexec(L, pc);
if (L->status == LUA_YIELD) { /* did hook yield? */
L->savedpc = pc - 1;
return;
}
base = L->base;
}
/* warning!! several calls may realloc the stack and invalidate `ra' */
ra = RA(i);
lua_assert(base == L->base && L->base == L->ci->base);
lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
switch (GET_OPCODE(i)) {
case OP_MOVE: {
setobjs2s(L, ra, RB(i));
continue;
}
case OP_LOADK: {
setobj2s(L, ra, KBx(i));
continue;
}
case OP_LOADBOOL: {
setbvalue(ra, GETARG_B(i));
if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
continue;
}
case OP_LOADNIL: {
TValue *rb = RB(i);
do {
setnilvalue(rb--);
} while (rb >= ra);
continue;
}
case OP_GETUPVAL: {
int b = GETARG_B(i);
setobj2s(L, ra, cl->upvals[b]->v);
continue;
}
case OP_GETGLOBAL: {
TValue g;
TValue *rb = KBx(i);
sethvalue(L, &g, cl->env);
lua_assert(ttisstring(rb));
Protect(luaV_gettable(L, &g, rb, ra));
continue;
}
case OP_GETTABLE: {
Protect(luaV_gettable(L, RB(i), RKC(i), ra));
continue;
}
case OP_SETGLOBAL: {
TValue g;
sethvalue(L, &g, cl->env);
lua_assert(ttisstring(KBx(i)));
Protect(luaV_settable(L, &g, KBx(i), ra));
continue;
}
case OP_SETUPVAL: {
UpVal *uv = cl->upvals[GETARG_B(i)];
setobj(L, uv->v, ra);
luaC_barrier(L, uv, ra);
continue;
}
case OP_SETTABLE: {
Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
continue;
}
case OP_NEWTABLE: {
int b = GETARG_B(i);
int c = GETARG_C(i);
sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
Protect(luaC_checkGC(L));
continue;
}
case OP_SELF: {
StkId rb = RB(i);
setobjs2s(L, ra+1, rb);
Protect(luaV_gettable(L, rb, RKC(i), ra));
continue;
}
case OP_ADD: {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
setnvalue(ra, luai_numadd(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_ADD));
continue;
}
case OP_SUB: {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
setnvalue(ra, luai_numsub(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_SUB));
continue;
}
case OP_MUL: {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
setnvalue(ra, luai_nummul(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_MUL));
continue;
}
case OP_DIV: {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
setnvalue(ra, luai_numdiv(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_DIV));
continue;
}
case OP_MOD: {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
setnvalue(ra, luai_nummod(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_MOD));
continue;
}
case OP_POW: {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
setnvalue(ra, luai_numpow(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_POW));
continue;
}
case OP_UNM: {
TValue *rb = RB(i);
if (ttisnumber(rb)) {
lua_Number nb = nvalue(rb);
setnvalue(ra, luai_numunm(L, nb));
}
else {
Protect(Arith(L, ra, rb, rb, TM_UNM));
}
continue;
}
case OP_NOT: {
int res = l_isfalse(RB(i)); /* next assignment may change this value */
setbvalue(ra, res);
continue;
}
case OP_LEN: {
const TValue *rb = RB(i);
switch (ttype(rb)) {
case LUA_TTABLE: {
setnvalue(ra, cast(lua_Number, luaH_getn(hvalue(rb))));
break;
}
case LUA_TSTRING: {
setnvalue(ra, cast(lua_Number, tsvalue(rb)->len));
break;
}
default: { /* try metamethod */
Protect(
if (!call_binTM(L, rb, &luaO_nilobject, ra, TM_LEN))
luaG_typeerror(L, rb, "get length of");
)
}
}
continue;
}
case OP_CONCAT: {
int b = GETARG_B(i);
int c = GETARG_C(i);
Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
setobjs2s(L, RA(i), base+b);
continue;
}
case OP_JMP: {
dojump(L, pc, GETARG_sBx(i));
continue;
}
case OP_EQ: {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
Protect(
if (equalobj(L, rb, rc) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
)
pc++;
continue;
}
case OP_LT: {
Protect(
if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
)
pc++;
continue;
}
case OP_LE: {
Protect(
if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
)
pc++;
continue;
}
case OP_TEST: {
if (l_isfalse(ra) == GETARG_C(i)) pc++;
else
dojump(L, pc, GETARG_sBx(*pc) + 1);
continue;
}
case OP_TESTSET: {
TValue *rb = RB(i);
if (l_isfalse(rb) == GETARG_C(i)) pc++;
else {
setobjs2s(L, ra, rb);
dojump(L, pc, GETARG_sBx(*pc) + 1);
}
continue;
}
case OP_CALL: {
int b = GETARG_B(i);
int nresults = GETARG_C(i) - 1;
if (b != 0) L->top = ra+b; /* else previous instruction set top */
L->savedpc = pc;
switch (luaD_precall(L, ra, nresults)) {
case PCRLUA: {
nexeccalls++;
goto reentry; /* restart luaV_execute over new Lua function */
}
case PCRC: {
/* it was a C function (`precall' called it); adjust results */
if (nresults >= 0) L->top = L->ci->top;
base = L->base;
continue;
}
default: {
return; /* yield */
}
}
}
case OP_TAILCALL: {
int b = GETARG_B(i);
if (b != 0) L->top = ra+b; /* else previous instruction set top */
L->savedpc = pc;
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
switch (luaD_precall(L, ra, LUA_MULTRET)) {
case PCRLUA: {
/* tail call: put new frame in place of previous one */
CallInfo *ci = L->ci - 1; /* previous frame */
int aux;
StkId func = ci->func;
StkId pfunc = (ci+1)->func; /* previous function index */
if (L->openupval) luaF_close(L, ci->base);
L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
setobjs2s(L, func+aux, pfunc+aux);
ci->top = L->top = func+aux; /* correct top */
lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
ci->savedpc = L->savedpc;
ci->tailcalls++; /* one more call lost */
L->ci--; /* remove new frame */
goto reentry;
}
case PCRC: { /* it was a C function (`precall' called it) */
base = L->base;
continue;
}
default: {
return; /* yield */
}
}
}
case OP_RETURN: {
int b = GETARG_B(i);
if (b != 0) L->top = ra+b-1;
if (L->openupval) luaF_close(L, base);
L->savedpc = pc;
b = luaD_poscall(L, ra);
if (--nexeccalls == 0) /* was previous function running `here'? */
return; /* no: return */
else { /* yes: continue its execution */
if (b) L->top = L->ci->top;
lua_assert(isLua(L->ci));
lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
goto reentry;
}
}
case OP_FORLOOP: {
lua_Number step = nvalue(ra+2);
lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
lua_Number limit = nvalue(ra+1);
if (step > 0 ? luai_numle(L, idx, limit) : luai_numle(L, limit, idx)) {
dojump(L, pc, GETARG_sBx(i)); /* jump back */
setnvalue(ra, idx); /* update internal index... */
setnvalue(ra+3, idx); /* ...and external index */
}
continue;
}
case OP_FORPREP: {
const TValue *init = ra;
const TValue *plimit = ra+1;
const TValue *pstep = ra+2;
L->savedpc = pc; /* next steps may throw errors */
if (!tonumber(init, ra))
luaG_runerror(L, LUA_QL("for") " initial value must be a number");
else if (!tonumber(plimit, ra+1))
luaG_runerror(L, LUA_QL("for") " limit must be a number");
else if (!tonumber(pstep, ra+2))
luaG_runerror(L, LUA_QL("for") " step must be a number");
setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
dojump(L, pc, GETARG_sBx(i));
continue;
}
case OP_TFORLOOP: {
StkId cb = ra + 3; /* call base */
setobjs2s(L, cb+2, ra+2);
setobjs2s(L, cb+1, ra+1);
setobjs2s(L, cb, ra);
L->top = cb+3; /* func. + 2 args (state and index) */
Protect(luaD_call(L, cb, GETARG_C(i)));
L->top = L->ci->top;
cb = RA(i) + 3; /* previous call may change the stack */
if (ttisnil(cb)) /* break loop? */
pc++; /* skip jump (break loop) */
else {
setobjs2s(L, cb-1, cb); /* save control variable */
dojump(L, pc, GETARG_sBx(*pc) + 1); /* jump back */
}
continue;
}
case OP_SETLIST: {
int n = GETARG_B(i);
int c = GETARG_C(i);
int last;
Table *h;
if (n == 0) {
n = cast(int, L->top - ra) - 1;
L->top = L->ci->top;
}
if (c == 0) c = cast(int, *pc++);
runtime_check(L, ttistable(ra));
h = hvalue(ra);
last = ((c-1)*LFIELDS_PER_FLUSH) + n;
if (last > h->sizearray) /* needs more space? */
luaH_resizearray(L, h, last); /* pre-alloc it at once */
for (; n > 0; n--) {
TValue *val = ra+n;
setobj2t(L, luaH_setnum(L, h, last--), val);
luaC_barriert(L, h, val);
}
continue;
}
case OP_CLOSE: {
luaF_close(L, ra);
continue;
}
case OP_CLOSURE: {
Proto *p;
Closure *ncl;
int nup, j;
p = cl->p->p[GETARG_Bx(i)];
nup = p->nups;
ncl = luaF_newLclosure(L, nup, cl->env);
ncl->l.p = p;
for (j=0; j<nup; j++, pc++) {
if (GET_OPCODE(*pc) == OP_GETUPVAL)
ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
else {
lua_assert(GET_OPCODE(*pc) == OP_MOVE);
ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
}
}
setclvalue(L, ra, ncl);
Protect(luaC_checkGC(L));
continue;
}
case OP_VARARG: {
int b = GETARG_B(i) - 1;
int j;
CallInfo *ci = L->ci;
int n = cast(int, ci->base - ci->func) - cl->p->numparams - 1;
if (b == LUA_MULTRET) {
Protect(luaD_checkstack(L, n));
ra = RA(i); /* previous call may change the stack */
b = n;
L->top = ra + n;
}
for (j = 0; j < b; j++) {
if (j < n) {
setobjs2s(L, ra + j, ci->base - n + j);
}
else {
setnilvalue(ra + j);
}
}
continue;
}
}
}
}
+36
View File
@@ -0,0 +1,36 @@
/*
** $Id: lvm.h,v 2.4 2005/04/25 19:24:10 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
#ifndef lvm_h
#define lvm_h
#include "ldo.h"
#include "lobject.h"
#include "ltm.h"
#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
(((o) = luaV_tonumber(o,n)) != NULL))
#define equalobj(L,o1,o2) \
(ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
#endif
+82
View File
@@ -0,0 +1,82 @@
/*
** $Id: lzio.c,v 1.30 2005/05/17 19:49:15 roberto Exp roberto $
** a generic input stream interface
** See Copyright Notice in lua.h
*/
#include <string.h>
#define lzio_c
#define LUA_CORE
#include "lua.h"
#include "llimits.h"
#include "lmem.h"
#include "lstate.h"
#include "lzio.h"
int luaZ_fill (ZIO *z) {
size_t size;
lua_State *L = z->L;
const char *buff;
lua_unlock(L);
buff = z->reader(L, z->data, &size);
lua_lock(L);
if (buff == NULL || size == 0) return EOZ;
z->n = size - 1;
z->p = buff;
return char2int(*(z->p++));
}
int luaZ_lookahead (ZIO *z) {
if (z->n == 0) {
if (luaZ_fill(z) == EOZ)
return EOZ;
else {
z->n++; /* luaZ_fill removed first byte; put back it */
z->p--;
}
}
return char2int(*z->p);
}
void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
z->L = L;
z->reader = reader;
z->data = data;
z->n = 0;
z->p = NULL;
}
/* --------------------------------------------------------------- read --- */
size_t luaZ_read (ZIO *z, void *b, size_t n) {
while (n) {
size_t m;
if (luaZ_lookahead(z) == EOZ)
return n; /* return number of missing bytes */
m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
memcpy(b, z->p, m);
z->n -= m;
z->p += m;
b = (char *)b + m;
n -= m;
}
return 0;
}
/* ------------------------------------------------------------------------ */
char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
if (n > buff->buffsize) {
if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
luaZ_resizebuffer(L, buff, n);
}
return buff->buffer;
}
+67
View File
@@ -0,0 +1,67 @@
/*
** $Id: lzio.h,v 1.20 2005/04/25 19:24:10 roberto Exp roberto $
** Buffered streams
** See Copyright Notice in lua.h
*/
#ifndef lzio_h
#define lzio_h
#include "lua.h"
#include "lmem.h"
#define EOZ (-1) /* end of stream */
typedef struct Zio ZIO;
#define char2int(c) cast(int, cast(unsigned char, (c)))
#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
typedef struct Mbuffer {
char *buffer;
size_t n;
size_t buffsize;
} Mbuffer;
#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
#define luaZ_buffer(buff) ((buff)->buffer)
#define luaZ_sizebuffer(buff) ((buff)->buffsize)
#define luaZ_bufflen(buff) ((buff)->n)
#define luaZ_resetbuffer(buff) ((buff)->n = 0)
#define luaZ_resizebuffer(L, buff, size) \
(luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
(buff)->buffsize = size)
#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
void *data);
LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
LUAI_FUNC int luaZ_lookahead (ZIO *z);
/* --------- Private Part ------------------ */
struct Zio {
size_t n; /* bytes still unread */
const char *p; /* current position in buffer */
lua_Reader reader;
void* data; /* additional data */
lua_State *L; /* Lua state (for reader) */
};
LUAI_FUNC int luaZ_fill (ZIO *z);
#endif
+146 -45
View File
@@ -1,53 +1,154 @@
# $Id: makefile,v 1.5 1994/01/10 19:49:56 roberto Exp celes $
# Compilation parameters
CC = gcc
CFLAGS = -I/usr/5include -Wall -O2
# makefile for building Lua
# see INSTALL for installation instructions
# see ../Makefile and luaconf.h for further customization
AR = ar
ARFLAGS = rvl
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
# Aplication modules
LUAMOD = \
y.tab \
lex \
opcode \
hash \
table \
inout \
tree
CWARNS= -pedantic -Waggregate-return -Wcast-align \
-Wmissing-prototypes -Wpointer-arith -Wshadow \
-Wsign-compare -Wstrict-prototypes -Wundef -Wwrite-strings
# -Wcast-qual
LIBMOD = \
iolib \
strlib \
mathlib
# -DEXTERNMEMCHECK -DHARDSTACKTESTS
# -g -DLUA_USER_H='"ltests.h"'
# -fomit-frame-pointer #-pg -malign-double
TESTS= -g -DLUA_USER_H='"ltests.h"'
LUAOBJS = $(LUAMOD:%=%.o)
LIBOBJS = $(LIBMOD:%=%.o)
lua : lua.o lua.a lualib.a
$(CC) $(CFLAGS) -o $@ lua.c lua.a lualib.a -lm
lua.a : y.tab.c $(LUAOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib lua.a
lualib.a : $(LIBOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib $@
.KEEP_STATE:
liblua.so.1.0 : lua.o
ld -o liblua.so.1.0 $(LUAOBJS)
%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
LOCAL = $(TESTS) $(CWARNS)
y.tab.c : lua.stx exscript
yacc -d lua.stx ; ex y.tab.c <exscript
CC= gcc
CFLAGS= -O2 -Wall $(MYCFLAGS)
AR= ar rcu
RANLIB= ranlib
RM= rm -f
% : RCS/%,v
co $@
MYCFLAGS= $(LOCAL)
MYLDFLAGS=
MYLIBS=
# enable Linux goodies
MYCFLAGS= $(LOCAL) -DLUA_USE_DLOPEN -DLUA_USE_READLINE
MYLDFLAGS= -Wl,-E
MYLIBS= -ldl -lreadline -lhistory -lncurses
# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
LIBS = -lm
CORE_T= liblua.a
CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
lundump.o lvm.o lzio.o ltests.o
AUX_O= lauxlib.o
LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \
loadlib.o linit.o
LUA_T= lua
LUA_O= lua.o
LUAC_T= luac
LUAC_O= luac.o print.o
ALL_T= $(CORE_T) $(LUA_T) $(LUAC_T)
ALL_O= $(CORE_O) $(LUA_O) $(LUAC_O) $(AUX_O) $(LIB_O)
ALL_A= $(CORE_T)
all: $(ALL_T)
o: $(ALL_O)
a: $(ALL_A)
$(CORE_T): $(CORE_O) $(AUX_O) $(LIB_O)
$(AR) $@ $?
$(RANLIB) $@
$(LUA_T): $(LUA_O) $(CORE_T)
$(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(CORE_T) $(LIBS) $(MYLIBS) $(DL)
$(LUAC_T): $(LUAC_O) $(CORE_T)
$(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(CORE_T) $(LIBS) $(MYLIBS)
clean:
$(RM) $(ALL_T) $(ALL_O)
depend:
@$(CC) $(CFLAGS) -MM *.c
echo:
@echo "CC = $(CC)"
@echo "CFLAGS = $(CFLAGS)"
@echo "AR = $(AR)"
@echo "RANLIB = $(RANLIB)"
@echo "RM = $(RM)"
@echo "MYCFLAGS = $(MYCFLAGS)"
@echo "MYLDFLAGS = $(MYLDFLAGS)"
@echo "MYLIBS = $(MYLIBS)"
@echo "DL = $(DL)"
# DO NOT DELETE
lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \
lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \
lundump.h lvm.h
lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h
lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h
lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
lzio.h lmem.h lopcodes.h lparser.h ltable.h ldebug.h lstate.h ltm.h \
ldo.h lgc.h
ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h
ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \
llex.h lzio.h lmem.h lopcodes.h lparser.h ltable.h ldebug.h lstate.h \
ltm.h ldo.h lfunc.h lstring.h lgc.h lvm.h
ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h ltable.h \
lstring.h lundump.h lvm.h
ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lopcodes.h lstate.h \
ltm.h lzio.h lmem.h lundump.h
lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \
lstate.h ltm.h lzio.h
lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h
liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h
llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \
lzio.h lmem.h llex.h lparser.h ltable.h lstring.h lgc.h
lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
ltm.h lzio.h lmem.h ldo.h
loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \
ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h
lopcodes.o: lopcodes.c lua.h luaconf.h lobject.h llimits.h lopcodes.h
loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h
lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
lzio.h lmem.h lopcodes.h lparser.h ltable.h ldebug.h lstate.h ltm.h \
ldo.h lfunc.h lstring.h lgc.h
lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h
lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \
ltm.h lzio.h lstring.h lgc.h
lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h
ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h
ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h
ltests.o: ltests.c lua.h luaconf.h lapi.h lobject.h llimits.h lauxlib.h \
lcode.h llex.h lzio.h lmem.h lopcodes.h lparser.h ltable.h ldebug.h \
lstate.h ltm.h ldo.h lfunc.h lstring.h lgc.h lualib.h
ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \
lmem.h lstring.h lgc.h ltable.h
lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h
lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lopcodes.h lstring.h lgc.h \
lundump.h
lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h
lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
lzio.h
# (end of Makefile)
-235
View File
@@ -1,235 +0,0 @@
/*
** mathlib.c
** Mathematics library to LUA
*/
char *rcs_mathlib="$Id: $";
#include <stdio.h> /* NULL */
#include <math.h>
#include "lua.h"
#define TODEGREE(a) ((a)*180.0/3.14159)
#define TORAD(a) ((a)*3.14159/180.0)
static void math_abs (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `abs'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `abs'"); return; }
d = lua_getnumber(o);
if (d < 0) d = -d;
lua_pushnumber (d);
}
static void math_sin (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `sin'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `sin'"); return; }
d = lua_getnumber(o);
lua_pushnumber (sin(TORAD(d)));
}
static void math_cos (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `cos'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `cos'"); return; }
d = lua_getnumber(o);
lua_pushnumber (cos(TORAD(d)));
}
static void math_tan (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `tan'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `tan'"); return; }
d = lua_getnumber(o);
lua_pushnumber (tan(TORAD(d)));
}
static void math_asin (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `asin'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `asin'"); return; }
d = lua_getnumber(o);
lua_pushnumber (TODEGREE(asin(d)));
}
static void math_acos (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `acos'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `acos'"); return; }
d = lua_getnumber(o);
lua_pushnumber (TODEGREE(acos(d)));
}
static void math_atan (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `atan'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `atan'"); return; }
d = lua_getnumber(o);
lua_pushnumber (TODEGREE(atan(d)));
}
static void math_ceil (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `ceil'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `ceil'"); return; }
d = lua_getnumber(o);
lua_pushnumber (ceil(d));
}
static void math_floor (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `floor'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `floor'"); return; }
d = lua_getnumber(o);
lua_pushnumber (floor(d));
}
static void math_mod (void)
{
int d1, d2;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (!lua_isnumber(o1) || !lua_isnumber(o2))
{ lua_error ("incorrect arguments to function `mod'"); return; }
d1 = (int) lua_getnumber(o1);
d2 = (int) lua_getnumber(o2);
lua_pushnumber (d1%d2);
}
static void math_sqrt (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `sqrt'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `sqrt'"); return; }
d = lua_getnumber(o);
lua_pushnumber (sqrt(d));
}
static void math_pow (void)
{
double d1, d2;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (!lua_isnumber(o1) || !lua_isnumber(o2))
{ lua_error ("incorrect arguments to function `pow'"); return; }
d1 = lua_getnumber(o1);
d2 = lua_getnumber(o2);
lua_pushnumber (pow(d1,d2));
}
static void math_min (void)
{
int i=1;
double d, dmin;
lua_Object o;
if ((o = lua_getparam(i++)) == NULL)
{ lua_error ("too few arguments to function `min'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `min'"); return; }
dmin = lua_getnumber (o);
while ((o = lua_getparam(i++)) != NULL)
{
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `min'"); return; }
d = lua_getnumber (o);
if (d < dmin) dmin = d;
}
lua_pushnumber (dmin);
}
static void math_max (void)
{
int i=1;
double d, dmax;
lua_Object o;
if ((o = lua_getparam(i++)) == NULL)
{ lua_error ("too few arguments to function `max'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `max'"); return; }
dmax = lua_getnumber (o);
while ((o = lua_getparam(i++)) != NULL)
{
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `max'"); return; }
d = lua_getnumber (o);
if (d > dmax) dmax = d;
}
lua_pushnumber (dmax);
}
/*
** Open math library
*/
void mathlib_open (void)
{
lua_register ("abs", math_abs);
lua_register ("sin", math_sin);
lua_register ("cos", math_cos);
lua_register ("tan", math_tan);
lua_register ("asin", math_asin);
lua_register ("acos", math_acos);
lua_register ("atan", math_atan);
lua_register ("ceil", math_ceil);
lua_register ("floor", math_floor);
lua_register ("mod", math_mod);
lua_register ("sqrt", math_sqrt);
lua_register ("pow", math_pow);
lua_register ("min", math_min);
lua_register ("max", math_max);
}
-13
View File
@@ -1,13 +0,0 @@
/*
** Math library to LUA
** TeCGraf - PUC-Rio
** $Id: $
*/
#ifndef strlib_h
void mathlib_open (void);
#endif
-39
View File
@@ -1,39 +0,0 @@
/*
** mm.h
** Waldemar Celes Filho
** Sep 16, 1992
*/
#ifndef mm_h
#define mm_h
#include <stdlib.h>
#ifdef _MM_
/* switch off the debugger functions */
#define malloc(s) MmMalloc(s,__FILE__,__LINE__)
#define calloc(n,s) MmCalloc(n,s,__FILE__,__LINE__)
#define realloc(a,s) MmRealloc(a,s,__FILE__,__LINE__,#a)
#define free(a) MmFree(a,__FILE__,__LINE__,#a)
#define strdup(s) MmStrdup(s,__FILE__,__LINE__)
#endif
typedef void (*Ferror) (char *);
/* Exported functions */
void MmInit (Ferror f, Ferror w);
void *MmMalloc (unsigned size, char *file, int line);
void *MmCalloc (unsigned n, unsigned size, char *file, int line);
void MmFree (void *a, char *file, int line, char *var);
void *MmRealloc (void *old, unsigned size, char *file, int line, char *var);
char *MmStrdup (char *s, char *file, int line);
unsigned MmGetBytes (void);
void MmListAllocated (void);
void MmCheck (void);
void MmStatistics (void);
#endif
-1036
View File
File diff suppressed because it is too large Load Diff
-164
View File
@@ -1,164 +0,0 @@
/*
** TeCGraf - PUC-Rio
** $Id: opcode.h,v 2.1 1994/04/20 22:07:57 celes Exp celes $
*/
#ifndef opcode_h
#define opcode_h
#ifndef STACKGAP
#define STACKGAP 128
#endif
#ifndef real
#define real float
#endif
#define FIELDS_PER_FLUSH 40
typedef unsigned char Byte;
typedef unsigned short Word;
typedef signed long Long;
typedef union
{
struct {char c1; char c2;} m;
Word w;
} CodeWord;
typedef union
{
struct {char c1; char c2; char c3; char c4;} m;
float f;
} CodeFloat;
typedef enum
{
PUSHNIL,
PUSH0, PUSH1, PUSH2,
PUSHBYTE,
PUSHWORD,
PUSHFLOAT,
PUSHSTRING,
PUSHLOCAL0, PUSHLOCAL1, PUSHLOCAL2, PUSHLOCAL3, PUSHLOCAL4,
PUSHLOCAL5, PUSHLOCAL6, PUSHLOCAL7, PUSHLOCAL8, PUSHLOCAL9,
PUSHLOCAL,
PUSHGLOBAL,
PUSHINDEXED,
PUSHMARK,
PUSHOBJECT,
STORELOCAL0, STORELOCAL1, STORELOCAL2, STORELOCAL3, STORELOCAL4,
STORELOCAL5, STORELOCAL6, STORELOCAL7, STORELOCAL8, STORELOCAL9,
STORELOCAL,
STOREGLOBAL,
STOREINDEXED0,
STOREINDEXED,
STORELIST0,
STORELIST,
STORERECORD,
ADJUST,
CREATEARRAY,
EQOP,
LTOP,
LEOP,
ADDOP,
SUBOP,
MULTOP,
DIVOP,
CONCOP,
MINUSOP,
NOTOP,
ONTJMP,
ONFJMP,
JMP,
UPJMP,
IFFJMP,
IFFUPJMP,
POP,
CALLFUNC,
RETCODE,
HALT,
SETFUNCTION,
SETLINE,
RESET
} OpCode;
typedef enum
{
T_MARK,
T_NIL,
T_NUMBER,
T_STRING,
T_ARRAY,
T_FUNCTION,
T_CFUNCTION,
T_USERDATA
} Type;
typedef void (*Cfunction) (void);
typedef int (*Input) (void);
typedef union
{
Cfunction f;
real n;
char *s;
Byte *b;
struct Hash *a;
void *u;
} Value;
typedef struct Object
{
Type tag;
Value value;
} Object;
typedef struct
{
Object object;
} Symbol;
/* Macros to access structure members */
#define tag(o) ((o)->tag)
#define nvalue(o) ((o)->value.n)
#define svalue(o) ((o)->value.s)
#define bvalue(o) ((o)->value.b)
#define avalue(o) ((o)->value.a)
#define fvalue(o) ((o)->value.f)
#define uvalue(o) ((o)->value.u)
/* Macros to access symbol table */
#define s_object(i) (lua_table[i].object)
#define s_tag(i) (tag(&s_object(i)))
#define s_nvalue(i) (nvalue(&s_object(i)))
#define s_svalue(i) (svalue(&s_object(i)))
#define s_bvalue(i) (bvalue(&s_object(i)))
#define s_avalue(i) (avalue(&s_object(i)))
#define s_fvalue(i) (fvalue(&s_object(i)))
#define s_uvalue(i) (uvalue(&s_object(i)))
#define get_word(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;}
#define get_float(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\
code.m.c3 = *pc++; code.m.c4 = *pc++;}
/* Exported functions */
int lua_execute (Byte *pc);
void lua_markstack (void);
char *lua_strdup (char *l);
void lua_setinput (Input fn); /* from "lex.c" module */
char *lua_lasttext (void); /* from "lex.c" module */
int lua_parse (void); /* from "lua.stx" module */
void lua_type (void);
void lua_obj2number (void);
void lua_print (void);
void lua_internaldofile (void);
void lua_internaldostring (void);
void lua_travstack (void (*fn)(Object *));
#endif
-135
View File
@@ -1,135 +0,0 @@
/*
** strlib.c
** String library to LUA
*/
char *rcs_strlib="$Id: strlib.c,v 1.1 1993/12/17 18:41:19 celes Exp celes $";
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "mm.h"
#include "lua.h"
/*
** Return the position of the first caracter of a substring into a string
** LUA interface:
** n = strfind (string, substring)
*/
static void str_find (void)
{
char *s1, *s2, *f;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (!lua_isstring(o1) || !lua_isstring(o2))
{ lua_error ("incorrect arguments to function `strfind'"); return; }
s1 = lua_getstring(o1);
s2 = lua_getstring(o2);
f = strstr(s1,s2);
if (f != NULL)
lua_pushnumber (f-s1+1);
else
lua_pushnil();
}
/*
** Return the string length
** LUA interface:
** n = strlen (string)
*/
static void str_len (void)
{
lua_Object o = lua_getparam (1);
if (!lua_isstring(o))
{ lua_error ("incorrect arguments to function `strlen'"); return; }
lua_pushnumber(strlen(lua_getstring(o)));
}
/*
** Return the substring of a string, from start to end
** LUA interface:
** substring = strsub (string, start, end)
*/
static void str_sub (void)
{
int start, end;
char *s;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
lua_Object o3 = lua_getparam (3);
if (!lua_isstring(o1) || !lua_isnumber(o2))
{ lua_error ("incorrect arguments to function `strsub'"); return; }
if (o3 != NULL && !lua_isnumber(o3))
{ lua_error ("incorrect third argument to function `strsub'"); return; }
s = lua_copystring(o1);
start = lua_getnumber (o2);
end = o3 == NULL ? strlen(s) : lua_getnumber (o3);
if (end < start || start < 1 || end > strlen(s))
lua_pushstring("");
else
{
s[end] = 0;
lua_pushstring (&s[start-1]);
}
free (s);
}
/*
** Convert a string to lower case.
** LUA interface:
** lowercase = strlower (string)
*/
static void str_lower (void)
{
char *s, *c;
lua_Object o = lua_getparam (1);
if (!lua_isstring(o))
{ lua_error ("incorrect arguments to function `strlower'"); return; }
c = s = strdup(lua_getstring(o));
while (*c != 0)
{
*c = tolower(*c);
c++;
}
lua_pushstring(s);
free(s);
}
/*
** Convert a string to upper case.
** LUA interface:
** uppercase = strupper (string)
*/
static void str_upper (void)
{
char *s, *c;
lua_Object o = lua_getparam (1);
if (!lua_isstring(o))
{ lua_error ("incorrect arguments to function `strlower'"); return; }
c = s = strdup(lua_getstring(o));
while (*c != 0)
{
*c = toupper(*c);
c++;
}
lua_pushstring(s);
free(s);
}
/*
** Open string library
*/
void strlib_open (void)
{
lua_register ("strfind", str_find);
lua_register ("strlen", str_len);
lua_register ("strsub", str_sub);
lua_register ("strlower", str_lower);
lua_register ("strupper", str_upper);
}
-13
View File
@@ -1,13 +0,0 @@
/*
** String library to LUA
** TeCGraf - PUC-Rio
** $Id: $
*/
#ifndef strlib_h
void strlib_open (void);
#endif
-309
View File
@@ -1,309 +0,0 @@
/*
** table.c
** Module to control static tables
*/
char *rcs_table="$Id: table.c,v 2.1 1994/04/20 22:07:57 celes Exp celes $";
#include <stdlib.h>
#include <string.h>
#include "mm.h"
#include "opcode.h"
#include "tree.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "lua.h"
#define streq(s1,s2) (s1[0]==s2[0]&&strcmp(s1+1,s2+1)==0)
#define BUFFER_BLOCK 256
Symbol *lua_table;
static Word lua_ntable = 0;
static Word lua_maxsymbol = 0;
char **lua_constant;
static Word lua_nconstant = 0;
static Word lua_maxconstant = 0;
#define MAXFILE 20
char *lua_file[MAXFILE];
int lua_nfile;
/* Variables to controll garbage collection */
#define GARBAGE_BLOCK 256
Word lua_block=GARBAGE_BLOCK; /* when garbage collector will be called */
Word lua_nentity; /* counter of new entities (strings and arrays) */
/*
** Initialise symbol table with internal functions
*/
static void lua_initsymbol (void)
{
int n;
lua_maxsymbol = BUFFER_BLOCK;
lua_table = (Symbol *) calloc(lua_maxsymbol, sizeof(Symbol));
if (lua_table == NULL)
{
lua_error ("symbol table: not enough memory");
return;
}
n = lua_findsymbol("type");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_type;
n = lua_findsymbol("tonumber");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_obj2number;
n = lua_findsymbol("next");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_next;
n = lua_findsymbol("nextvar");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_nextvar;
n = lua_findsymbol("print");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_print;
n = lua_findsymbol("dofile");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_internaldofile;
n = lua_findsymbol("dostring");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_internaldostring;
}
/*
** Initialise constant table with pre-defined constants
*/
void lua_initconstant (void)
{
lua_maxconstant = BUFFER_BLOCK;
lua_constant = (char **) calloc(lua_maxconstant, sizeof(char *));
if (lua_constant == NULL)
{
lua_error ("constant table: not enough memory");
return;
}
lua_findconstant("mark");
lua_findconstant("nil");
lua_findconstant("number");
lua_findconstant("string");
lua_findconstant("table");
lua_findconstant("function");
lua_findconstant("cfunction");
lua_findconstant("userdata");
}
/*
** Given a name, search it at symbol table and return its index. If not
** found, allocate it.
** On error, return -1.
*/
int lua_findsymbol (char *s)
{
char *n;
if (lua_table == NULL)
lua_initsymbol();
n = lua_varcreate(s);
if (n == NULL)
{
lua_error ("create symbol: not enough memory");
return -1;
}
if (indexstring(n) == UNMARKED_STRING)
{
if (lua_ntable == lua_maxsymbol)
{
lua_maxsymbol *= 2;
if (lua_maxsymbol > MAX_WORD)
{
lua_error("symbol table overflow");
return -1;
}
lua_table = (Symbol *)realloc(lua_table, lua_maxsymbol*sizeof(Symbol));
if (lua_table == NULL)
{
lua_error ("symbol table: not enough memory");
return -1;
}
}
indexstring(n) = lua_ntable;
s_tag(lua_ntable) = T_NIL;
lua_ntable++;
}
return indexstring(n);
}
/*
** Given a name, search it at constant table and return its index. If not
** found, allocate it.
** On error, return -1.
*/
int lua_findconstant (char *s)
{
char *n;
if (lua_constant == NULL)
lua_initconstant();
n = lua_constcreate(s);
if (n == NULL)
{
lua_error ("create constant: not enough memory");
return -1;
}
if (indexstring(n) == UNMARKED_STRING)
{
if (lua_nconstant == lua_maxconstant)
{
lua_maxconstant *= 2;
if (lua_maxconstant > MAX_WORD)
{
lua_error("constant table overflow");
return -1;
}
lua_constant = (char**)realloc(lua_constant,lua_maxconstant*sizeof(char*));
if (lua_constant == NULL)
{
lua_error ("constant table: not enough memory");
return -1;
}
}
indexstring(n) = lua_nconstant;
lua_constant[lua_nconstant] = n;
lua_nconstant++;
}
return indexstring(n);
}
/*
** Traverse symbol table objects
*/
void lua_travsymbol (void (*fn)(Object *))
{
int i;
for (i=0; i<lua_ntable; i++)
fn(&s_object(i));
}
/*
** Mark an object if it is a string or a unmarked array.
*/
void lua_markobject (Object *o)
{
if (tag(o) == T_STRING && indexstring(svalue(o)) == UNMARKED_STRING)
indexstring(svalue(o)) = MARKED_STRING;
else if (tag(o) == T_ARRAY)
lua_hashmark (avalue(o));
}
/*
** Garbage collection.
** Delete all unused strings and arrays.
*/
void lua_pack (void)
{
/* mark stack strings */
lua_travstack(lua_markobject);
/* mark symbol table strings */
lua_travsymbol(lua_markobject);
lua_strcollector();
lua_hashcollector();
lua_nentity = 0; /* reset counter */
}
/*
** If the string isn't allocated, allocate a new string at string tree.
*/
char *lua_createstring (char *s)
{
if (s == NULL) return NULL;
if (lua_nentity == lua_block)
lua_pack ();
lua_nentity++;
return lua_strcreate(s);
}
/*
** Add a file name at file table, checking overflow. This function also set
** the external variable "lua_filename" with the function filename set.
** Return 0 on success or 1 on error.
*/
int lua_addfile (char *fn)
{
if (lua_nfile >= MAXFILE-1)
{
lua_error ("too many files");
return 1;
}
if ((lua_file[lua_nfile++] = strdup (fn)) == NULL)
{
lua_error ("not enough memory");
return 1;
}
return 0;
}
/*
** Delete a file from file stack
*/
int lua_delfile (void)
{
lua_nfile--;
return 1;
}
/*
** Return the last file name set.
*/
char *lua_filename (void)
{
return lua_file[lua_nfile-1];
}
/*
** Internal function: return next global variable
*/
void lua_nextvar (void)
{
char *varname, *next;
Object *o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `nextvar'"); return; }
if (lua_getparam (2) != NULL)
{ lua_error ("too many arguments to function `nextvar'"); return; }
if (tag(o) == T_NIL)
{
varname = 0;
}
else if (tag(o) != T_STRING)
{
lua_error ("incorrect argument to function `nextvar'");
return;
}
else
{
varname = svalue(o);
}
next = lua_varnext(varname);
if (next == NULL)
{
lua_pushnil();
lua_pushnil();
}
else
{
Object name;
tag(&name) = T_STRING;
svalue(&name) = next;
if (lua_pushobject (&name)) return;
if (lua_pushobject (&s_object(indexstring(next)))) return;
}
}
-32
View File
@@ -1,32 +0,0 @@
/*
** Module to control static tables
** TeCGraf - PUC-Rio
** $Id: table.h,v 2.1 1994/04/20 22:07:57 celes Exp celes $
*/
#ifndef table_h
#define table_h
extern Symbol *lua_table;
extern char **lua_constant;
extern char *lua_file[];
extern int lua_nfile;
extern Word lua_block;
extern Word lua_nentity;
void lua_initconstant (void);
int lua_findsymbol (char *s);
int lua_findconstant (char *s);
void lua_travsymbol (void (*fn)(Object *));
void lua_markobject (Object *o);
void lua_pack (void);
char *lua_createstring (char *s);
int lua_addfile (char *fn);
int lua_delfile (void);
char *lua_filename (void);
void lua_nextvar (void);
#endif
-210
View File
@@ -1,210 +0,0 @@
/*
** tree.c
** TecCGraf - PUC-Rio
*/
char *rcs_tree="$Id: $";
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "tree.h"
#define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b)))
typedef struct TreeNode
{
struct TreeNode *right;
struct TreeNode *left;
Word index;
char str[1]; /* \0 byte already reserved */
} TreeNode;
static TreeNode *string_root = NULL;
static TreeNode *constant_root = NULL;
static TreeNode *variable_root = NULL;
/*
** Insert a new string/constant/variable at the tree.
*/
static char *tree_create (TreeNode **node, char *str)
{
if (*node == NULL)
{
*node = (TreeNode *) malloc (sizeof(TreeNode)+strlen(str));
if (*node == NULL)
lua_error ("memoria insuficiente\n");
(*node)->left = (*node)->right = NULL;
strcpy((*node)->str, str);
(*node)->index = UNMARKED_STRING;
return (*node)->str;
}
else
{
int c = lua_strcmp(str, (*node)->str);
if (c < 0)
return tree_create(&(*node)->left, str);
else if (c > 0)
return tree_create(&(*node)->right, str);
else
return (*node)->str;
}
}
char *lua_strcreate (char *str)
{
return tree_create(&string_root, str);
}
char *lua_constcreate (char *str)
{
return tree_create(&constant_root, str);
}
char *lua_varcreate (char *str)
{
return tree_create(&variable_root, str);
}
/*
** Free a node of the tree
*/
static TreeNode *lua_strfree (TreeNode *parent)
{
if (parent->left == NULL && parent->right == NULL) /* no child */
{
free (parent);
return NULL;
}
else if (parent->left == NULL) /* only right child */
{
TreeNode *p = parent->right;
free (parent);
return p;
}
else if (parent->right == NULL) /* only left child */
{
TreeNode *p = parent->left;
free (parent);
return p;
}
else /* two children */
{
TreeNode *p = parent, *r = parent->right;
while (r->left != NULL)
{
p = r;
r = r->left;
}
if (p == parent)
{
r->left = parent->left;
parent->left = NULL;
parent->right = r->right;
r->right = lua_strfree(parent);
}
else
{
TreeNode *t = r->right;
r->left = parent->left;
r->right = parent->right;
parent->left = NULL;
parent->right = t;
p->left = lua_strfree(parent);
}
return r;
}
}
/*
** Traverse tree for garbage collection
*/
static TreeNode *lua_travcollector (TreeNode *r)
{
if (r == NULL) return NULL;
r->right = lua_travcollector(r->right);
r->left = lua_travcollector(r->left);
if (r->index == UNMARKED_STRING)
return lua_strfree(r);
else
{
r->index = UNMARKED_STRING;
return r;
}
}
/*
** Garbage collection function.
** This function traverse the tree freening unindexed strings
*/
void lua_strcollector (void)
{
string_root = lua_travcollector(string_root);
}
/*
** Return next variable.
*/
static TreeNode *tree_next (TreeNode *node, char *str)
{
#if 0
if (node == NULL) return NULL;
if (str == NULL || lua_strcmp(str, node->str) < 0)
{
TreeNode *result = tree_next(node->left, str);
return result == NULL ? node : result;
}
else
{
return tree_next(node->right, str);
}
#else
if (node == NULL) return NULL;
else if (str == NULL) return node;
else
{
int c = lua_strcmp(str, node->str);
if (c == 0)
return node->left != NULL ? node->left : node->right;
else if (c < 0)
{
TreeNode *result = tree_next(node->left, str);
return result != NULL ? result : node->right;
}
else
return tree_next(node->right, str);
}
#endif
}
char *lua_varnext (char *n)
{
TreeNode *result = tree_next(variable_root, n);
return result != NULL ? result->str : NULL;
}
/*
** Given an id, find the string with exaustive search
*/
static char *tree_name (TreeNode *node, Word index)
{
if (node == NULL) return NULL;
if (node->index == index) return node->str;
else
{
char *result = tree_name(node->left, index);
return result != NULL ? result : tree_name(node->right, index);
}
}
char *lua_varname (Word index)
{
return tree_name(variable_root, index);
}
-27
View File
@@ -1,27 +0,0 @@
/*
** tree.h
** TecCGraf - PUC-Rio
** $Id: $
*/
#ifndef tree_h
#define tree_h
#include "opcode.h"
#define UNMARKED_STRING 0xFFFF
#define MARKED_STRING 0xFFFE
#define MAX_WORD 0xFFFD
#define indexstring(s) (*(((Word *)s)-1))
char *lua_strcreate (char *str);
char *lua_constcreate (char *str);
char *lua_varcreate (char *str);
void lua_strcollector (void);
char *lua_varnext (char *n);
char *lua_varname (Word index);
#endif