Compare commits

...

183 Commits
v3.1 ... v3.2

Author SHA1 Message Date
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
43 changed files with 3749 additions and 2823 deletions

65
bugs
View File

@@ -4,6 +4,7 @@ Tue Dec 2 10:45:48 EDT 1997
>> started only in the 2nd line of a function.
--- Version 3.1 alpha
** lua.c
@@ -13,7 +14,7 @@ Thu Jan 15 14:34:58 EDT 1998
** 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
@@ -31,7 +32,7 @@ Tue Jan 27 17:12:36 EDT 1998
** lstring.c / ltable.c
Wed Jan 28 14:48:12 EDT 1998
>> tables can become full of "emptys" slots, and keep growing without limits.
>> tables can become full of "empty" slots, and keep growing without limits.
** lstrlib.c
Mon Mar 9 15:26:09 EST 1998
@@ -41,3 +42,63 @@ Mon Mar 9 15:26:09 EST 1998
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)

268
lapi.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 1.24 1998/03/09 21:49:52 roberto Exp roberto $
** $Id: lapi.c,v 1.46 1999/06/17 17:04:03 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -25,17 +25,16 @@
char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
"$Autores: " LUA_AUTHORS " $";
"$Authors: " LUA_AUTHORS " $";
TObject *luaA_Address (lua_Object o)
{
return Address(o);
TObject *luaA_Address (lua_Object o) {
return (o != LUA_NOOBJECT) ? Address(o) : NULL;
}
static int normalized_type (TObject *o)
static lua_Type normalized_type (TObject *o)
{
int t = ttype(o);
switch (t) {
@@ -71,12 +70,8 @@ void luaA_packresults (void)
}
int luaA_passresults (void)
{
luaD_checkstack(L->Cstack.num);
memcpy(L->stack.top, L->Cstack.lua2C+L->stack.stack,
L->Cstack.num*sizeof(TObject));
L->stack.top += L->Cstack.num;
int luaA_passresults (void) {
L->Cstack.base = L->Cstack.lua2C; /* position of first result */
return L->Cstack.num;
}
@@ -88,24 +83,29 @@ static void checkCparams (int nParams)
}
static lua_Object put_luaObject (TObject *o)
{
static lua_Object put_luaObject (TObject *o) {
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
L->stack.stack[L->Cstack.base++] = *o;
return L->Cstack.base; /* this is +1 real position (see Ref) */
}
static lua_Object put_luaObjectonTop (void)
{
static lua_Object put_luaObjectonTop (void) {
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
L->stack.stack[L->Cstack.base++] = *(--L->stack.top);
return L->Cstack.base; /* this is +1 real position (see Ref) */
}
lua_Object lua_pop (void)
{
static void top2LC (int n) {
/* Put the 'n' elements on the top as the Lua2C contents */
L->Cstack.base = (L->stack.top-L->stack.stack); /* new base */
L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */
L->Cstack.num = n; /* number of results */
}
lua_Object lua_pop (void) {
checkCparams(1);
return put_luaObjectonTop();
}
@@ -131,7 +131,7 @@ int lua_callfunction (lua_Object function)
else {
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
set_normalized(L->stack.stack+L->Cstack.base, Address(function));
return luaD_protectedrun(MULT_RET);
return luaD_protectedrun();
}
}
@@ -150,12 +150,12 @@ lua_Object lua_settagmethod (int tag, char *event)
}
lua_Object lua_seterrormethod (void)
{
TObject temp = L->errorim;
lua_Object lua_seterrormethod (void) {
lua_Object temp;
checkCparams(1);
L->errorim = *(--L->stack.top);
return put_luaObject(&temp);
temp = lua_getglobal("_ERRORMESSAGE");
lua_setglobal("_ERRORMESSAGE");
return temp;
}
@@ -167,34 +167,26 @@ lua_Object lua_gettable (void)
}
lua_Object lua_rawgettable (void)
{
lua_Object lua_rawgettable (void) {
checkCparams(2);
if (ttype(L->stack.top-2) != LUA_T_ARRAY)
lua_error("indexed expression not a table in rawgettable");
else {
TObject *h = luaH_get(avalue(L->stack.top-2), L->stack.top-1);
--L->stack.top;
if (h != NULL)
*(L->stack.top-1) = *h;
else
ttype(L->stack.top-1) = LUA_T_NIL;
}
*(L->stack.top-2) = *luaH_get(avalue(L->stack.top-2), L->stack.top-1);
--L->stack.top;
return put_luaObjectonTop();
}
void lua_settable (void)
{
void lua_settable (void) {
checkCparams(3);
luaV_settable(L->stack.top-3, 1);
luaV_settable(L->stack.top-3);
L->stack.top -= 2; /* pop table and index */
}
void lua_rawsettable (void)
{
void lua_rawsettable (void) {
checkCparams(3);
luaV_settable(L->stack.top-3, 0);
luaV_rawsettable(L->stack.top-3);
}
@@ -373,14 +365,11 @@ void luaA_pushobject (TObject *o)
incr_top;
}
void lua_pushobject (lua_Object o)
{
void lua_pushobject (lua_Object o) {
if (o == LUA_NOOBJECT)
lua_error("API error - attempt to push a NOOBJECT");
else {
set_normalized(L->stack.top, Address(o));
incr_top;
}
set_normalized(L->stack.top, Address(o));
incr_top;
}
@@ -426,22 +415,108 @@ void lua_settag (int tag)
break;
default:
luaL_verror("cannot change the tag of a %.20s",
luaO_typenames[-ttype((L->stack.top-1))]);
luaO_typename(L->stack.top-1));
}
L->stack.top--;
}
TaggedString *luaA_nextvar (TaggedString *g) {
if (g == NULL)
g = (TaggedString *)L->rootglobal.next; /* first variable */
else {
/* check whether name is in global var list */
luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
g = (TaggedString *)g->head.next; /* get next */
}
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
g = (TaggedString *)g->head.next;
if (g) {
ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g;
incr_top;
luaA_pushobject(&g->u.s.globalval);
}
return g;
}
char *lua_nextvar (char *varname) {
TaggedString *g = (varname == NULL) ? NULL : luaS_new(varname);
g = luaA_nextvar(g);
if (g) {
top2LC(2);
return g->str;
}
else {
top2LC(0);
return NULL;
}
}
int luaA_next (Hash *t, int i) {
int tsize = nhash(t);
for (; i<tsize; i++) {
Node *n = node(t, i);
if (ttype(val(n)) != LUA_T_NIL) {
luaA_pushobject(ref(n));
luaA_pushobject(val(n));
return i+1; /* index to be used next time */
}
}
return 0; /* no more elements */
}
int lua_next (lua_Object o, int i) {
TObject *t = Address(o);
if (ttype(t) != LUA_T_ARRAY)
lua_error("API error - object is not a table in `lua_next'");
i = luaA_next(avalue(t), i);
top2LC((i==0) ? 0 : 2);
return i;
}
/*
** =======================================================
** Debug interface
** {======================================================
** To manipulate some state information
** =======================================================
*/
lua_State *lua_setstate (lua_State *st) {
lua_State *old = lua_state;
lua_state = st;
return old;
}
/* Hooks */
lua_CHFunction lua_callhook = NULL;
lua_LHFunction lua_linehook = NULL;
lua_LHFunction lua_setlinehook (lua_LHFunction func) {
lua_LHFunction old = L->linehook;
L->linehook = func;
return old;
}
lua_CHFunction lua_setcallhook (lua_CHFunction func) {
lua_CHFunction old = L->callhook;
L->callhook = func;
return old;
}
int lua_setdebug (int debug) {
int old = L->debug;
L->debug = debug;
return old;
}
/* }====================================================== */
/*
** {======================================================
** Debug interface
** =======================================================
*/
lua_Function lua_stackedfunction (int level)
@@ -457,6 +532,12 @@ lua_Function lua_stackedfunction (int level)
}
int lua_nups (lua_Function func) {
TObject *o = luaA_Address(func);
return (!o || normalized_type(o) != LUA_T_CLOSURE) ? 0 : o->value.cl->nelems;
}
int lua_currentline (lua_Function func)
{
TObject *f = Address(func);
@@ -465,8 +546,7 @@ int lua_currentline (lua_Function func)
}
lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
{
lua_Object lua_getlocal (lua_Function func, int local_number, char **name) {
/* check whether func is a Lua function */
if (lua_tag(func) != LUA_T_PROTO)
return LUA_NOOBJECT;
@@ -477,7 +557,7 @@ lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
if (*name) {
/* if "*name", there must be a LUA_T_LINE */
/* therefore, f+2 points to function base */
return Ref((f+2)+(local_number-1));
return put_luaObject((f+2)+(local_number-1));
}
else
return LUA_NOOBJECT;
@@ -508,18 +588,17 @@ int lua_setlocal (lua_Function func, int local_number)
}
void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
{
void lua_funcinfo (lua_Object func, char **source, int *linedefined) {
if (!lua_isfunction(func))
lua_error("API - `funcinfo' called with a non-function value");
lua_error("API error - `funcinfo' called with a non-function value");
else {
TObject *f = luaA_protovalue(Address(func));
if (normalized_type(f) == LUA_T_PROTO) {
*filename = tfvalue(f)->fileName->str;
*source = tfvalue(f)->source->str;
*linedefined = tfvalue(f)->lineDefined;
}
else {
*filename = "(C)";
*source = "(C)";
*linedefined = -1;
}
}
@@ -534,31 +613,37 @@ static int checkfunc (TObject *o)
char *lua_getobjname (lua_Object o, char **name)
{ /* try to find a name for given function */
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc */
if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
return "tag-method";
else if ((*name = luaS_travsymbol(checkfunc)) != NULL)
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
if ((*name = luaS_travsymbol(checkfunc)) != NULL)
return "global";
else if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
return "tag-method";
else return "";
}
/* }====================================================== */
/*
** =======================================================
** {======================================================
** BLOCK mechanism
** =======================================================
*/
void lua_beginblock (void)
{
if (L->numCblocks >= MAX_C_BLOCKS)
lua_error("too many nested blocks");
#ifndef MAX_C_BLOCKS
#define MAX_C_BLOCKS 1000 /* arbitrary limit */
#endif
void lua_beginblock (void) {
luaM_growvector(L->Cblocks, L->numCblocks, 1, struct C_Lua_Stack,
"too many nested blocks", MAX_C_BLOCKS);
L->Cblocks[L->numCblocks] = L->Cstack;
L->numCblocks++;
}
void lua_endblock (void)
{
void lua_endblock (void) {
--L->numCblocks;
L->Cstack = L->Cblocks[L->numCblocks];
luaD_adjusttop(L->Cstack.base);
@@ -566,8 +651,7 @@ void lua_endblock (void)
int lua_ref (int lock)
{
int lua_ref (int lock) {
int ref;
checkCparams(1);
ref = luaC_ref(L->stack.top-1, lock);
@@ -577,32 +661,12 @@ int lua_ref (int lock)
lua_Object lua_getref (int ref)
{
lua_Object lua_getref (int ref) {
TObject *o = luaC_getref(ref);
return (o ? put_luaObject(o) : LUA_NOOBJECT);
}
/*
** =======================================================
** Derived functions
** =======================================================
*/
int (lua_call) (char *name) { return lua_call(name); }
void (lua_pushref) (int ref) { lua_pushref(ref); }
int (lua_refobject) (lua_Object o, int l) { return lua_refobject(o, l); }
void (lua_register) (char *n, lua_CFunction f) { lua_register(n, f); }
void (lua_pushuserdata) (void *u) { lua_pushuserdata(u); }
void (lua_pushcfunction) (lua_CFunction f) { lua_pushcfunction(f); }
int (lua_clonetag) (int t) { return lua_clonetag(t); }
/* }====================================================== */
@@ -611,17 +675,15 @@ int (lua_clonetag) (int t) { return lua_clonetag(t); }
** API: set a function as a fallback
*/
static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults)
{
StkId base = (L->stack.top-L->stack.stack)-nParams;
static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults) {
luaD_openstack(nParams);
L->stack.stack[base].ttype = LUA_T_CPROTO;
L->stack.stack[base].value.f = f;
luaD_call(base+1, nResults);
(L->stack.top-nParams)->ttype = LUA_T_CPROTO;
(L->stack.top-nParams)->value.f = f;
luaD_calln(nParams, nResults);
}
lua_Object lua_setfallback (char *name, lua_CFunction fallback)
{
lua_Object lua_setfallback (char *name, lua_CFunction fallback) {
lua_pushstring(name);
lua_pushcfunction(fallback);
do_unprotectedrun(luaT_setfallback, 2, 1);

4
lapi.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
** $Id: lapi.h,v 1.3 1999/02/22 19:13:12 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
@@ -16,5 +16,7 @@ TObject *luaA_Address (lua_Object o);
void luaA_pushobject (TObject *o);
void luaA_packresults (void);
int luaA_passresults (void);
TaggedString *luaA_nextvar (TaggedString *g);
int luaA_next (Hash *t, int i);
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.c,v 1.11 1998/06/18 16:57:03 roberto Exp roberto $
** $Id: lauxlib.c,v 1.16 1999/03/10 14:19:41 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -10,9 +10,10 @@
#include <string.h>
/* Please Notice: This file uses only the official API of Lua
** Any function declared here could be written as an application
** function. With care, these functions can be used by other libraries.
** Any function declared here could be written as an application function.
** With care, these functions can be used by other libraries.
*/
#include "lauxlib.h"
#include "lua.h"
#include "luadebug.h"
@@ -27,12 +28,13 @@ int luaL_findstring (char *name, char *list[]) {
return -1; /* name not found */
}
void luaL_argerror (int numarg, char *extramsg)
{
void luaL_argerror (int numarg, char *extramsg) {
lua_Function f = lua_stackedfunction(0);
char *funcname;
lua_getobjname(lua_stackedfunction(0), &funcname);
lua_getobjname(f, &funcname);
numarg -= lua_nups(f);
if (funcname == NULL)
funcname = "???";
funcname = "?";
if (extramsg == NULL)
luaL_verror("bad argument #%d to function `%.50s'", numarg, funcname);
else
@@ -109,3 +111,23 @@ void luaL_verror (char *fmt, ...)
lua_error(buff);
}
void luaL_chunkid (char *out, char *source, int len) {
len -= 13; /* 13 = strlen("string ''...\0") */
if (*source == '@')
sprintf(out, "file `%.*s'", len, source+1);
else if (*source == '(')
strcpy(out, "(C code)");
else {
char *b = strchr(source , '\n'); /* stop string at first new line */
int lim = (b && (b-source)<len) ? b-source : len;
sprintf(out, "string `%.*s'", lim, source);
strcpy(out+lim+(13-5), "...'"); /* 5 = strlen("...'\0") */
}
}
void luaL_filesource (char *out, char *filename, int len) {
if (filename == NULL) filename = "(stdin)";
sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.h,v 1.8 1998/06/18 16:57:03 roberto Exp roberto $
** $Id: lauxlib.h,v 1.11 1999/03/04 21:17:26 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -28,7 +28,11 @@ char *luaL_check_lstr (int numArg, long *len);
#define luaL_opt_string(n, d) (luaL_opt_lstr((n), (d), NULL))
char *luaL_opt_lstr (int numArg, char *def, long *len);
double luaL_check_number (int numArg);
#define luaL_check_int(n) ((int)luaL_check_number(n))
#define luaL_check_long(n) ((long)luaL_check_number(n))
double luaL_opt_number (int numArg, double def);
#define luaL_opt_int(n,d) ((int)luaL_opt_number(n,d))
#define luaL_opt_long(n,d) ((long)luaL_opt_number(n,d))
lua_Object luaL_functionarg (int arg);
lua_Object luaL_tablearg (int arg);
lua_Object luaL_nonnullarg (int numArg);
@@ -42,6 +46,8 @@ int luaL_newbuffer (int size);
void luaL_oldbuffer (int old);
char *luaL_buffer (void);
int luaL_findstring (char *name, char *list[]);
void luaL_chunkid (char *out, char *source, int len);
void luaL_filesource (char *out, char *filename, int len);
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lbuffer.c,v 1.3 1998/06/02 20:37:04 roberto Exp roberto $
** $Id: lbuffer.c,v 1.8 1999/02/25 19:20:40 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -16,70 +16,60 @@
** Auxiliary buffer
-------------------------------------------------------*/
#define BUFF_STEP 32
#define EXTRABUFF 32
#define openspace(size) if (L->Mbuffnext+(size) > L->Mbuffsize) Openspace(size)
static void Openspace (int size)
{
static void Openspace (int size) {
lua_State *l = L; /* to optimize */
int base = l->Mbuffbase-l->Mbuffer;
l->Mbuffsize *= 2;
if (l->Mbuffnext+size > l->Mbuffsize) /* still not big enough? */
l->Mbuffsize = l->Mbuffnext+size;
l->Mbuffer = luaM_realloc(l->Mbuffer, l->Mbuffsize);
l->Mbuffbase = l->Mbuffer+base;
size += EXTRABUFF;
l->Mbuffsize = l->Mbuffnext+size;
luaM_growvector(l->Mbuffer, l->Mbuffnext, size, char, arrEM, MAX_INT);
}
char *luaL_openspace (int size)
{
char *luaL_openspace (int size) {
openspace(size);
return L->Mbuffer+L->Mbuffnext;
}
void luaL_addchar (int c)
{
openspace(BUFF_STEP);
L->Mbuffer[L->Mbuffnext++] = c;
void luaL_addchar (int c) {
openspace(1);
L->Mbuffer[L->Mbuffnext++] = (char)c;
}
void luaL_resetbuffer (void)
{
L->Mbuffnext = L->Mbuffbase-L->Mbuffer;
void luaL_resetbuffer (void) {
L->Mbuffnext = L->Mbuffbase;
}
void luaL_addsize (int n)
{
void luaL_addsize (int n) {
L->Mbuffnext += n;
}
int luaL_getsize (void)
{
return L->Mbuffnext-(L->Mbuffbase-L->Mbuffer);
int luaL_getsize (void) {
return L->Mbuffnext-L->Mbuffbase;
}
int luaL_newbuffer (int size)
{
int old = L->Mbuffbase-L->Mbuffer;
int luaL_newbuffer (int size) {
int old = L->Mbuffbase;
openspace(size);
L->Mbuffbase = L->Mbuffer+L->Mbuffnext;
L->Mbuffbase = L->Mbuffnext;
return old;
}
void luaL_oldbuffer (int old)
{
L->Mbuffnext = L->Mbuffbase-L->Mbuffer;
L->Mbuffbase = L->Mbuffer+old;
void luaL_oldbuffer (int old) {
L->Mbuffnext = L->Mbuffbase;
L->Mbuffbase = old;
}
char *luaL_buffer (void)
{
return L->Mbuffbase;
char *luaL_buffer (void) {
return L->Mbuffer+L->Mbuffbase;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lbuiltin.c,v 1.31 1998/06/19 18:47:06 roberto Exp roberto $
** $Id: lbuiltin.c,v 1.58 1999/05/27 20:21:03 roberto Exp roberto $
** Built-in functions
** See Copyright Notice in lua.h
*/
@@ -23,11 +23,18 @@
#include "ltm.h"
#include "lua.h"
#include "lundump.h"
#include "lvm.h"
static void pushstring (TaggedString *s)
{
/*
** {======================================================
** Auxiliary functions
** =======================================================
*/
static void pushtagstring (TaggedString *s) {
TObject o;
o.ttype = LUA_T_STRING;
o.value.ts = s;
@@ -35,209 +42,126 @@ static void pushstring (TaggedString *s)
}
static void nextvar (void)
{
TObject *o = luaA_Address(luaL_nonnullarg(1));
TaggedString *g;
if (ttype(o) == LUA_T_NIL)
g = (TaggedString *)L->rootglobal.next;
else {
luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
g = tsvalue(o);
/* check whether name is in global var list */
luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
g = (TaggedString *)g->head.next;
}
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
g = (TaggedString *)g->head.next;
if (g) {
pushstring(g);
luaA_pushobject(&g->u.s.globalval);
}
else lua_pushnil();
}
static void foreachvar (void)
{
TObject f = *luaA_Address(luaL_functionarg(1));
GCnode *g;
StkId name = L->Cstack.base++; /* place to keep var name (to avoid GC) */
ttype(L->stack.stack+name) = LUA_T_NIL;
L->stack.top++;
for (g = L->rootglobal.next; g; g = g->next) {
TaggedString *s = (TaggedString *)g;
if (s->u.s.globalval.ttype != LUA_T_NIL) {
ttype(L->stack.stack+name) = LUA_T_STRING;
tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */
luaA_pushobject(&f);
pushstring(s);
luaA_pushobject(&s->u.s.globalval);
luaD_call((L->stack.top-L->stack.stack)-2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL)
return;
L->stack.top--;
}
}
}
static void next (void)
{
lua_Object o = luaL_tablearg(1);
lua_Object r = luaL_nonnullarg(2);
Node *n = luaH_next(luaA_Address(o), luaA_Address(r));
if (n) {
luaA_pushobject(&n->ref);
luaA_pushobject(&n->val);
}
else lua_pushnil();
}
static void foreach (void)
{
TObject t = *luaA_Address(luaL_tablearg(1));
TObject f = *luaA_Address(luaL_functionarg(2));
static real getsize (Hash *h) {
real max = 0;
int i;
for (i=0; i<avalue(&t)->nhash; i++) {
Node *nd = &(avalue(&t)->node[i]);
if (ttype(ref(nd)) != LUA_T_NIL && ttype(val(nd)) != LUA_T_NIL) {
luaA_pushobject(&f);
luaA_pushobject(ref(nd));
luaA_pushobject(val(nd));
luaD_call((L->stack.top-L->stack.stack)-2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL)
return;
L->stack.top--;
}
for (i = 0; i<nhash(h); i++) {
Node *n = h->node+i;
if (ttype(ref(n)) == LUA_T_NUMBER &&
ttype(val(n)) != LUA_T_NIL &&
nvalue(ref(n)) > max)
max = nvalue(ref(n));
}
return max;
}
static real getnarg (Hash *a) {
TObject index;
TObject *value;
/* value = table.n */
ttype(&index) = LUA_T_STRING;
tsvalue(&index) = luaS_new("n");
value = luaH_get(a, &index);
return (ttype(value) == LUA_T_NUMBER) ? nvalue(value) : getsize(a);
}
static Hash *gethash (int arg) {
return avalue(luaA_Address(luaL_tablearg(arg)));
}
/* }====================================================== */
/*
** {======================================================
** Functions that use only the official API
** =======================================================
*/
/*
** If your system does not support "stderr", redefine this function, or
** redefine _ERRORMESSAGE so that it won't need _ALERT.
*/
static void luaB_alert (void) {
fputs(luaL_check_string(1), stderr);
}
/*
** Standard implementation of _ERRORMESSAGE.
** The library "iolib" redefines _ERRORMESSAGE for better error information.
*/
static void error_message (void) {
lua_Object al = lua_rawgetglobal("_ALERT");
if (lua_isfunction(al)) { /* avoid error loop if _ALERT is not defined */
char buff[600];
sprintf(buff, "lua error: %.500s\n", luaL_check_string(1));
lua_pushstring(buff);
lua_callfunction(al);
}
}
static void internaldostring (void)
{
long l;
char *s = luaL_check_lstr(1, &l);
if (*s == ID_CHUNK)
lua_error("`dostring' cannot run pre-compiled code");
if (lua_dobuffer(s, l, luaL_opt_string(2, NULL)) == 0)
if (luaA_passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
/*
** If your system does not support "stdout", 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).
*/
#ifndef MAXPRINT
#define MAXPRINT 40 /* arbitrary limit */
#endif
static void internaldofile (void)
{
char *fname = luaL_opt_string(1, NULL);
if (lua_dofile(fname) == 0)
if (luaA_passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
static void to_string (void) {
lua_Object obj = lua_getparam(1);
char *buff = luaL_openspace(30);
TObject *o = luaA_Address(obj);
switch (ttype(o)) {
case LUA_T_NUMBER:
lua_pushstring(lua_getstring(obj));
return;
case LUA_T_STRING:
lua_pushobject(obj);
return;
case LUA_T_ARRAY: {
sprintf(buff, "table: %p", (void *)o->value.a);
break;
}
case LUA_T_CLOSURE: {
sprintf(buff, "function: %p", (void *)o->value.cl);
break;
}
case LUA_T_PROTO: {
sprintf(buff, "function: %p", (void *)o->value.tf);
break;
}
case LUA_T_CPROTO: {
sprintf(buff, "function: %p", (void *)o->value.f);
break;
}
case LUA_T_USERDATA: {
sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
break;
}
case LUA_T_NIL:
lua_pushstring("nil");
return;
default:
LUA_INTERNALERROR("invalid type");
}
lua_pushstring(buff);
}
static void luaI_print (void) {
TaggedString *ts = luaS_new("tostring");
static void luaB_print (void) {
lua_Object args[MAXPRINT];
lua_Object obj;
int i = 1;
while ((obj = lua_getparam(i++)) != LUA_NOOBJECT) {
luaA_pushobject(&ts->u.s.globalval);
lua_pushobject(obj);
luaD_call((L->stack.top-L->stack.stack)-1, 1);
if (ttype(L->stack.top-1) != LUA_T_STRING)
lua_error("`tostring' must return a string to `print'");
printf("%s\t", svalue(L->stack.top-1));
L->stack.top--;
int n = 0;
int i;
while ((obj = lua_getparam(n+1)) != LUA_NOOBJECT) {
luaL_arg_check(n < MAXPRINT, n+1, "too many arguments");
args[n++] = obj;
}
printf("\n");
for (i=0; i<n; i++) {
lua_pushobject(args[i]);
if (lua_call("tostring"))
lua_error("error in `tostring' called by `print'");
obj = lua_getresult(1);
if (!lua_isstring(obj))
lua_error("`tostring' must return a string to `print'");
if (i>0) fputs("\t", stdout);
fputs(lua_getstring(obj), stdout);
}
fputs("\n", stdout);
}
static void luaI_type (void)
{
lua_Object o = luaL_nonnullarg(1);
lua_pushstring(luaO_typenames[-ttype(luaA_Address(o))]);
lua_pushnumber(lua_tag(o));
}
static void tonumber (void)
{
int base = luaL_opt_number(2, 10);
static void luaB_tonumber (void) {
int base = luaL_opt_int(2, 10);
if (base == 10) { /* standard conversion */
lua_Object o = lua_getparam(1);
if (lua_isnumber(o))
lua_pushnumber(lua_getnumber(o));
if (lua_isnumber(o)) lua_pushnumber(lua_getnumber(o));
else lua_pushnil(); /* not a number */
}
else {
char *s = luaL_check_string(1);
unsigned long n;
long n;
luaL_arg_check(0 <= base && base <= 36, 2, "base out of range");
n = strtol(s, &s, base);
while (isspace(*s)) s++; /* skip trailing spaces */
while (isspace((unsigned char)*s)) s++; /* skip trailing spaces */
if (*s) lua_pushnil(); /* invalid format: return nil */
else lua_pushnumber(n);
}
}
static void luaI_error (void)
{
static void luaB_error (void) {
lua_error(lua_getstring(lua_getparam(1)));
}
static void luaI_assert (void)
{
lua_Object p = lua_getparam(1);
if (p == LUA_NOOBJECT || lua_isnil(p))
luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
}
static void setglobal (void)
{
static void luaB_setglobal (void) {
char *n = luaL_check_string(1);
lua_Object value = luaL_nonnullarg(2);
lua_pushobject(value);
@@ -245,8 +169,7 @@ static void setglobal (void)
lua_pushobject(value); /* return given value */
}
static void rawsetglobal (void)
{
static void luaB_rawsetglobal (void) {
char *n = luaL_check_string(1);
lua_Object value = luaL_nonnullarg(2);
lua_pushobject(value);
@@ -254,51 +177,111 @@ static void rawsetglobal (void)
lua_pushobject(value); /* return given value */
}
static void getglobal (void)
{
static void luaB_getglobal (void) {
lua_pushobject(lua_getglobal(luaL_check_string(1)));
}
static void rawgetglobal (void)
{
static void luaB_rawgetglobal (void) {
lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
}
static void luatag (void)
{
static void luaB_luatag (void) {
lua_pushnumber(lua_tag(lua_getparam(1)));
}
static int getnarg (lua_Object table)
{
lua_Object temp;
/* temp = table.n */
lua_pushobject(table); lua_pushstring("n"); temp = lua_rawgettable();
return (lua_isnumber(temp) ? lua_getnumber(temp) : MAX_INT);
static void luaB_settag (void) {
lua_Object o = luaL_tablearg(1);
lua_pushobject(o);
lua_settag(luaL_check_int(2));
lua_pushobject(o); /* return first argument */
}
static void luaI_call (void)
{
static void luaB_newtag (void) {
lua_pushnumber(lua_newtag());
}
static void luaB_copytagmethods (void) {
lua_pushnumber(lua_copytagmethods(luaL_check_int(1),
luaL_check_int(2)));
}
static void luaB_rawgettable (void) {
lua_pushobject(luaL_nonnullarg(1));
lua_pushobject(luaL_nonnullarg(2));
lua_pushobject(lua_rawgettable());
}
static void luaB_rawsettable (void) {
lua_pushobject(luaL_nonnullarg(1));
lua_pushobject(luaL_nonnullarg(2));
lua_pushobject(luaL_nonnullarg(3));
lua_rawsettable();
}
static void luaB_settagmethod (void) {
lua_Object nf = luaL_nonnullarg(3);
lua_pushobject(nf);
lua_pushobject(lua_settagmethod(luaL_check_int(1), luaL_check_string(2)));
}
static void luaB_gettagmethod (void) {
lua_pushobject(lua_gettagmethod(luaL_check_int(1), luaL_check_string(2)));
}
static void luaB_seterrormethod (void) {
lua_Object nf = luaL_functionarg(1);
lua_pushobject(nf);
lua_pushobject(lua_seterrormethod());
}
static void luaB_collectgarbage (void) {
lua_pushnumber(lua_collectgarbage(luaL_opt_int(1, 0)));
}
/* }====================================================== */
/*
** {======================================================
** Functions that could use only the official API but
** do not, for efficiency.
** =======================================================
*/
static void luaB_dostring (void) {
long l;
char *s = luaL_check_lstr(1, &l);
if (*s == ID_CHUNK)
lua_error("`dostring' cannot run pre-compiled code");
if (lua_dobuffer(s, l, luaL_opt_string(2, s)) == 0)
if (luaA_passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
static void luaB_dofile (void) {
char *fname = luaL_opt_string(1, NULL);
if (lua_dofile(fname) == 0)
if (luaA_passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
static void luaB_call (void) {
lua_Object f = luaL_nonnullarg(1);
lua_Object arg = luaL_tablearg(2);
Hash *arg = gethash(2);
char *options = luaL_opt_string(3, "");
lua_Object err = lua_getparam(4);
int narg = getnarg(arg);
int narg = (int)getnarg(arg);
int i, status;
if (err != LUA_NOOBJECT) { /* set new error method */
lua_pushobject(err);
err = lua_seterrormethod();
}
/* push arg[1...n] */
for (i=0; i<narg; i++) {
lua_Object temp;
/* temp = arg[i+1] */
lua_pushobject(arg); lua_pushnumber(i+1); temp = lua_rawgettable();
if (narg == MAX_INT && lua_isnil(temp))
break;
lua_pushobject(temp);
}
luaD_checkstack(narg);
for (i=0; i<narg; i++)
*(L->stack.top++) = *luaH_getint(arg, i+1);
status = lua_callfunction(f);
if (err != LUA_NOOBJECT) { /* restore old error method */
lua_pushobject(err);
@@ -312,7 +295,7 @@ static void luaI_call (void)
else
lua_error(NULL);
}
else { /* no errors */
else { /* no errors */
if (strchr(options, 'p'))
luaA_packresults();
else
@@ -321,91 +304,306 @@ static void luaI_call (void)
}
static void settag (void)
{
lua_Object o = luaL_tablearg(1);
lua_pushobject(o);
lua_settag(luaL_check_number(2));
lua_pushobject(o); /* returns first argument */
static void luaB_nextvar (void) {
TObject *o = luaA_Address(luaL_nonnullarg(1));
TaggedString *g;
if (ttype(o) == LUA_T_NIL)
g = NULL;
else {
luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
g = tsvalue(o);
}
if (!luaA_nextvar(g))
lua_pushnil();
}
static void newtag (void)
{
lua_pushnumber(lua_newtag());
static void luaB_next (void) {
Hash *a = gethash(1);
TObject *k = luaA_Address(luaL_nonnullarg(2));
int i = (ttype(k) == LUA_T_NIL) ? 0 : luaH_pos(a, k)+1;
if (luaA_next(a, i) == 0)
lua_pushnil();
}
static void copytagmethods (void)
{
lua_pushnumber(lua_copytagmethods(luaL_check_number(1),
luaL_check_number(2)));
static void luaB_tostring (void) {
lua_Object obj = lua_getparam(1);
TObject *o = luaA_Address(obj);
char buff[64];
switch (ttype(o)) {
case LUA_T_NUMBER:
lua_pushstring(lua_getstring(obj));
return;
case LUA_T_STRING:
lua_pushobject(obj);
return;
case LUA_T_ARRAY:
sprintf(buff, "table: %p", (void *)o->value.a);
break;
case LUA_T_CLOSURE:
sprintf(buff, "function: %p", (void *)o->value.cl);
break;
case LUA_T_PROTO:
sprintf(buff, "function: %p", (void *)o->value.tf);
break;
case LUA_T_CPROTO:
sprintf(buff, "function: %p", (void *)o->value.f);
break;
case LUA_T_USERDATA:
sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
break;
case LUA_T_NIL:
lua_pushstring("nil");
return;
default:
LUA_INTERNALERROR("invalid type");
}
lua_pushstring(buff);
}
static void rawgettable (void)
{
lua_pushobject(luaL_nonnullarg(1));
lua_pushobject(luaL_nonnullarg(2));
lua_pushobject(lua_rawgettable());
static void luaB_type (void) {
lua_Object o = luaL_nonnullarg(1);
lua_pushstring(luaO_typename(luaA_Address(o)));
lua_pushnumber(lua_tag(o));
}
/* }====================================================== */
static void rawsettable (void)
{
lua_pushobject(luaL_nonnullarg(1));
lua_pushobject(luaL_nonnullarg(2));
lua_pushobject(luaL_nonnullarg(3));
lua_rawsettable();
}
static void settagmethod (void)
{
lua_Object nf = luaL_nonnullarg(3);
lua_pushobject(nf);
lua_pushobject(lua_settagmethod((int)luaL_check_number(1),
luaL_check_string(2)));
}
static void gettagmethod (void)
{
lua_pushobject(lua_gettagmethod((int)luaL_check_number(1),
luaL_check_string(2)));
}
static void seterrormethod (void)
{
lua_Object nf = luaL_functionarg(1);
lua_pushobject(nf);
lua_pushobject(lua_seterrormethod());
}
static void luaI_collectgarbage (void)
{
lua_pushnumber(lua_collectgarbage(luaL_opt_number(1, 0)));
}
/*
** {======================================================
** "Extra" functions
** These functions can be written in Lua, so you can
** delete them if you need a tiny Lua implementation.
** If you delete them, remove their entries in array
** "builtin_funcs".
** =======================================================
*/
static void luaB_assert (void) {
lua_Object p = lua_getparam(1);
if (p == LUA_NOOBJECT || lua_isnil(p))
luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
}
static void luaB_foreachi (void) {
Hash *t = gethash(1);
int i;
int n = (int)getnarg(t);
TObject f;
/* 'f' cannot be a pointer to TObject, because it is on the stack, and the
stack may be reallocated by the call. Moreover, some C compilers do not
initialize structs, so we must do the assignment after the declaration */
f = *luaA_Address(luaL_functionarg(2));
luaD_checkstack(3); /* for f, ref, and val */
for (i=1; i<=n; i++) {
*(L->stack.top++) = f;
ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i;
*(L->stack.top++) = *luaH_getint(t, i);
luaD_calln(2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL)
return;
L->stack.top--;
}
}
static void luaB_foreach (void) {
Hash *a = gethash(1);
int i;
TObject f; /* see comment in 'foreachi' */
f = *luaA_Address(luaL_functionarg(2));
luaD_checkstack(3); /* for f, ref, and val */
for (i=0; i<a->nhash; i++) {
Node *nd = &(a->node[i]);
if (ttype(val(nd)) != LUA_T_NIL) {
*(L->stack.top++) = f;
*(L->stack.top++) = *ref(nd);
*(L->stack.top++) = *val(nd);
luaD_calln(2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL)
return;
L->stack.top--; /* remove result */
}
}
}
static void luaB_foreachvar (void) {
GCnode *g;
TObject f; /* see comment in 'foreachi' */
f = *luaA_Address(luaL_functionarg(1));
luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
for (g = L->rootglobal.next; g; g = g->next) {
TaggedString *s = (TaggedString *)g;
if (s->u.s.globalval.ttype != LUA_T_NIL) {
pushtagstring(s); /* keep (extra) s on stack to avoid GC */
*(L->stack.top++) = f;
pushtagstring(s);
*(L->stack.top++) = s->u.s.globalval;
luaD_calln(2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL) {
L->stack.top--;
*(L->stack.top-1) = *L->stack.top; /* remove extra s */
return;
}
L->stack.top-=2; /* remove result and extra s */
}
}
}
static void luaB_getn (void) {
lua_pushnumber(getnarg(gethash(1)));
}
static void luaB_tinsert (void) {
Hash *a = gethash(1);
lua_Object v = lua_getparam(3);
int n = (int)getnarg(a);
int pos;
if (v != LUA_NOOBJECT)
pos = luaL_check_int(2);
else { /* called with only 2 arguments */
v = luaL_nonnullarg(2);
pos = n+1;
}
luaV_setn(a, n+1); /* a.n = n+1 */
for ( ;n>=pos; n--)
luaH_move(a, n, n+1); /* a[n+1] = a[n] */
luaH_setint(a, pos, luaA_Address(v)); /* a[pos] = v */
}
static void luaB_tremove (void) {
Hash *a = gethash(1);
int n = (int)getnarg(a);
int pos = luaL_opt_int(2, n);
if (n <= 0) return; /* table is "empty" */
luaA_pushobject(luaH_getint(a, pos)); /* result = a[pos] */
for ( ;pos<n; pos++)
luaH_move(a, pos+1, pos); /* a[pos] = a[pos+1] */
luaV_setn(a, n-1); /* a.n = n-1 */
luaH_setint(a, n, &luaO_nilobject); /* a[n] = nil */
}
/* {
** Quicksort
*/
static void swap (Hash *a, int i, int j) {
TObject temp;
temp = *luaH_getint(a, i);
luaH_move(a, j, i);
luaH_setint(a, j, &temp);
}
static int sort_comp (lua_Object f, TObject *a, TObject *b) {
/* notice: the caller (auxsort) must check stack space */
if (f != LUA_NOOBJECT) {
*(L->stack.top) = *luaA_Address(f);
*(L->stack.top+1) = *a;
*(L->stack.top+2) = *b;
L->stack.top += 3;
luaD_calln(2, 1);
}
else { /* a < b? */
*(L->stack.top) = *a;
*(L->stack.top+1) = *b;
L->stack.top += 2;
luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
}
return ttype(--(L->stack.top)) != LUA_T_NIL;
}
static void auxsort (Hash *a, int l, int u, lua_Object f) {
while (l < u) { /* for tail recursion */
TObject *P;
int i, j;
/* sort elements a[l], a[(l+u)/2] and a[u] */
if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[l]>a[u]? */
swap(a, l, u);
if (u-l == 1) break; /* only 2 elements */
i = (l+u)/2;
P = luaH_getint(a, i);
if (sort_comp(f, P, luaH_getint(a, l))) /* a[l]>a[i]? */
swap(a, l, i);
else if (sort_comp(f, luaH_getint(a, u), P)) /* a[i]>a[u]? */
swap(a, i, u);
if (u-l == 2) break; /* only 3 elements */
P = L->stack.top++;
*P = *luaH_getint(a, i); /* save pivot on stack (for GC) */
swap(a, i, u-1); /* put median element as pivot (a[u-1]) */
/* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
i = l; j = u-1;
for (;;) {
/* invariant: a[l..i] <= P <= a[j..u] */
while (sort_comp(f, luaH_getint(a, ++i), P)) /* stop when a[i] >= P */
if (i>u) lua_error("invalid order function for sorting");
while (sort_comp(f, P, luaH_getint(a, --j))) /* stop when a[j] <= P */
if (j<l) lua_error("invalid order function for sorting");
if (j<i) break;
swap(a, i, j);
}
swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */
L->stack.top--; /* remove pivot from stack */
/* 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(a, j, i, f); /* call recursively the smaller one */
} /* repeat the routine for the larger one */
}
static void luaB_sort (void) {
lua_Object t = lua_getparam(1);
Hash *a = gethash(1);
int n = (int)getnarg(a);
lua_Object func = lua_getparam(2);
luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2,
"function expected");
luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */
auxsort(a, 1, n, func);
lua_pushobject(t);
}
/* }}===================================================== */
/*
** ====================================================== */
#ifdef DEBUG
/*
** {======================================================
** some DEBUG functions
** =======================================================
*/
#ifdef DEBUG
static void mem_query (void)
{
static void mem_query (void) {
lua_pushnumber(totalmem);
lua_pushnumber(numblocks);
}
static void countlist (void)
{
static void query_strings (void) {
lua_pushnumber(L->string_root[luaL_check_int(1)].nuse);
}
static void countlist (void) {
char *s = luaL_check_string(1);
GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next :
(s[0]=='p') ? L->rootproto.next : L->rootglobal.next;
@@ -418,8 +616,7 @@ static void countlist (void)
}
static void testC (void)
{
static void testC (void) {
#define getnum(s) ((*s++) - '0')
#define getname(s) (nome[0] = *s++, nome)
@@ -428,7 +625,7 @@ static void testC (void)
char nome[2];
char *s = luaL_check_string(1);
nome[1] = 0;
while (1) {
for (;;) {
switch (*s++) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@@ -454,11 +651,17 @@ static void testC (void)
case '=': lua_setglobal(getname(s)); break;
case 's': lua_pushstring(getname(s)); break;
case 'o': lua_pushobject(reg[getnum(s)]); break;
case 'f': (lua_call)(getname(s)); break;
case 'f': lua_call(getname(s)); break;
case 'i': reg[getnum(s)] = lua_gettable(); break;
case 'I': reg[getnum(s)] = lua_rawgettable(); break;
case 't': lua_settable(); break;
case 'T': lua_rawsettable(); break;
case 'N' : lua_pushstring(lua_nextvar(lua_getstring(reg[getnum(s)])));
break;
case 'n' : { int n=getnum(s);
n=lua_next(reg[n], (int)lua_getnumber(reg[getnum(s)]));
lua_pushnumber(n); break;
}
default: luaL_verror("unknown command in `testC': %c", *(s-1));
}
if (*s == 0) return;
@@ -466,13 +669,12 @@ static void testC (void)
}
}
/* }====================================================== */
#endif
/*
** Internal functions
*/
static struct luaL_reg int_funcs[] = {
static struct luaL_reg builtin_funcs[] = {
#ifdef LUA_COMPAT2_5
{"setfallback", luaT_setfallback},
#endif
@@ -480,46 +682,54 @@ static struct luaL_reg int_funcs[] = {
{"testC", testC},
{"totalmem", mem_query},
{"count", countlist},
{"querystr", query_strings},
#endif
{"assert", luaI_assert},
{"call", luaI_call},
{"collectgarbage", luaI_collectgarbage},
{"dofile", internaldofile},
{"copytagmethods", copytagmethods},
{"dostring", internaldostring},
{"error", luaI_error},
{"foreach", foreach},
{"foreachvar", foreachvar},
{"getglobal", getglobal},
{"newtag", newtag},
{"next", next},
{"nextvar", nextvar},
{"print", luaI_print},
{"rawgetglobal", rawgetglobal},
{"rawgettable", rawgettable},
{"rawsetglobal", rawsetglobal},
{"rawsettable", rawsettable},
{"seterrormethod", seterrormethod},
{"setglobal", setglobal},
{"settagmethod", settagmethod},
{"gettagmethod", gettagmethod},
{"settag", settag},
{"tonumber", tonumber},
{"tostring", to_string},
{"tag", luatag},
{"type", luaI_type}
{"_ALERT", luaB_alert},
{"_ERRORMESSAGE", error_message},
{"call", luaB_call},
{"collectgarbage", luaB_collectgarbage},
{"copytagmethods", luaB_copytagmethods},
{"dofile", luaB_dofile},
{"dostring", luaB_dostring},
{"error", luaB_error},
{"getglobal", luaB_getglobal},
{"gettagmethod", luaB_gettagmethod},
{"newtag", luaB_newtag},
{"next", luaB_next},
{"nextvar", luaB_nextvar},
{"print", luaB_print},
{"rawgetglobal", luaB_rawgetglobal},
{"rawgettable", luaB_rawgettable},
{"rawsetglobal", luaB_rawsetglobal},
{"rawsettable", luaB_rawsettable},
{"seterrormethod", luaB_seterrormethod},
{"setglobal", luaB_setglobal},
{"settag", luaB_settag},
{"settagmethod", luaB_settagmethod},
{"tag", luaB_luatag},
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
{"type", luaB_type},
/* "Extra" functions */
{"assert", luaB_assert},
{"foreach", luaB_foreach},
{"foreachi", luaB_foreachi},
{"foreachvar", luaB_foreachvar},
{"getn", luaB_getn},
{"sort", luaB_sort},
{"tinsert", luaB_tinsert},
{"tremove", luaB_tremove}
};
#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0]))
#define INTFUNCSIZE (sizeof(builtin_funcs)/sizeof(builtin_funcs[0]))
void luaB_predefine (void)
{
void luaB_predefine (void) {
/* pre-register mem error messages, to avoid loop when error arises */
luaS_newfixedstring(tableEM);
luaS_newfixedstring(memEM);
luaL_openlib(int_funcs, (sizeof(int_funcs)/sizeof(int_funcs[0])));
luaL_openlib(builtin_funcs, (sizeof(builtin_funcs)/sizeof(builtin_funcs[0])));
lua_pushstring(LUA_VERSION);
lua_setglobal("_VERSION");
}

217
ldblib.c Normal file
View File

@@ -0,0 +1,217 @@
/*
** $Id: ldblib.c,v 1.4 1999/02/04 17:47:59 roberto Exp roberto $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "lua.h"
#include "luadebug.h"
#include "lualib.h"
static void settabss (lua_Object t, char *i, char *v) {
lua_pushobject(t);
lua_pushstring(i);
lua_pushstring(v);
lua_settable();
}
static void settabsi (lua_Object t, char *i, int v) {
lua_pushobject(t);
lua_pushstring(i);
lua_pushnumber(v);
lua_settable();
}
static lua_Object getfuncinfo (lua_Object func) {
lua_Object result = lua_createtable();
char *str;
int line;
lua_funcinfo(func, &str, &line);
if (line == -1) /* C function? */
settabss(result, "kind", "C");
else if (line == 0) { /* "main"? */
settabss(result, "kind", "chunk");
settabss(result, "source", str);
}
else { /* Lua function */
settabss(result, "kind", "Lua");
settabsi(result, "def_line", line);
settabss(result, "source", str);
}
if (line != 0) { /* is it not a "main"? */
char *kind = lua_getobjname(func, &str);
if (*kind) {
settabss(result, "name", str);
settabss(result, "where", kind);
}
}
return result;
}
static void getstack (void) {
lua_Object func = lua_stackedfunction(luaL_check_int(1));
if (func == LUA_NOOBJECT) /* level out of range? */
return;
else {
lua_Object result = getfuncinfo(func);
int currline = lua_currentline(func);
if (currline > 0)
settabsi(result, "current", currline);
lua_pushobject(result);
lua_pushstring("func");
lua_pushobject(func);
lua_settable(); /* result.func = func */
lua_pushobject(result);
}
}
static void funcinfo (void) {
lua_pushobject(getfuncinfo(luaL_functionarg(1)));
}
static int findlocal (lua_Object func, int arg) {
lua_Object v = lua_getparam(arg);
if (lua_isnumber(v))
return (int)lua_getnumber(v);
else {
char *name = luaL_check_string(arg);
int i = 0;
int result = -1;
char *vname;
while (lua_getlocal(func, ++i, &vname) != LUA_NOOBJECT) {
if (strcmp(name, vname) == 0)
result = i; /* keep looping to get the last var with this name */
}
if (result == -1)
luaL_verror("no local variable `%.50s' at given level", name);
return result;
}
}
static void getlocal (void) {
lua_Object func = lua_stackedfunction(luaL_check_int(1));
lua_Object val;
char *name;
if (func == LUA_NOOBJECT) /* level out of range? */
return; /* return nil */
else if (lua_getparam(2) != LUA_NOOBJECT) { /* 2nd argument? */
if ((val = lua_getlocal(func, findlocal(func, 2), &name)) != LUA_NOOBJECT) {
lua_pushobject(val);
lua_pushstring(name);
}
/* else return nil */
}
else { /* collect all locals in a table */
lua_Object result = lua_createtable();
int i;
for (i=1; ;i++) {
if ((val = lua_getlocal(func, i, &name)) == LUA_NOOBJECT)
break;
lua_pushobject(result);
lua_pushstring(name);
lua_pushobject(val);
lua_settable(); /* result[name] = value */
}
lua_pushobject(result);
}
}
static void setlocal (void) {
lua_Object func = lua_stackedfunction(luaL_check_int(1));
int numvar;
luaL_arg_check(func != LUA_NOOBJECT, 1, "level out of range");
numvar = findlocal(func, 2);
lua_pushobject(luaL_nonnullarg(3));
if (!lua_setlocal(func, numvar))
lua_error("no such local variable");
}
static int linehook = -1; /* Lua reference to line hook function */
static int callhook = -1; /* Lua reference to call hook function */
static void dohook (int ref) {
lua_LHFunction oldlinehook = lua_setlinehook(NULL);
lua_CHFunction oldcallhook = lua_setcallhook(NULL);
lua_callfunction(lua_getref(ref));
lua_setlinehook(oldlinehook);
lua_setcallhook(oldcallhook);
}
static void linef (int line) {
lua_pushnumber(line);
dohook(linehook);
}
static void callf (lua_Function func, char *file, int line) {
if (func != LUA_NOOBJECT) {
lua_pushobject(func);
lua_pushstring(file);
lua_pushnumber(line);
}
dohook(callhook);
}
static void setcallhook (void) {
lua_Object f = lua_getparam(1);
lua_unref(callhook);
if (f == LUA_NOOBJECT) {
callhook = -1;
lua_setcallhook(NULL);
}
else {
lua_pushobject(f);
callhook = lua_ref(1);
lua_setcallhook(callf);
}
}
static void setlinehook (void) {
lua_Object f = lua_getparam(1);
lua_unref(linehook);
if (f == LUA_NOOBJECT) {
linehook = -1;
lua_setlinehook(NULL);
}
else {
lua_pushobject(f);
linehook = lua_ref(1);
lua_setlinehook(linef);
}
}
static struct luaL_reg dblib[] = {
{"funcinfo", funcinfo},
{"getlocal", getlocal},
{"getstack", getstack},
{"setcallhook", setcallhook},
{"setlinehook", setlinehook},
{"setlocal", setlocal}
};
void lua_dblibopen (void) {
luaL_openlib(dblib, (sizeof(dblib)/sizeof(dblib[0])));
}

224
ldo.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.26 1998/06/15 21:34:14 roberto Exp roberto $
** $Id: ldo.c,v 1.44 1999/06/17 17:04:03 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -10,6 +10,7 @@
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
@@ -17,6 +18,7 @@
#include "lobject.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltm.h"
#include "lua.h"
#include "luadebug.h"
@@ -27,42 +29,33 @@
#ifndef STACK_LIMIT
#define STACK_LIMIT 6000
#define STACK_LIMIT 6000 /* arbitrary limit */
#endif
/*
** Error messages
*/
static void stderrorim (void)
{
fprintf(stderr, "lua error: %s\n", lua_getstring(lua_getparam(1)));
}
#define STACK_UNIT 128
void luaD_init (void)
{
#ifdef DEBUG
#undef STACK_UNIT
#define STACK_UNIT 2
#endif
void luaD_init (void) {
L->stack.stack = luaM_newvector(STACK_UNIT, TObject);
L->stack.top = L->stack.stack;
L->stack.last = L->stack.stack+(STACK_UNIT-1);
ttype(&L->errorim) = LUA_T_CPROTO;
fvalue(&L->errorim) = stderrorim;
}
void luaD_checkstack (int n)
{
void luaD_checkstack (int n) {
struct Stack *S = &L->stack;
if (S->last-S->top <= n) {
StkId top = S->top-S->stack;
int stacksize = (S->last-S->stack)+1+STACK_UNIT+n;
S->stack = luaM_reallocvector(S->stack, stacksize, TObject);
int stacksize = (S->last-S->stack)+STACK_UNIT+n;
luaM_reallocvector(S->stack, stacksize, TObject);
S->last = S->stack+(stacksize-1);
S->top = S->stack + top;
if (stacksize >= STACK_LIMIT) { /* stack overflow? */
@@ -78,8 +71,7 @@ void luaD_checkstack (int n)
/*
** Adjust stack. Set top to the given value, pushing NILs if needed.
*/
void luaD_adjusttop (StkId newtop)
{
void luaD_adjusttop (StkId newtop) {
int diff = newtop-(L->stack.top-L->stack.stack);
if (diff <= 0)
L->stack.top += diff;
@@ -94,38 +86,35 @@ void luaD_adjusttop (StkId newtop)
/*
** Open a hole below "nelems" from the L->stack.top.
*/
void luaD_openstack (int nelems)
{
void luaD_openstack (int nelems) {
luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems,
nelems*sizeof(TObject));
incr_top;
}
void luaD_lineHook (int line)
{
void luaD_lineHook (int line) {
struct C_Lua_Stack oldCLS = L->Cstack;
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
L->Cstack.num = 0;
(*lua_linehook)(line);
(*L->linehook)(line);
L->stack.top = L->stack.stack+old_top;
L->Cstack = oldCLS;
}
void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn)
{
void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn) {
struct C_Lua_Stack oldCLS = L->Cstack;
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
L->Cstack.num = 0;
if (isreturn)
(*lua_callhook)(LUA_NOOBJECT, "(return)", 0);
(*L->callhook)(LUA_NOOBJECT, "(return)", 0);
else {
TObject *f = L->stack.stack+base-1;
if (tf)
(*lua_callhook)(Ref(f), tf->fileName->str, tf->lineDefined);
(*L->callhook)(Ref(f), tf->source->str, tf->lineDefined);
else
(*lua_callhook)(Ref(f), "(C)", -1);
(*L->callhook)(Ref(f), "(C)", -1);
}
L->stack.top = L->stack.stack+old_top;
L->Cstack = oldCLS;
@@ -137,28 +126,26 @@ void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn)
** Cstack.num is the number of arguments; Cstack.lua2C points to the
** first argument. Returns an index to the first result from C.
*/
static StkId callC (lua_CFunction f, StkId base)
{
struct C_Lua_Stack *CS = &L->Cstack;
struct C_Lua_Stack oldCLS = *CS;
static StkId callC (lua_CFunction f, StkId base) {
struct C_Lua_Stack *cls = &L->Cstack;
struct C_Lua_Stack oldCLS = *cls;
StkId firstResult;
int numarg = (L->stack.top-L->stack.stack) - base;
CS->num = numarg;
CS->lua2C = base;
CS->base = base+numarg; /* == top-stack */
if (lua_callhook)
cls->num = numarg;
cls->lua2C = base;
cls->base = base+numarg; /* == top-stack */
if (L->callhook)
luaD_callHook(base, NULL, 0);
(*f)(); /* do the actual call */
if (lua_callhook) /* func may have changed lua_callhook */
if (L->callhook) /* func may have changed callhook */
luaD_callHook(base, NULL, 1);
firstResult = CS->base;
*CS = oldCLS;
firstResult = cls->base;
*cls = oldCLS;
return firstResult;
}
static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base)
{
static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base) {
TObject *pbase;
int nup = cl->nelems; /* number of upvalues */
luaD_checkstack(nup);
@@ -172,24 +159,25 @@ static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base)
}
void luaD_callTM (TObject *f, int nParams, int nResults)
{
void luaD_callTM (TObject *f, int nParams, int nResults) {
luaD_openstack(nParams);
*(L->stack.top-nParams-1) = *f;
luaD_call((L->stack.top-L->stack.stack)-nParams, nResults);
luaD_calln(nParams, nResults);
}
/*
** Call a function (C or Lua). The parameters must be on the L->stack.stack,
** between [L->stack.stack+base,L->stack.top). The function to be called is at L->stack.stack+base-1.
** When returns, the results are on the L->stack.stack, between [L->stack.stack+base-1,L->stack.top).
** Call a function (C or Lua). The parameters must be on the stack,
** between [top-nArgs,top). The function to be called is right below the
** arguments.
** When returns, the results are on the stack, between [top-nArgs-1,top).
** The number of results is nResults, unless nResults=MULT_RET.
*/
void luaD_call (StkId base, int nResults)
{
void luaD_calln (int nArgs, int nResults) {
struct Stack *S = &L->stack; /* to optimize */
StkId base = (S->top-S->stack)-nArgs;
TObject *func = S->stack+base-1;
StkId firstResult;
TObject *func = L->stack.stack+base-1;
int i;
switch (ttype(func)) {
case LUA_T_CPROTO:
@@ -214,23 +202,23 @@ void luaD_call (StkId base, int nResults)
TObject *im = luaT_getimbyObj(func, IM_FUNCTION);
if (ttype(im) == LUA_T_NIL)
lua_error("call expression not a function");
luaD_callTM(im, (L->stack.top-L->stack.stack)-(base-1), nResults);
luaD_callTM(im, (S->top-S->stack)-(base-1), nResults);
return;
}
}
/* adjust the number of results */
if (nResults != MULT_RET)
if (nResults == MULT_RET)
nResults = (S->top-S->stack)-firstResult;
else
luaD_adjusttop(firstResult+nResults);
/* move results to base-1 (to erase parameters and function) */
base--;
nResults = L->stack.top - (L->stack.stack+firstResult); /* actual number of results */
for (i=0; i<nResults; i++)
*(L->stack.stack+base+i) = *(L->stack.stack+firstResult+i);
L->stack.top -= firstResult-base;
*(S->stack+base+i) = *(S->stack+firstResult+i);
S->top -= firstResult-base;
}
/*
** Traverse all objects on L->stack.stack
*/
@@ -243,59 +231,50 @@ void luaD_travstack (int (*fn)(TObject *))
static void message (char *s)
{
TObject im = L->errorim;
if (ttype(&im) != LUA_T_NIL) {
static void message (char *s) {
TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
ttype(em) == LUA_T_CLOSURE) {
*L->stack.top = *em;
incr_top;
lua_pushstring(s);
luaD_callTM(&im, 1, 0);
luaD_calln(1, 0);
}
}
/*
** Reports an error, and jumps up to the available recover label
*/
void lua_error (char *s)
{
void lua_error (char *s) {
if (s) message(s);
if (L->errorJmp)
longjmp(*((jmp_buf *)L->errorJmp), 1);
longjmp(L->errorJmp->b, 1);
else {
fprintf (stderr, "lua: exit(1). Unable to recover\n");
message("exit(1). Unable to recover.\n");
exit(1);
}
}
/*
** Call the function at L->Cstack.base, and incorporate results on
** the Lua2C structure.
*/
static void do_callinc (int nResults)
{
StkId base = L->Cstack.base;
luaD_call(base+1, nResults);
L->Cstack.lua2C = base; /* position of the luaM_new results */
L->Cstack.num = (L->stack.top-L->stack.stack) - base; /* number of results */
L->Cstack.base = base + L->Cstack.num; /* incorporate results on L->stack.stack */
}
/*
** Execute a protected call. Assumes that function is at L->Cstack.base and
** parameters are on top of it. Leave nResults on the stack.
*/
int luaD_protectedrun (int nResults)
{
jmp_buf myErrorJmp;
int status;
int luaD_protectedrun (void) {
volatile struct C_Lua_Stack oldCLS = L->Cstack;
jmp_buf *volatile oldErr = L->errorJmp;
struct lua_longjmp myErrorJmp;
volatile int status;
struct lua_longjmp *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp) == 0) {
do_callinc(nResults);
if (setjmp(myErrorJmp.b) == 0) {
StkId base = L->Cstack.base;
luaD_calln((L->stack.top-L->stack.stack)-base-1, MULT_RET);
L->Cstack.lua2C = base; /* position of the new results */
L->Cstack.num = (L->stack.top-L->stack.stack) - base;
L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
status = 0;
}
else { /* an error occurred: restore L->Cstack and L->stack.top */
else { /* an error occurred: restore L->Cstack and L->stack.top */
L->Cstack = oldCLS;
L->stack.top = L->stack.stack+L->Cstack.base;
status = 1;
@@ -308,18 +287,20 @@ int luaD_protectedrun (int nResults)
/*
** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
*/
static int protectedparser (ZIO *z, int bin)
{
static int protectedparser (ZIO *z, int bin) {
volatile struct C_Lua_Stack oldCLS = L->Cstack;
struct lua_longjmp myErrorJmp;
volatile int status;
TProtoFunc *volatile tf;
jmp_buf myErrorJmp;
jmp_buf *volatile oldErr = L->errorJmp;
struct lua_longjmp *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp) == 0) {
if (setjmp(myErrorJmp.b) == 0) {
tf = bin ? luaU_undump1(z) : luaY_parser(z);
status = 0;
}
else {
else { /* an error occurred: restore L->Cstack and L->stack.top */
L->Cstack = oldCLS;
L->stack.top = L->stack.stack+L->Cstack.base;
tf = NULL;
status = 1;
}
@@ -334,9 +315,9 @@ static int protectedparser (ZIO *z, int bin)
}
static int do_main (ZIO *z, int bin)
{
static int do_main (ZIO *z, int bin) {
int status;
int debug = L->debug; /* save debug status */
do {
long old_blocks = (luaC_checkGC(), L->nblocks);
status = protectedparser(z, bin);
@@ -345,10 +326,11 @@ static int do_main (ZIO *z, int bin)
else {
unsigned long newelems2 = 2*(L->nblocks-old_blocks);
L->GCthreshold += newelems2;
status = luaD_protectedrun(MULT_RET);
status = luaD_protectedrun();
L->GCthreshold -= newelems2;
}
} while (bin && status == 0);
L->debug = debug; /* restore debug status */
return status;
}
@@ -364,23 +346,24 @@ void luaD_gcIM (TObject *o)
}
int lua_dofile (char *filename)
{
#define MAXFILENAME 260 /* maximum part of a file name kept */
int lua_dofile (char *filename) {
ZIO z;
int status;
int c;
int bin;
char source[MAXFILENAME];
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
if (f == NULL)
return 2;
if (filename == NULL)
filename = "(stdin)";
c = fgetc(f);
ungetc(c, f);
bin = (c == ID_CHUNK);
if (bin)
f = freopen(filename, "rb", f); /* set binary mode */
luaZ_Fopen(&z, f, filename);
luaL_filesource(source, filename, sizeof(source));
luaZ_Fopen(&z, f, source);
status = do_main(&z, bin);
if (f != stdin)
fclose(f);
@@ -388,40 +371,15 @@ int lua_dofile (char *filename)
}
#define SIZE_PREF 20 /* size of string prefix to appear in error messages */
#define SSIZE_PREF "20"
static void build_name (char *str, char *name) {
if (str == NULL || *str == ID_CHUNK)
strcpy(name, "(buffer)");
else {
char *temp;
sprintf(name, "(dostring) >> \"%." SSIZE_PREF "s\"", str);
temp = strchr(name, '\n');
if (temp) { /* end string after first line */
*temp = '"';
*(temp+1) = 0;
}
}
}
int lua_dostring (char *str) {
return lua_dobuffer(str, strlen(str), NULL);
return lua_dobuffer(str, strlen(str), str);
}
int lua_dobuffer (char *buff, int size, char *name) {
char newname[SIZE_PREF+25];
ZIO z;
int status;
if (name==NULL) {
build_name(buff, newname);
name = newname;
}
if (!name) name = "?";
luaZ_mopen(&z, buff, size, name);
status = do_main(&z, buff[0]==ID_CHUNK);
return status;
return do_main(&z, buff[0]==ID_CHUNK);
}

6
ldo.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 1.3 1997/11/19 17:29:23 roberto Exp roberto $
** $Id: ldo.h,v 1.5 1998/07/12 16:14:34 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -35,9 +35,9 @@ void luaD_adjusttop (StkId newtop);
void luaD_openstack (int nelems);
void luaD_lineHook (int line);
void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn);
void luaD_call (StkId base, int nResults);
void luaD_calln (int nArgs, int nResults);
void luaD_callTM (TObject *f, int nParams, int nResults);
int luaD_protectedrun (int nResults);
int luaD_protectedrun (void);
void luaD_gcIM (TObject *o);
void luaD_travstack (int (*fn)(TObject *));
void luaD_checkstack (int n);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lfunc.c,v 1.8 1997/12/15 16:17:20 roberto Exp roberto $
** $Id: lfunc.c,v 1.9 1998/06/19 16:14:09 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@@ -31,7 +31,7 @@ TProtoFunc *luaF_newproto (void)
TProtoFunc *f = luaM_new(TProtoFunc);
f->code = NULL;
f->lineDefined = 0;
f->fileName = NULL;
f->source = NULL;
f->consts = NULL;
f->nconsts = 0;
f->locvars = NULL;

31
lgc.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 1.17 1998/03/06 16:54:42 roberto Exp roberto $
** $Id: lgc.c,v 1.22 1999/02/26 15:48:55 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -29,23 +29,18 @@ static int markobject (TObject *o);
*/
int luaC_ref (TObject *o, int lock)
{
int luaC_ref (TObject *o, int lock) {
int ref;
if (ttype(o) == LUA_T_NIL)
ref = -1; /* special ref for nil */
else {
for (ref=0; ref<L->refSize; ref++)
if (L->refArray[ref].status == FREE)
goto found;
/* no more empty spaces */ {
int oldSize = L->refSize;
L->refSize = luaM_growvector(&L->refArray, L->refSize, struct ref,
refEM, MAX_INT);
for (ref=oldSize; ref<L->refSize; ref++)
L->refArray[ref].status = FREE;
ref = oldSize;
} found:
break;
if (ref == L->refSize) { /* no more empty spaces? */
luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT);
L->refSize++;
}
L->refArray[ref].o = *o;
L->refArray[ref].status = lock ? LOCK : HOLD;
}
@@ -163,21 +158,13 @@ static void strmark (TaggedString *s)
}
static void protomark (TProtoFunc *f)
{
static void protomark (TProtoFunc *f) {
if (!f->head.marked) {
LocVar *v = f->locvars;
int i;
f->head.marked = 1;
if (f->fileName)
strmark(f->fileName);
strmark(f->source);
for (i=0; i<f->nconsts; i++)
markobject(&f->consts[i]);
if (v) {
for (; v->line != -1; v++)
if (v->varname)
strmark(v->varname);
}
}
}

17
linit.c Normal file
View File

@@ -0,0 +1,17 @@
/*
** $Id: linit.c,v 1.1 1999/01/08 16:47:44 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/
#include "lua.h"
#include "lualib.h"
void lua_userinit (void) {
lua_iolibopen();
lua_strlibopen();
lua_mathlibopen();
lua_dblibopen();
}

559
liolib.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 1.20 1998/06/05 22:17:44 roberto Exp roberto $
** $Id: liolib.c,v 1.40 1999/05/14 12:24:04 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -20,6 +20,7 @@
#ifndef OLD_ANSI
#include <locale.h>
#else
/* no support for locale and for strerror: fake them */
#define setlocale(a,b) 0
#define LC_ALL 0
#define LC_COLLATE 0
@@ -31,10 +32,12 @@
#endif
#define CLOSEDTAG 2
#define IOTAG 1
#define IOTAG 1
#define FIRSTARG 2 /* 1st is upvalue */
#define CLOSEDTAG(tag) ((tag)-1) /* assume that CLOSEDTAG = iotag-1 */
#define FIRSTARG 3 /* 1st and 2nd are upvalues */
#define FINPUT "_INPUT"
#define FOUTPUT "_OUTPUT"
@@ -43,262 +46,371 @@
#ifdef POPEN
FILE *popen();
int pclose();
#define CLOSEFILE(f) {if (pclose(f) == -1) fclose(f);}
#else
/* no support for popen */
#define popen(x,y) NULL /* that is, popen always fails */
#define pclose(x) (-1)
#define CLOSEFILE(f) {fclose(f);}
#endif
static int gettag (int i)
{
return lua_getnumber(lua_getparam(i));
}
static void pushresult (int i)
{
static void pushresult (int i) {
if (i)
lua_pushuserdata(NULL);
else {
lua_pushnil();
lua_pushstring(strerror(errno));
lua_pushnumber(errno);
}
}
static int ishandler (lua_Object f)
{
/*
** {======================================================
** FILE Operations
** =======================================================
*/
static int gettag (void) {
return (int)lua_getnumber(lua_getparam(IOTAG));
}
static int ishandle (lua_Object f) {
if (lua_isuserdata(f)) {
if (lua_tag(f) == gettag(CLOSEDTAG))
int tag = gettag();
if (lua_tag(f) == CLOSEDTAG(tag))
lua_error("cannot access a closed file");
return lua_tag(f) == gettag(IOTAG);
return lua_tag(f) == tag;
}
else return 0;
}
static FILE *getfile (char *name)
{
static FILE *getfilebyname (char *name) {
lua_Object f = lua_getglobal(name);
if (!ishandler(f))
if (!ishandle(f))
luaL_verror("global variable `%.50s' is not a file handle", name);
return lua_getuserdata(f);
}
static FILE *getfileparam (char *name, int *arg)
{
lua_Object f = lua_getparam(*arg);
if (ishandler(f)) {
static FILE *getfile (int arg) {
lua_Object f = lua_getparam(arg);
return (ishandle(f)) ? lua_getuserdata(f) : NULL;
}
static FILE *getnonullfile (int arg) {
FILE *f = getfile(arg);
luaL_arg_check(f, arg, "invalid file handle");
return f;
}
static FILE *getfileparam (char *name, int *arg) {
FILE *f = getfile(*arg);
if (f) {
(*arg)++;
return lua_getuserdata(f);
return f;
}
else
return getfile(name);
return getfilebyname(name);
}
static void closefile (char *name)
{
FILE *f = getfile(name);
if (f == stdin || f == stdout) return;
if (pclose(f) == -1)
fclose(f);
lua_pushobject(lua_getglobal(name));
lua_settag(gettag(CLOSEDTAG));
static void closefile (FILE *f) {
if (f != stdin && f != stdout) {
int tag = gettag();
CLOSEFILE(f);
lua_pushusertag(f, tag);
lua_settag(CLOSEDTAG(tag));
}
}
static void setfile (FILE *f, char *name, int tag)
{
static void io_close (void) {
closefile(getnonullfile(FIRSTARG));
}
static void gc_close (void) {
FILE *f = getnonullfile(FIRSTARG);
if (f != stdin && f != stdout && f != stderr) {
CLOSEFILE(f);
}
}
static void io_open (void) {
FILE *f = fopen(luaL_check_string(FIRSTARG), luaL_check_string(FIRSTARG+1));
if (f) lua_pushusertag(f, gettag());
else pushresult(0);
}
static void setfile (FILE *f, char *name, int tag) {
lua_pushusertag(f, tag);
lua_setglobal(name);
}
static void setreturn (FILE *f, char *name)
{
int tag = gettag(IOTAG);
setfile(f, name, tag);
lua_pushusertag(f, tag);
static void setreturn (FILE *f, char *name) {
if (f == NULL)
pushresult(0);
else {
int tag = gettag();
setfile(f, name, tag);
lua_pushusertag(f, tag);
}
}
static void io_readfrom (void)
{
static void io_readfrom (void) {
FILE *current;
lua_Object f = lua_getparam(FIRSTARG);
if (f == LUA_NOOBJECT) {
closefile(FINPUT);
closefile(getfilebyname(FINPUT));
current = stdin;
}
else if (lua_tag(f) == gettag(IOTAG))
else if (lua_tag(f) == gettag()) /* deprecated option */
current = lua_getuserdata(f);
else {
char *s = luaL_check_string(FIRSTARG);
current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
if (current == NULL) {
pushresult(0);
return;
}
}
setreturn(current, FINPUT);
}
static void io_writeto (void)
{
static void io_writeto (void) {
FILE *current;
lua_Object f = lua_getparam(FIRSTARG);
if (f == LUA_NOOBJECT) {
closefile(FOUTPUT);
closefile(getfilebyname(FOUTPUT));
current = stdout;
}
else if (lua_tag(f) == gettag(IOTAG))
else if (lua_tag(f) == gettag()) /* deprecated option */
current = lua_getuserdata(f);
else {
char *s = luaL_check_string(FIRSTARG);
current = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
if (current == NULL) {
pushresult(0);
return;
}
current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w");
}
setreturn(current, FOUTPUT);
}
static void io_appendto (void)
{
char *s = luaL_check_string(FIRSTARG);
FILE *fp = fopen (s, "a");
if (fp != NULL)
setreturn(fp, FOUTPUT);
else
pushresult(0);
static void io_appendto (void) {
FILE *current = fopen(luaL_check_string(FIRSTARG), "a");
setreturn(current, FOUTPUT);
}
/*
** {======================================================
** READ
** =======================================================
*/
/*
** We cannot lookahead without need, because this can lock stdin.
** This flag signals when we need to read a next char.
*/
#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
static void read_until (FILE *f, int lim) {
int l = 0;
int c;
for (c = getc(f); c != EOF && c != lim; c = getc(f)) {
luaL_addchar(c);
l++;
}
if (l > 0 || c == lim) /* read anything? */
lua_pushlstring(luaL_buffer(), l);
}
static void io_read (void) {
int arg = FIRSTARG;
FILE *f = getfileparam(FINPUT, &arg);
char *p = luaL_opt_string(arg, NULL);
luaL_resetbuffer();
if (p == NULL) /* default: read a line */
read_until(f, '\n');
else if (p[0] == '.' && p[1] == '*' && p[2] == 0) /* p = ".*" */
read_until(f, EOF);
else {
int l = 0; /* number of chars read in buffer */
int inskip = 0; /* to control {skips} */
int c = NEED_OTHER;
while (*p) {
switch (*p) {
case '{':
inskip++;
p++;
continue;
case '}':
if (inskip == 0)
lua_error("unbalanced braces in read pattern");
inskip--;
p++;
continue;
default: {
char *ep; /* get what is next */
int m; /* match result */
if (c == NEED_OTHER) c = getc(f);
if (c == EOF) {
luaI_singlematch(0, p, &ep); /* to set "ep" */
m = 0;
}
else {
m = luaI_singlematch(c, p, &ep);
if (m) {
if (inskip == 0) {
luaL_addchar(c);
l++;
}
c = NEED_OTHER;
static int read_pattern (FILE *f, char *p) {
int inskip = 0; /* {skip} level */
int c = NEED_OTHER;
while (*p != '\0') {
switch (*p) {
case '{':
inskip++;
p++;
continue;
case '}':
if (!inskip) lua_error("unbalanced braces in read pattern");
inskip--;
p++;
continue;
default: {
char *ep = luaI_classend(p); /* get what is next */
int m; /* match result */
if (c == NEED_OTHER) c = getc(f);
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
if (m) {
if (!inskip) luaL_addchar(c);
c = NEED_OTHER;
}
switch (*ep) {
case '+': /* repetition (1 or more) */
if (!m) goto break_while; /* pattern fails? */
/* else go through */
case '*': /* repetition (0 or more) */
while (m) { /* reads the same item until it fails */
c = getc(f);
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
if (m && !inskip) luaL_addchar(c);
}
}
switch (*ep) {
case '*': /* repetition */
if (!m) p = ep+1; /* else stay in (repeat) the same item */
continue;
case '?': /* optional */
p = ep+1; /* continues reading the pattern */
continue;
default:
if (m) p = ep; /* continues reading the pattern */
else
goto break_while; /* pattern fails */
}
/* go through to continue reading the pattern */
case '?': /* optional */
p = ep+1; /* continues reading the pattern */
continue;
default:
if (!m) goto break_while; /* pattern fails? */
p = ep; /* else continues reading the pattern */
}
}
} break_while:
if (c >= 0) /* not EOF nor NEED_OTHER? */
ungetc(c, f);
if (l > 0 || *p == 0) /* read something or did not fail? */
lua_pushlstring(luaL_buffer(), l);
}
}
} break_while:
if (c != NEED_OTHER) ungetc(c, f);
return (*p == '\0');
}
static void io_write (void)
{
static int read_number (FILE *f) {
double d;
if (fscanf(f, "%lf", &d) == 1) {
lua_pushnumber(d);
return 1;
}
else return 0; /* read fails */
}
#define HUNK_LINE 1024
#define HUNK_FILE BUFSIZ
static int read_line (FILE *f) {
/* equivalent to: return read_pattern(f, "[^\n]*{\n}"); */
int n;
char *b;
do {
b = luaL_openspace(HUNK_LINE);
if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */
n = strlen(b);
luaL_addsize(n);
} while (b[n-1] != '\n');
luaL_addsize(-1); /* remove '\n' */
return 1;
}
static void read_file (FILE *f) {
/* equivalent to: return read_pattern(f, ".*"); */
int n;
do {
char *b = luaL_openspace(HUNK_FILE);
n = fread(b, sizeof(char), HUNK_FILE, f);
luaL_addsize(n);
} while (n==HUNK_FILE);
}
static void io_read (void) {
static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL};
int arg = FIRSTARG;
FILE *f = getfileparam(FINPUT, &arg);
char *p = luaL_opt_string(arg++, "*l");
do { /* repeat for each part */
long l;
int success;
luaL_resetbuffer();
switch (luaL_findstring(p, options)) {
case 0: /* number */
if (!read_number(f)) return; /* read fails */
continue; /* number is already pushed; avoid the "pushstring" */
case 1: /* line */
success = read_line(f);
break;
case 2: case 3: /* file */
read_file(f);
success = 1; /* always success */
break;
case 4: /* word */
success = read_pattern(f, "{%s*}%S+");
break;
default:
success = read_pattern(f, p);
}
l = luaL_getsize();
if (!success && l==0) return; /* read fails */
lua_pushlstring(luaL_buffer(), l);
} while ((p = luaL_opt_string(arg++, NULL)) != NULL);
}
/* }====================================================== */
static void io_write (void) {
int arg = FIRSTARG;
FILE *f = getfileparam(FOUTPUT, &arg);
int status = 1;
char *s;
long l;
while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL)
status = status && (fwrite(s, 1, l, f) == l);
status = status && ((long)fwrite(s, 1, l, f) == l);
pushresult(status);
}
static void io_execute (void)
{
static void io_seek (void) {
static int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static char *modenames[] = {"set", "cur", "end", NULL};
FILE *f = getnonullfile(FIRSTARG);
int op = luaL_findstring(luaL_opt_string(FIRSTARG+1, "cur"), modenames);
long offset = luaL_opt_long(FIRSTARG+2, 0);
luaL_arg_check(op != -1, FIRSTARG+1, "invalid mode");
op = fseek(f, offset, mode[op]);
if (op)
pushresult(0); /* error */
else
lua_pushnumber(ftell(f));
}
static void io_flush (void) {
FILE *f = getfile(FIRSTARG);
luaL_arg_check(f || lua_getparam(FIRSTARG) == LUA_NOOBJECT, FIRSTARG,
"invalid file handle");
pushresult(fflush(f) == 0);
}
/* }====================================================== */
/*
** {======================================================
** Other O.S. Operations
** =======================================================
*/
static void io_execute (void) {
lua_pushnumber(system(luaL_check_string(1)));
}
static void io_remove (void)
{
static void io_remove (void) {
pushresult(remove(luaL_check_string(1)) == 0);
}
static void io_rename (void)
{
static void io_rename (void) {
pushresult(rename(luaL_check_string(1),
luaL_check_string(2)) == 0);
}
static void io_tmpname (void)
{
static void io_tmpname (void) {
lua_pushstring(tmpnam(NULL));
}
static void io_getenv (void)
{
static void io_getenv (void) {
lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
}
@@ -308,12 +420,11 @@ static void io_clock (void) {
}
static void io_date (void)
{
time_t t;
struct tm *tm;
static void io_date (void) {
char b[256];
char *s = luaL_opt_string(1, "%c");
char b[BUFSIZ];
struct tm *tm;
time_t t;
time(&t); tm = localtime(&t);
if (strftime(b,sizeof(b),s,tm))
lua_pushstring(b);
@@ -322,8 +433,7 @@ static void io_date (void)
}
static void setloc (void)
{
static void setloc (void) {
static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC,
LC_TIME};
static char *catnames[] = {"all", "collate", "ctype", "monetary",
@@ -334,115 +444,140 @@ static void setloc (void)
}
static void io_exit (void)
{
static void io_exit (void) {
lua_Object o = lua_getparam(1);
exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
}
/* }====================================================== */
static void io_debug (void)
{
while (1) {
static void io_debug (void) {
for (;;) {
char buffer[250];
fprintf(stderr, "lua_debug> ");
if (fgets(buffer, sizeof(buffer), stdin) == 0) return;
if (strcmp(buffer, "cont\n") == 0) return;
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
strcmp(buffer, "cont\n") == 0)
return;
lua_dostring(buffer);
}
}
static void lua_printstack (FILE *f)
{
#define MESSAGESIZE 150
#define MAXMESSAGE (MESSAGESIZE*10)
#define MAXSRC 60
static void errorfb (void) {
char buff[MAXMESSAGE];
int level = 1; /* skip level 0 (it's this function) */
lua_Object func;
sprintf(buff, "lua error: %.200s\n", lua_getstring(lua_getparam(1)));
while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
char *name;
int currentline;
char *filename;
char *chunkname;
char buffchunk[MAXSRC];
int linedefined;
lua_funcinfo(func, &filename, &linedefined);
fprintf(f, (level==2) ? "Active Stack:\n\t" : "\t");
lua_funcinfo(func, &chunkname, &linedefined);
luaL_chunkid(buffchunk, chunkname, sizeof(buffchunk));
if (level == 2) strcat(buff, "Active Stack:\n");
strcat(buff, " ");
if (strlen(buff) > MAXMESSAGE-MESSAGESIZE) {
strcat(buff, "...\n");
break; /* buffer is full */
}
switch (*lua_getobjname(func, &name)) {
case 'g':
fprintf(f, "function %s", name);
sprintf(buff+strlen(buff), "function `%.50s'", name);
break;
case 't':
fprintf(f, "`%s' tag method", name);
sprintf(buff+strlen(buff), "`%.50s' tag method", name);
break;
default: {
if (linedefined == 0)
fprintf(f, "main of %s", filename);
sprintf(buff+strlen(buff), "main of %.70s", buffchunk);
else if (linedefined < 0)
fprintf(f, "%s", filename);
sprintf(buff+strlen(buff), "%.70s", buffchunk);
else
fprintf(f, "function (%s:%d)", filename, linedefined);
filename = NULL;
sprintf(buff+strlen(buff), "function <%d:%.70s>",
linedefined, buffchunk);
chunkname = NULL;
}
}
if ((currentline = lua_currentline(func)) > 0)
fprintf(f, " at line %d", currentline);
if (filename)
fprintf(f, " [in file %s]", filename);
fprintf(f, "\n");
sprintf(buff+strlen(buff), " at line %d", currentline);
if (chunkname)
sprintf(buff+strlen(buff), " [%.70s]", buffchunk);
strcat(buff, "\n");
}
func = lua_rawgetglobal("_ALERT");
if (lua_isfunction(func)) { /* avoid error loop if _ALERT is not defined */
lua_pushstring(buff);
lua_callfunction(func);
}
}
static void errorfb (void)
{
fprintf(stderr, "lua: %s\n", lua_getstring(lua_getparam(1)));
lua_printstack(stderr);
}
static struct luaL_reg iolib[] = {
{"setlocale", setloc},
{"execute", io_execute},
{"remove", io_remove},
{"rename", io_rename},
{"tmpname", io_tmpname},
{"getenv", io_getenv},
{"date", io_date},
{"clock", io_clock},
{"exit", io_exit},
{"debug", io_debug},
{"print_stack", errorfb}
{"_ERRORMESSAGE", errorfb},
{"clock", io_clock},
{"date", io_date},
{"debug", io_debug},
{"execute", io_execute},
{"exit", io_exit},
{"getenv", io_getenv},
{"remove", io_remove},
{"rename", io_rename},
{"setlocale", setloc},
{"tmpname", io_tmpname}
};
static struct luaL_reg iolibtag[] = {
{"readfrom", io_readfrom},
{"writeto", io_writeto},
{"appendto", io_appendto},
{"read", io_read},
{"write", io_write}
{"appendto", io_appendto},
{"closefile", io_close},
{"flush", io_flush},
{"openfile", io_open},
{"read", io_read},
{"readfrom", io_readfrom},
{"seek", io_seek},
{"write", io_write},
{"writeto", io_writeto}
};
static void openwithtags (void)
{
int iotag = lua_newtag();
int closedtag = lua_newtag();
static void openwithtags (void) {
int i;
int iotag = lua_newtag();
lua_newtag(); /* alloc CLOSEDTAG: assume that CLOSEDTAG = iotag-1 */
for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) {
/* put both tags as upvalues for these functions */
/* put iotag as upvalue for these functions */
lua_pushnumber(iotag);
lua_pushnumber(closedtag);
lua_pushcclosure(iolibtag[i].func, 2);
lua_pushcclosure(iolibtag[i].func, 1);
lua_setglobal(iolibtag[i].name);
}
/* predefined file handles */
setfile(stdin, FINPUT, iotag);
setfile(stdout, FOUTPUT, iotag);
setfile(stdin, "_STDIN", iotag);
setfile(stdout, "_STDOUT", iotag);
setfile(stderr, "_STDERR", iotag);
/* close file when collected */
lua_pushnumber(iotag);
lua_pushcclosure(gc_close, 1);
lua_settagmethod(iotag, "gc");
}
void lua_iolibopen (void)
{
void lua_iolibopen (void) {
/* register lib functions */
luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
openwithtags();
lua_pushcfunction(errorfb);
lua_seterrormethod();
}

130
llex.c
View File

@@ -1,6 +1,6 @@
/*
** $Id: llex.c,v 1.22 1998/06/19 18:47:06 roberto Exp roberto $
** Lexical Analizer
** $Id: llex.c,v 1.35 1999/05/14 12:24:04 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -20,9 +20,6 @@
int lua_debug=0;
#define next(LS) (LS->current = zgetc(LS->lex_z))
@@ -35,8 +32,7 @@ char *reserved [] = {"and", "do", "else", "elseif", "end", "function",
"until", "while"};
void luaX_init (void)
{
void luaX_init (void) {
int i;
for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
TaggedString *ts = luaS_new(reserved[i]);
@@ -45,24 +41,28 @@ void luaX_init (void)
}
#define MAXSRC 80
void luaX_syntaxerror (LexState *ls, char *s, char *token) {
if (token[0] == 0)
char buff[MAXSRC];
luaL_chunkid(buff, zname(ls->lex_z), sizeof(buff));
if (token[0] == '\0')
token = "<eof>";
luaL_verror("%.100s;\n last token read: `%.50s' at line %d in chunk `%.50s'",
s, token, ls->linenumber, zname(ls->lex_z));
luaL_verror("%.100s;\n last token read: `%.50s' at line %d in %.80s",
s, token, ls->linenumber, buff);
}
void luaX_error (LexState *ls, char *s) {
save(0);
save('\0');
luaX_syntaxerror(ls, s, luaL_buffer());
}
void luaX_token2str (LexState *ls, int token, char *s) {
void luaX_token2str (int token, char *s) {
if (token < 255) {
s[0] = token;
s[1] = 0;
s[0] = (char)token;
s[1] = '\0';
}
else
strcpy(s, reserved[token-FIRST_RESERVED]);
@@ -70,8 +70,8 @@ void luaX_token2str (LexState *ls, int token, char *s) {
static void luaX_invalidchar (LexState *ls, int c) {
char buff[10];
sprintf(buff, "0x%X", c);
char buff[8];
sprintf(buff, "0x%02X", c);
luaX_syntaxerror(ls, "invalid control char", buff);
}
@@ -106,17 +106,17 @@ void luaX_setinput (LexState *LS, ZIO *z)
** =======================================================
*/
#define PRAGMASIZE 20
#ifndef PRAGMASIZE
#define PRAGMASIZE 80 /* arbitrary limit */
#endif
static void skipspace (LexState *LS)
{
static void skipspace (LexState *LS) {
while (LS->current == ' ' || LS->current == '\t' || LS->current == '\r')
next(LS);
}
static int checkcond (LexState *LS, char *buff)
{
static int checkcond (LexState *LS, char *buff) {
static char *opts[] = {"nil", "1", NULL};
int i = luaL_findstring(buff, opts);
if (i >= 0) return i;
@@ -129,8 +129,7 @@ static int checkcond (LexState *LS, char *buff)
}
static void readname (LexState *LS, char *buff)
{
static void readname (LexState *LS, char *buff) {
int i = 0;
skipspace(LS);
while (isalnum(LS->current) || LS->current == '_') {
@@ -138,7 +137,7 @@ static void readname (LexState *LS, char *buff)
buff[PRAGMASIZE] = 0;
luaX_syntaxerror(LS, "pragma too long", buff);
}
buff[i++] = LS->current;
buff[i++] = (char)LS->current;
next(LS);
}
buff[i] = 0;
@@ -148,8 +147,7 @@ static void readname (LexState *LS, char *buff)
static void inclinenumber (LexState *LS);
static void ifskip (LexState *LS)
{
static void ifskip (LexState *LS) {
while (LS->ifstate[LS->iflevel].skip) {
if (LS->current == '\n')
inclinenumber(LS);
@@ -160,8 +158,7 @@ static void ifskip (LexState *LS)
}
static void inclinenumber (LexState *LS)
{
static void inclinenumber (LexState *LS) {
static char *pragmas [] =
{"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL};
next(LS); /* skip '\n' */
@@ -174,10 +171,10 @@ static void inclinenumber (LexState *LS)
readname(LS, buff);
switch (luaL_findstring(buff, pragmas)) {
case 0: /* debug */
if (!skip) lua_debug = 1;
if (!skip) L->debug = 1;
break;
case 1: /* nodebug */
if (!skip) lua_debug = 0;
if (!skip) L->debug = 0;
break;
case 2: /* endinput */
if (!skip) {
@@ -221,6 +218,7 @@ static void inclinenumber (LexState *LS)
}
/*
** =======================================================
** LEXICAL ANALIZER
@@ -229,12 +227,9 @@ static void inclinenumber (LexState *LS)
static int read_long_string (LexState *LS)
{
static int read_long_string (LexState *LS) {
int cont = 0;
while (1) {
for (;;) {
switch (LS->current) {
case EOZ:
luaX_error(LS, "unfinished long string");
@@ -262,17 +257,16 @@ static int read_long_string (LexState *LS)
save_and_next(LS);
}
} endloop:
save_and_next(LS); /* pass the second ']' */
LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+2,
L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4);
save_and_next(LS); /* skip the second ']' */
LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+2),
L->Mbuffnext-L->Mbuffbase-4);
return STRING;
}
int luaX_lex (LexState *LS) {
double a;
luaL_resetbuffer();
while (1) {
for (;;) {
switch (LS->current) {
case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
@@ -347,7 +341,7 @@ int luaX_lex (LexState *LS) {
c = 10*c + (LS->current-'0');
next(LS);
} while (++i<3 && isdigit(LS->current));
if (c >= 256)
if (c != (unsigned char)c)
luaX_error(LS, "escape sequence too large");
save(c);
}
@@ -364,8 +358,8 @@ int luaX_lex (LexState *LS) {
}
}
save_and_next(LS); /* skip delimiter */
LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+1,
L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-2);
LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+1),
L->Mbuffnext-L->Mbuffbase-2);
return STRING;
}
@@ -382,15 +376,11 @@ int luaX_lex (LexState *LS) {
else return CONC; /* .. */
}
else if (!isdigit(LS->current)) return '.';
/* LS->current is a digit: goes through to number */
a=0.0;
goto fraction;
goto fraction; /* LS->current is a digit: goes through to number */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
a=0.0;
do {
a = 10.0*a + (LS->current-'0');
save_and_next(LS);
} while (isdigit(LS->current));
if (LS->current == '.') {
@@ -402,35 +392,19 @@ int luaX_lex (LexState *LS) {
}
}
fraction:
{ double da=0.1;
while (isdigit(LS->current))
{
a += (LS->current-'0')*da;
da /= 10.0;
while (isdigit(LS->current))
save_and_next(LS);
if (toupper(LS->current) == 'E') {
save_and_next(LS); /* read 'E' */
save_and_next(LS); /* read '+', '-' or first digit */
while (isdigit(LS->current))
save_and_next(LS);
}
if (toupper(LS->current) == 'E') {
int e = 0;
int neg;
double ea;
save_and_next(LS);
neg = (LS->current=='-');
if (LS->current == '+' || LS->current == '-') save_and_next(LS);
if (!isdigit(LS->current))
luaX_error(LS, "invalid numeral format");
do {
e = 10*e + (LS->current-'0');
save_and_next(LS);
} while (isdigit(LS->current));
for (ea=neg?0.1:10.0; e>0; e>>=1)
{
if (e & 1) a *= ea;
ea *= ea;
}
}
LS->seminfo.r = a;
return NUMBER;
}
save('\0');
LS->seminfo.r = luaO_str2d(L->Mbuffer+L->Mbuffbase);
if (LS->seminfo.r < 0)
luaX_error(LS, "invalid numeric format");
return NUMBER;
case EOZ:
if (LS->iflevel > 0)
@@ -450,9 +424,9 @@ int luaX_lex (LexState *LS) {
do {
save_and_next(LS);
} while (isalnum(LS->current) || LS->current == '_');
save(0);
ts = luaS_new(L->Mbuffbase);
if (ts->head.marked >= 'A')
save('\0');
ts = luaS_new(L->Mbuffer+L->Mbuffbase);
if (ts->head.marked >= FIRST_RESERVED)
return ts->head.marked; /* reserved word */
LS->seminfo.ts = ts;
return NAME;

12
llex.h
View File

@@ -1,6 +1,6 @@
/*
** $Id: llex.h,v 1.8 1998/05/27 13:03:40 roberto Exp roberto $
** Lexical Analizer
** $Id: llex.h,v 1.11 1999/02/25 19:13:56 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -25,12 +25,14 @@ enum RESERVED {
NAME, CONC, DOTS, EQ, GE, LE, NE, NUMBER, STRING, EOS};
#define MAX_IFS 5
#ifndef MAX_IFS
#define MAX_IFS 5 /* arbitrary limit */
#endif
/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
struct ifState {
int elsepart; /* true if its in the $else part */
int elsepart; /* true if it's in the $else part */
int condition; /* true if $if condition is true */
int skip; /* true if part must be skipped */
};
@@ -56,7 +58,7 @@ void luaX_setinput (LexState *LS, ZIO *z);
int luaX_lex (LexState *LS);
void luaX_syntaxerror (LexState *ls, char *s, char *token);
void luaX_error (LexState *ls, char *s);
void luaX_token2str (LexState *ls, int token, char *s);
void luaX_token2str (int token, char *s);
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lmathlib.c,v 1.9 1998/05/27 19:09:39 roberto Exp roberto $
** $Id: lmathlib.c,v 1.16 1999/02/19 17:33:35 roberto Exp roberto $
** Lua standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -12,107 +12,96 @@
#include "lua.h"
#include "lualib.h"
#ifdef M_PI
#define PI M_PI
#undef PI
#define PI (3.14159265358979323846)
#define RADIANS_PER_DEGREE (PI/180.0)
/*
** If you want Lua to operate in radians (instead of degrees),
** define RADIANS
*/
#ifdef RADIANS
#define FROMRAD(a) (a)
#define TORAD(a) (a)
#else
#define PI ((double)3.14159265358979323846)
#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
#define TORAD(a) ((a)*RADIANS_PER_DEGREE)
#endif
#define FROMRAD(a) ((a)*(180.0/PI))
#define TORAD(a) ((a)*(PI/180.0))
static void math_abs (void)
{
double d = luaL_check_number(1);
if (d < 0) d = -d;
lua_pushnumber(d);
static void math_abs (void) {
lua_pushnumber(fabs(luaL_check_number(1)));
}
static void math_sin (void)
{
static void math_sin (void) {
lua_pushnumber(sin(TORAD(luaL_check_number(1))));
}
static void math_cos (void)
{
static void math_cos (void) {
lua_pushnumber(cos(TORAD(luaL_check_number(1))));
}
static void math_tan (void)
{
static void math_tan (void) {
lua_pushnumber(tan(TORAD(luaL_check_number(1))));
}
static void math_asin (void)
{
static void math_asin (void) {
lua_pushnumber(FROMRAD(asin(luaL_check_number(1))));
}
static void math_acos (void)
{
static void math_acos (void) {
lua_pushnumber(FROMRAD(acos(luaL_check_number(1))));
}
static void math_atan (void)
{
static void math_atan (void) {
lua_pushnumber(FROMRAD(atan(luaL_check_number(1))));
}
static void math_atan2 (void)
{
static void math_atan2 (void) {
lua_pushnumber(FROMRAD(atan2(luaL_check_number(1), luaL_check_number(2))));
}
static void math_ceil (void)
{
static void math_ceil (void) {
lua_pushnumber(ceil(luaL_check_number(1)));
}
static void math_floor (void)
{
static void math_floor (void) {
lua_pushnumber(floor(luaL_check_number(1)));
}
static void math_mod (void)
{
static void math_mod (void) {
lua_pushnumber(fmod(luaL_check_number(1), luaL_check_number(2)));
}
static void math_sqrt (void)
{
static void math_sqrt (void) {
lua_pushnumber(sqrt(luaL_check_number(1)));
}
static void math_pow (void)
{
static void math_pow (void) {
lua_pushnumber(pow(luaL_check_number(1), luaL_check_number(2)));
}
static void math_log (void)
{
static void math_log (void) {
lua_pushnumber(log(luaL_check_number(1)));
}
static void math_log10 (void)
{
static void math_log10 (void) {
lua_pushnumber(log10(luaL_check_number(1)));
}
static void math_exp (void)
{
static void math_exp (void) {
lua_pushnumber(exp(luaL_check_number(1)));
}
static void math_deg (void)
{
lua_pushnumber(luaL_check_number(1)*(180.0/PI));
static void math_deg (void) {
lua_pushnumber(luaL_check_number(1)/RADIANS_PER_DEGREE);
}
static void math_rad (void)
{
lua_pushnumber(luaL_check_number(1)*(PI/180.0));
static void math_rad (void) {
lua_pushnumber(luaL_check_number(1)*RADIANS_PER_DEGREE);
}
static void math_frexp (void) {
@@ -122,13 +111,12 @@ static void math_frexp (void) {
}
static void math_ldexp (void) {
lua_pushnumber(ldexp(luaL_check_number(1), luaL_check_number(2)));
lua_pushnumber(ldexp(luaL_check_number(1), luaL_check_int(2)));
}
static void math_min (void)
{
static void math_min (void) {
int i = 1;
double dmin = luaL_check_number(i);
while (lua_getparam(++i) != LUA_NOOBJECT) {
@@ -140,8 +128,7 @@ static void math_min (void)
}
static void math_max (void)
{
static void math_max (void) {
int i = 1;
double dmax = luaL_check_number(i);
while (lua_getparam(++i) != LUA_NOOBJECT) {
@@ -153,22 +140,27 @@ static void math_max (void)
}
static void math_random (void)
{
/* the '%' is needed because on some systems (SunOS!) "rand()" may */
/* return a value bigger than RAND_MAX... */
static void math_random (void) {
/* the '%' avoids the (rare) case of r==1, and is needed also because on
some systems (SunOS!) "rand()" may return a value bigger than RAND_MAX */
double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
double l = luaL_opt_number(1, 0);
int l = luaL_opt_int(1, 0);
if (l == 0)
lua_pushnumber(r);
else
lua_pushnumber((int)(r*l)+1);
else {
int u = luaL_opt_int(2, 0);
if (u == 0) {
u = l;
l = 1;
}
luaL_arg_check(l<=u, 1, "interval is empty");
lua_pushnumber((int)(r*(u-l+1))+l);
}
}
static void math_randomseed (void)
{
srand(luaL_check_number(1));
static void math_randomseed (void) {
srand(luaL_check_int(1));
}
@@ -201,10 +193,8 @@ static struct luaL_reg mathlib[] = {
/*
** Open math library
*/
void lua_mathlibopen (void)
{
void lua_mathlibopen (void) {
luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
lua_pushstring("deg"); lua_setglobal("_TRIGMODE");
lua_pushcfunction(math_pow);
lua_pushnumber(0); /* to get its tag */
lua_settagmethod(lua_tag(lua_pop()), "pow");

133
lmem.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lmem.c,v 1.6 1998/06/19 16:14:09 roberto Exp roberto $
** $Id: lmem.c,v 1.16 1999/05/20 20:43:06 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -12,41 +12,54 @@
#include "lua.h"
/*
** real ANSI systems do not need these tests;
** but some systems (Sun OS) are not that ANSI...
*/
#ifdef OLD_ANSI
#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
#define free(b) if (b) (free)(b)
#endif
int luaM_growaux (void **block, unsigned long nelems, int size,
char *errormsg, unsigned long limit)
{
if (nelems >= limit)
lua_error(errormsg);
nelems = (nelems == 0) ? 32 : nelems*2;
if (nelems > limit)
nelems = limit;
*block = luaM_realloc(*block, nelems*size);
return (int)nelems;
#define MINSIZE 8 /* minimum size for "growing" vectors */
static unsigned long power2 (unsigned long n) {
unsigned long p = MINSIZE;
while (p<=n) p<<=1;
return p;
}
void *luaM_growaux (void *block, unsigned long nelems, int inc, int size,
char *errormsg, unsigned long limit) {
unsigned long newn = nelems+inc;
if (newn >= limit) lua_error(errormsg);
if ((newn ^ nelems) <= nelems || /* still the same power of 2 limit? */
(nelems > 0 && newn < MINSIZE)) /* or block already is MINSIZE? */
return block; /* do not need to reallocate */
else /* it crossed a power of 2 boundary; grow to next power */
return luaM_realloc(block, power2(newn)*size);
}
#ifndef DEBUG
/*
** generic allocation routine.
** real ANSI systems do not need some of these tests,
** since realloc(NULL, s)==malloc(s) and realloc(b, 0)==free(b).
** But some systems (e.g. Sun OS) are not that ANSI...
*/
void *luaM_realloc (void *block, unsigned long size)
{
void *luaM_realloc (void *block, unsigned long size) {
size_t s = (size_t)size;
if (s != size)
lua_error("Allocation Error: Block too big");
lua_error("memory allocation error: block too big");
if (size == 0) {
if (block) {
free(block);
}
free(block); /* block may be NULL, that is OK for free */
return NULL;
}
block = block ? realloc(block, s) : malloc(s);
block = realloc(block, s);
if (block == NULL)
lua_error(memEM);
return block;
@@ -61,52 +74,66 @@ void *luaM_realloc (void *block, unsigned long size)
#define HEADER (sizeof(double))
#define MARKSIZE 16
#define MARK 55
#define blocksize(b) ((unsigned long *)((char *)(b) - HEADER))
unsigned long numblocks = 0;
unsigned long totalmem = 0;
static void *checkblock (void *block)
{
unsigned long *b = (unsigned long *)((char *)block - HEADER);
unsigned long size = *b;
LUA_ASSERT(*(((char *)b)+size+HEADER) == MARK,
"corrupted block");
numblocks--;
totalmem -= size;
return b;
static void *checkblock (void *block) {
if (block == NULL)
return NULL;
else {
unsigned long *b = blocksize(block);
unsigned long size = *b;
int i;
for (i=0;i<MARKSIZE;i++)
LUA_ASSERT(*(((char *)b)+HEADER+size+i) == MARK+i, "corrupted block");
numblocks--;
totalmem -= size;
return b;
}
}
void *luaM_realloc (void *block, unsigned long size)
{
unsigned long realsize = HEADER+size+1;
static void freeblock (void *block) {
if (block)
memset(block, -1, *blocksize(block)); /* erase block */
free(checkblock(block));
}
void *luaM_realloc (void *block, unsigned long size) {
unsigned long realsize = HEADER+size+MARKSIZE;
if (realsize != (size_t)realsize)
lua_error("Allocation Error: Block too big");
if (size == 0) { /* ANSI dosen't need this, but some machines... */
if (block) {
unsigned long *b = (unsigned long *)((char *)block - HEADER);
memset(block, -1, *b); /* erase block */
block = checkblock(block);
free(block);
}
lua_error("memory allocation error: block too big");
if (size == 0) {
freeblock(block);
return NULL;
}
if (block) {
block = checkblock(block);
block = (unsigned long *)realloc(block, realsize);
else {
char *newblock = malloc(realsize);
int i;
if (block) {
unsigned long oldsize = *blocksize(block);
if (oldsize > size) oldsize = size;
memcpy(newblock+HEADER, block, oldsize);
freeblock(block); /* erase (and check) old copy */
}
if (newblock == NULL)
lua_error(memEM);
totalmem += size;
numblocks++;
*(unsigned long *)newblock = size;
for (i=0;i<MARKSIZE;i++)
*(newblock+HEADER+size+i) = MARK+i;
return newblock+HEADER;
}
else
block = (unsigned long *)malloc(realsize);
if (block == NULL)
lua_error(memEM);
totalmem += size;
numblocks++;
*(unsigned long *)block = size;
*(((char *)block)+size+HEADER) = MARK;
return (unsigned long *)((char *)block+HEADER);
}

16
lmem.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lmem.h,v 1.4 1997/12/01 20:30:44 roberto Exp roberto $
** $Id: lmem.h,v 1.7 1999/02/25 15:16:26 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -8,10 +8,7 @@
#define lmem_h
#ifndef NULL
#define NULL 0
#endif
#include <stdlib.h>
/* memory error messages */
#define codeEM "code size overflow"
@@ -19,18 +16,19 @@
#define refEM "reference table overflow"
#define tableEM "table overflow"
#define memEM "not enough memory"
#define arrEM "internal array bigger than `int' limit"
void *luaM_realloc (void *oldblock, unsigned long size);
int luaM_growaux (void **block, unsigned long nelems, int size,
void *luaM_growaux (void *block, unsigned long nelems, int inc, int size,
char *errormsg, unsigned long limit);
#define luaM_free(b) luaM_realloc((b), 0)
#define luaM_malloc(t) luaM_realloc(NULL, (t))
#define luaM_new(t) ((t *)luaM_malloc(sizeof(t)))
#define luaM_newvector(n,t) ((t *)luaM_malloc((n)*sizeof(t)))
#define luaM_growvector(old,n,t,e,l) \
(luaM_growaux((void**)old,n,sizeof(t),e,l))
#define luaM_reallocvector(v,n,t) ((t *)luaM_realloc(v,(n)*sizeof(t)))
#define luaM_growvector(v,nelems,inc,t,e,l) \
((v)=(t *)luaM_growaux(v,nelems,inc,sizeof(t),e,l))
#define luaM_reallocvector(v,n,t) ((v)=(t *)luaM_realloc(v,(n)*sizeof(t)))
#ifdef DEBUG

View File

@@ -1,9 +1,10 @@
/*
** $Id: lobject.c,v 1.12 1998/06/18 16:57:03 roberto Exp roberto $
** $Id: lobject.c,v 1.18 1999/02/26 15:48:30 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdlib.h>
#include "lobject.h"
@@ -34,14 +35,12 @@ int luaO_redimension (int oldsize)
if (dimensions[i] > oldsize)
return dimensions[i];
}
lua_error("table overflow");
lua_error("tableEM");
return 0; /* to avoid warnings */
}
int luaO_equalObj (TObject *t1, TObject *t2)
{
if (ttype(t1) != ttype(t2)) return 0;
int luaO_equalval (TObject *t1, TObject *t2) {
switch (ttype(t1)) {
case LUA_T_NIL: return 1;
case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
@@ -64,20 +63,67 @@ void luaO_insertlist (GCnode *root, GCnode *node)
node->marked = 0;
}
#ifdef OLD_ANSI
void luaO_memup (void *dest, void *src, int size)
{
char *d = dest;
char *s = src;
while (size--) d[size]=s[size];
void luaO_memup (void *dest, void *src, int size) {
while (size--)
((char *)dest)[size]=((char *)src)[size];
}
void luaO_memdown (void *dest, void *src, int size)
{
char *d = dest;
char *s = src;
void luaO_memdown (void *dest, void *src, int size) {
int i;
for (i=0; i<size; i++) d[i]=s[i];
for (i=0; i<size; i++)
((char *)dest)[i]=((char *)src)[i];
}
#endif
static double expten (unsigned int e) {
double exp = 10.0;
double res = 1.0;
for (; e; e>>=1) {
if (e & 1) res *= exp;
exp *= exp;
}
return res;
}
double luaO_str2d (char *s) { /* LUA_NUMBER */
double a = 0.0;
int point = 0;
while (isdigit((unsigned char)*s)) {
a = 10.0*a + (*(s++)-'0');
}
if (*s == '.') {
s++;
while (isdigit((unsigned char)*s)) {
a = 10.0*a + (*(s++)-'0');
point++;
}
}
if (toupper((unsigned char)*s) == 'E') {
int e = 0;
int sig = 1;
s++;
if (*s == '-') {
s++;
sig = -1;
}
else if (*s == '+') s++;
if (!isdigit((unsigned char)*s)) return -1; /* no digit in the exponent? */
do {
e = 10*e + (*(s++)-'0');
} while (isdigit((unsigned char)*s));
point -= sig*e;
}
while (isspace((unsigned char)*s)) s++;
if (*s != '\0') return -1; /* invalid trailing characters? */
if (point > 0)
a /= expten(point);
else if (point < 0)
a *= expten(-point);
return a;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 1.20 1998/06/11 18:21:37 roberto Exp roberto $
** $Id: lobject.h,v 1.27 1999/03/04 21:17:26 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -32,10 +32,6 @@
#define LUA_NUM_TYPE double
#endif
/*
** format to convert number to strings
*/
#define NUMBER_FMT "%g"
typedef LUA_NUM_TYPE real;
@@ -45,13 +41,6 @@ typedef unsigned char Byte; /* unsigned 8 bits */
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
/* maximum value of a word of 2 bytes (-2 for safety); must fit in an "int" */
#if MAX_INT < 65534
#define MAX_WORD MAX_INT
#else
#define MAX_WORD 65534
#endif
typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */
@@ -75,7 +64,6 @@ typedef enum {
LUA_T_LINE = -11
} lua_Type;
#define NUM_TYPES 11
#define NUM_TAGS 7
@@ -139,7 +127,7 @@ typedef struct TProtoFunc {
int nconsts;
Byte *code; /* ends with opcode ENDCODE */
int lineDefined;
TaggedString *fileName;
TaggedString *source;
struct LocVar *locvars; /* ends with line = -1 */
} TProtoFunc;
@@ -192,11 +180,17 @@ typedef struct Hash {
extern char *luaO_typenames[];
#define luaO_typename(o) luaO_typenames[-ttype(o)]
extern TObject luaO_nilobject;
int luaO_equalObj (TObject *t1, TObject *t2);
#define luaO_equalObj(t1,t2) ((ttype(t1) != ttype(t2)) ? 0 \
: luaO_equalval(t1,t2))
int luaO_equalval (TObject *t1, TObject *t2);
int luaO_redimension (int oldsize);
void luaO_insertlist (GCnode *root, GCnode *node);
double luaO_str2d (char *s);
#ifdef OLD_ANSI
void luaO_memup (void *dest, void *src, int size);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.17 1998/03/25 18:52:29 roberto Exp roberto $
** $Id: lopcodes.h,v 1.32 1999/03/10 14:09:45 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -10,172 +10,129 @@
/*
** NOTICE: variants of the same opcode must be consecutive: First, those
** with byte parameter, then with built-in parameters, and last with
** word parameter.
** with word parameter, then with byte parameter.
*/
typedef enum {
/* name parm before after side effect
-----------------------------------------------------------------------------*/
ENDCODE,/* - - - */
ENDCODE,/* - - (return) */
RETCODE,/* b - (return) */
PUSHNIL,/* b - nil_0...nil_b */
PUSHNIL0,/* - - nil */
CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
PUSHNUMBER,/* b - (float)b */
PUSHNUMBER0,/* - - 0.0 */
PUSHNUMBER1,/* - - 1.0 */
PUSHNUMBER2,/* - - 2.0 */
PUSHNUMBERW,/* w - (float)w */
TAILCALL,/* b c v_c...v_1 f (return) f(v1,...,v_c) */
PUSHCONSTANT,/* b - CNST[b] */
PUSHCONSTANT0,/*- - CNST[0] */
PUSHCONSTANT1,/*- - CNST[1] */
PUSHCONSTANT2,/*- - CNST[2] */
PUSHCONSTANT3,/*- - CNST[3] */
PUSHCONSTANT4,/*- - CNST[4] */
PUSHCONSTANT5,/*- - CNST[5] */
PUSHCONSTANT6,/*- - CNST[6] */
PUSHCONSTANT7,/*- - CNST[7] */
PUSHCONSTANTW,/*w - CNST[w] */
PUSHNIL,/* b - nil_0...nil_b */
POP,/* b a_b...a_1 - */
PUSHUPVALUE,/* b - Closure[b] */
PUSHUPVALUE0,/* - - Closure[0] */
PUSHUPVALUE1,/* - - Closure[1] */
PUSHNUMBERW,/* w - (float)w */
PUSHNUMBER,/* b - (float)b */
PUSHLOCAL,/* b - LOC[b] */
PUSHLOCAL0,/* - - LOC[0] */
PUSHLOCAL1,/* - - LOC[1] */
PUSHLOCAL2,/* - - LOC[2] */
PUSHLOCAL3,/* - - LOC[3] */
PUSHLOCAL4,/* - - LOC[4] */
PUSHLOCAL5,/* - - LOC[5] */
PUSHLOCAL6,/* - - LOC[6] */
PUSHLOCAL7,/* - - LOC[7] */
PUSHNUMBERNEGW,/* w - (float)-w */
PUSHNUMBERNEG,/* b - (float)-b */
GETGLOBAL,/* b - VAR[CNST[b]] */
GETGLOBAL0,/* - - VAR[CNST[0]] */
GETGLOBAL1,/* - - VAR[CNST[1]] */
GETGLOBAL2,/* - - VAR[CNST[2]] */
GETGLOBAL3,/* - - VAR[CNST[3]] */
GETGLOBAL4,/* - - VAR[CNST[4]] */
GETGLOBAL5,/* - - VAR[CNST[5]] */
GETGLOBAL6,/* - - VAR[CNST[6]] */
GETGLOBAL7,/* - - VAR[CNST[7]] */
GETGLOBALW,/* w - VAR[CNST[w]] */
PUSHCONSTANTW,/*w - CNST[w] */
PUSHCONSTANT,/* b - CNST[b] */
GETTABLE,/* - i t t[i] */
PUSHUPVALUE,/* b - Closure[b] */
GETDOTTED,/* b t t[CNST[b]] */
GETDOTTED0,/* - t t[CNST[0]] */
GETDOTTED1,/* - t t[CNST[1]] */
GETDOTTED2,/* - t t[CNST[2]] */
GETDOTTED3,/* - t t[CNST[3]] */
GETDOTTED4,/* - t t[CNST[4]] */
GETDOTTED5,/* - t t[CNST[5]] */
GETDOTTED6,/* - t t[CNST[6]] */
GETDOTTED7,/* - t t[CNST[7]] */
GETDOTTEDW,/* w t t[CNST[w]] */
PUSHLOCAL,/* b - LOC[b] */
PUSHSELF,/* b t t t[CNST[b]] */
PUSHSELF0,/* - t t t[CNST[0]] */
PUSHSELF1,/* - t t t[CNST[1]] */
PUSHSELF2,/* - t t t[CNST[2]] */
PUSHSELF3,/* - t t t[CNST[3]] */
PUSHSELF4,/* - t t t[CNST[4]] */
PUSHSELF5,/* - t t t[CNST[5]] */
PUSHSELF6,/* - t t t[CNST[6]] */
PUSHSELF7,/* - t t t[CNST[7]] */
PUSHSELFW,/* w t t t[CNST[w]] */
GETGLOBALW,/* w - VAR[CNST[w]] */
GETGLOBAL,/* b - VAR[CNST[b]] */
CREATEARRAY,/* b - newarray(size = b) */
CREATEARRAY0,/* - - newarray(size = 0) */
CREATEARRAY1,/* - - newarray(size = 1) */
CREATEARRAYW,/* w - newarray(size = w) */
GETTABLE,/* - i t t[i] */
SETLOCAL,/* b x - LOC[b]=x */
SETLOCAL0,/* - x - LOC[0]=x */
SETLOCAL1,/* - x - LOC[1]=x */
SETLOCAL2,/* - x - LOC[2]=x */
SETLOCAL3,/* - x - LOC[3]=x */
SETLOCAL4,/* - x - LOC[4]=x */
SETLOCAL5,/* - x - LOC[5]=x */
SETLOCAL6,/* - x - LOC[6]=x */
SETLOCAL7,/* - x - LOC[7]=x */
GETDOTTEDW,/* w t t[CNST[w]] */
GETDOTTED,/* b t t[CNST[b]] */
SETGLOBAL,/* b x - VAR[CNST[b]]=x */
SETGLOBAL0,/* - x - VAR[CNST[0]]=x */
SETGLOBAL1,/* - x - VAR[CNST[1]]=x */
SETGLOBAL2,/* - x - VAR[CNST[2]]=x */
SETGLOBAL3,/* - x - VAR[CNST[3]]=x */
SETGLOBAL4,/* - x - VAR[CNST[4]]=x */
SETGLOBAL5,/* - x - VAR[CNST[5]]=x */
SETGLOBAL6,/* - x - VAR[CNST[6]]=x */
SETGLOBAL7,/* - x - VAR[CNST[7]]=x */
SETGLOBALW,/* w x - VAR[CNST[w]]=x */
PUSHSELFW,/* w t t t[CNST[w]] */
PUSHSELF,/* b t t t[CNST[b]] */
SETTABLE0,/* - v i t - t[i]=v */
CREATEARRAYW,/* w - newarray(size = w) */
CREATEARRAY,/* b - newarray(size = b) */
SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
SETLOCAL,/* b x - LOC[b]=x */
SETLIST,/* b c v_c...v_1 t - t[i+b*FPF]=v_i */
SETLIST0,/* b v_b...v_1 t - t[i]=v_i */
SETLISTW,/* w c v_c...v_1 t - t[i+w*FPF]=v_i */
SETGLOBALW,/* w x - VAR[CNST[w]]=x */
SETGLOBAL,/* b x - VAR[CNST[b]]=x */
SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */
SETMAP0,/* - v_0 k_0 t t t[k_0]=v_0 */
SETTABLEPOP,/* - v i t - t[i]=v */
EQOP,/* - y x (x==y)? 1 : nil */
NEQOP,/* - y x (x~=y)? 1 : nil */
LTOP,/* - y x (x<y)? 1 : nil */
LEOP,/* - y x (x<y)? 1 : nil */
GTOP,/* - y x (x>y)? 1 : nil */
GEOP,/* - y x (x>=y)? 1 : nil */
ADDOP,/* - y x x+y */
SUBOP,/* - y x x-y */
MULTOP,/* - y x x*y */
DIVOP,/* - y x x/y */
POWOP,/* - y x x^y */
CONCOP,/* - y x x..y */
MINUSOP,/* - x -x */
NOTOP,/* - x (x==nil)? 1 : nil */
SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */
ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */
ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */
ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */
JMP,/* b - - PC+=b */
JMPW,/* w - - PC+=w */
IFFJMP,/* b x - (x==nil)? PC+=b */
IFFJMPW,/* w x - (x==nil)? PC+=w */
IFTUPJMP,/* b x - (x!=nil)? PC-=b */
IFTUPJMPW,/* w x - (x!=nil)? PC-=w */
IFFUPJMP,/* b x - (x==nil)? PC-=b */
IFFUPJMPW,/* w x - (x==nil)? PC-=w */
SETLISTW,/* w c v_c...v_1 t t t[i+w*FPF]=v_i */
SETLIST,/* b c v_c...v_1 t t t[i+b*FPF]=v_i */
CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
CLOSUREW,/* w c v_b...v_1 closure(CNST[w], v_c...v_1) */
SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */
CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
CALLFUNC0,/* b v_b...v_1 f - f(v1,...,v_b) */
CALLFUNC1,/* b v_b...v_1 f r_1 f(v1,...,v_b) */
NEQOP,/* - y x (x~=y)? 1 : nil */
EQOP,/* - y x (x==y)? 1 : nil */
LTOP,/* - y x (x<y)? 1 : nil */
LEOP,/* - y x (x<y)? 1 : nil */
GTOP,/* - y x (x>y)? 1 : nil */
GEOP,/* - y x (x>=y)? 1 : nil */
ADDOP,/* - y x x+y */
SUBOP,/* - y x x-y */
MULTOP,/* - y x x*y */
DIVOP,/* - y x x/y */
POWOP,/* - y x x^y */
CONCOP,/* - y x x..y */
MINUSOP,/* - x -x */
NOTOP,/* - x (x==nil)? 1 : nil */
RETCODE,/* b - - */
ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */
ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */
ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */
ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */
JMPW,/* w - - PC+=w */
JMP,/* b - - PC+=b */
IFFJMPW,/* w x - (x==nil)? PC+=w */
IFFJMP,/* b x - (x==nil)? PC+=b */
IFTUPJMPW,/* w x - (x!=nil)? PC-=w */
IFTUPJMP,/* b x - (x!=nil)? PC-=b */
IFFUPJMPW,/* w x - (x==nil)? PC-=w */
IFFUPJMP,/* b x - (x==nil)? PC-=b */
SETLINE,/* b - - LINE=b */
SETLINEW,/* w - - LINE=w */
CLOSUREW,/* w c v_c...v_1 closure(CNST[w], v_c...v_1) */
CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
POP,/* b - - TOP-=(b+1) */
POP0,/* - - - TOP-=1 */
POP1/* - - - TOP-=2 */
SETLINEW,/* w - - LINE=w */
SETLINE,/* b - - LINE=b */
LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */
LONGARG,/* b (add b*(1<<16) to arg of next instruction) */
CHECKSTACK /* b (assert #temporaries == b; only for internal debuging!) */
} OpCode;
#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */
#define LFIELDS_PER_FLUSH 64 /* lists (SETLIST) */
#define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) */
#define ZEROVARARG 128
/* maximum value of an arg of 3 bytes; must fit in an "int" */
#if MAX_INT < (1<<24)
#define MAX_ARG MAX_INT
#else
#define MAX_ARG ((1<<24)-1)
#endif
/* maximum value of a word of 2 bytes; cannot be bigger than MAX_ARG */
#if MAX_ARG < (1<<16)
#define MAX_WORD MAX_ARG
#else
#define MAX_WORD ((1<<16)-1)
#endif
/* maximum value of a byte */
#define MAX_BYTE ((1<<8)-1)
#define ZEROVARARG 64
#endif

588
lparser.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
** $Id: lparser.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
** Syntax analizer and code generator
** $Id: lparser.h,v 1.2 1997/12/22 20:57:18 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.c,v 1.5 1997/12/17 20:48:58 roberto Exp roberto $
** $Id: lstate.c,v 1.11 1999/05/11 14:19:32 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -24,11 +24,19 @@ void lua_open (void)
{
if (lua_state) return;
lua_state = luaM_new(lua_State);
L->numCblocks = 0;
L->Cstack.base = 0;
L->Cstack.lua2C = 0;
L->Cstack.num = 0;
L->errorJmp = NULL;
L->Mbuffer = NULL;
L->Mbuffbase = 0;
L->Mbuffsize = 0;
L->Mbuffnext = 0;
L->Cblocks = NULL;
L->numCblocks = 0;
L->debug = 0;
L->callhook = NULL;
L->linehook = NULL;
L->rootproto.next = NULL;
L->rootproto.marked = 0;
L->rootcl.next = NULL;
@@ -37,12 +45,9 @@ void lua_open (void)
L->rootglobal.marked = 0;
L->roottable.next = NULL;
L->roottable.marked = 0;
L->IMtable = NULL;
L->refArray = NULL;
L->refSize = 0;
L->Mbuffsize = 0;
L->Mbuffnext = 0;
L->Mbuffbase = NULL;
L->Mbuffer = NULL;
L->GCthreshold = GARBAGE_BLOCK;
L->nblocks = 0;
luaD_init();
@@ -69,6 +74,7 @@ void lua_close (void)
luaM_free(L->IMtable);
luaM_free(L->refArray);
luaM_free(L->Mbuffer);
luaM_free(L->Cblocks);
luaM_free(L);
L = NULL;
#ifdef DEBUG
@@ -78,9 +84,3 @@ void lua_close (void)
}
lua_State *lua_setstate (lua_State *st) {
lua_State *old = lua_state;
lua_state = st;
return old;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 1.10 1998/06/19 16:14:09 roberto Exp roberto $
** $Id: lstate.h,v 1.18 1999/05/11 14:19:32 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -11,15 +11,24 @@
#include "lobject.h"
#include "lua.h"
#include "luadebug.h"
#define MAX_C_BLOCKS 10
#define GARBAGE_BLOCK 150
typedef int StkId; /* index to stack elements */
/*
** "jmp_buf" may be an array, so it is better to make sure it has an
** address (and not that it *is* an address...)
*/
struct lua_longjmp {
jmp_buf b;
};
struct Stack {
TObject *top;
TObject *stack;
@@ -34,7 +43,7 @@ struct C_Lua_Stack {
};
typedef struct {
typedef struct stringtable {
int size;
int nuse; /* number of elements (including EMPTYs) */
TaggedString **hash;
@@ -53,22 +62,23 @@ struct lua_State {
/* thread-specific state */
struct Stack stack; /* Lua stack */
struct C_Lua_Stack Cstack; /* C2lua struct */
jmp_buf *errorJmp; /* current error recover point */
struct lua_longjmp *errorJmp; /* current error recover point */
char *Mbuffer; /* global buffer */
char *Mbuffbase; /* current first position of Mbuffer */
int Mbuffbase; /* current first position of Mbuffer */
int Mbuffsize; /* size of Mbuffer */
int Mbuffnext; /* next position to fill in Mbuffer */
struct C_Lua_Stack Cblocks[MAX_C_BLOCKS];
struct C_Lua_Stack *Cblocks;
int numCblocks; /* number of nested Cblocks */
int debug;
lua_CHFunction callhook;
lua_LHFunction linehook;
/* global state */
TObject errorim; /* error tag method */
GCnode rootproto; /* list of all prototypes */
GCnode rootcl; /* list of all closures */
GCnode roottable; /* list of all tables */
GCnode rootglobal; /* list of strings with global values */
stringtable *string_root; /* array of hash tables for strings and udata */
struct IM *IMtable; /* table for tag methods */
int IMtable_size; /* size of IMtable */
int last_tag; /* last used tag in IMtable */
struct ref *refArray; /* locked objects */
int refSize; /* size of refArray */
@@ -77,10 +87,8 @@ struct lua_State {
};
extern lua_State *lua_state;
#define L lua_state
#endif

139
lstring.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lstring.c,v 1.12 1998/03/06 16:54:42 roberto Exp roberto $
** $Id: lstring.c,v 1.18 1999/02/08 16:28:48 roberto Exp roberto $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -14,7 +14,9 @@
#include "lua.h"
#define NUM_HASHS 61
#define NUM_HASHSTR 31
#define NUM_HASHUDATA 31
#define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA)
#define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */
@@ -25,8 +27,7 @@ static TaggedString EMPTY = {{NULL, 2}, 0L, 0,
{{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
void luaS_init (void)
{
void luaS_init (void) {
int i;
L->string_root = luaM_newvector(NUM_HASHS, stringtable);
for (i=0; i<NUM_HASHS; i++) {
@@ -37,16 +38,14 @@ void luaS_init (void)
}
static unsigned long hash_s (char *s, long l)
{
unsigned long h = 0;
static unsigned long hash_s (char *s, long l) {
unsigned long h = 0; /* seed */
while (l--)
h = ((h<<5)-h)^(unsigned char)*(s++);
h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++));
return h;
}
static int newsize (stringtable *tb)
{
static int newsize (stringtable *tb) {
int size = tb->size;
int realuse = 0;
int i;
@@ -54,16 +53,11 @@ static int newsize (stringtable *tb)
for (i=0; i<size; i++)
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
realuse++;
if (2*(realuse+1) <= size) /* +1 is the new element */
return size; /* don't need to grow, just rehash to clear EMPTYs */
else
return luaO_redimension(size);
return luaO_redimension((realuse+1)*2); /* +1 is the new element */
}
static void grow (stringtable *tb)
{
static void grow (stringtable *tb) {
int ns = newsize(tb);
TaggedString **newhash = luaM_newvector(ns, TaggedString *);
int i;
@@ -73,10 +67,13 @@ static void grow (stringtable *tb)
tb->nuse = 0;
for (i=0; i<tb->size; i++) {
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
int h = tb->hash[i]->hash%ns;
while (newhash[h])
h = (h+1)%ns;
newhash[h] = tb->hash[i];
unsigned long h = tb->hash[i]->hash;
int h1 = h%ns;
while (newhash[h1]) {
h1 += (h&(ns-2)) + 1; /* double hashing */
if (h1 >= ns) h1 -= ns;
}
newhash[h1] = tb->hash[i];
tb->nuse++;
}
}
@@ -86,8 +83,7 @@ static void grow (stringtable *tb)
}
static TaggedString *newone_s (char *str, long l, unsigned long h)
{
static TaggedString *newone_s (char *str, long l, unsigned long h) {
TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
memcpy(ts->str, str, l);
ts->str[l] = 0; /* ending 0 */
@@ -101,8 +97,7 @@ static TaggedString *newone_s (char *str, long l, unsigned long h)
return ts;
}
static TaggedString *newone_u (char *buff, int tag, unsigned long h)
{
static TaggedString *newone_u (char *buff, int tag, unsigned long h) {
TaggedString *ts = luaM_new(TaggedString);
ts->u.d.v = buff;
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
@@ -114,82 +109,79 @@ static TaggedString *newone_u (char *buff, int tag, unsigned long h)
return ts;
}
static TaggedString *insert_s (char *str, long l, stringtable *tb)
{
static TaggedString *insert_s (char *str, long l, stringtable *tb) {
TaggedString *ts;
unsigned long h = hash_s(str, l);
int size = tb->size;
int i;
int j = -1;
int h1;
if ((long)tb->nuse*3 >= (long)size*2) {
grow(tb);
size = tb->size;
}
for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
h1 = h%size;
while ((ts = tb->hash[h1]) != NULL) {
if (ts == &EMPTY)
j = i;
else if (ts->constindex >= 0 &&
ts->u.s.len == l &&
(memcmp(str, ts->str, l) == 0))
j = h1;
else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
return ts;
if (++i == size) i=0;
h1 += (h&(size-2)) + 1; /* double hashing */
if (h1 >= size) h1 -= size;
}
/* not found */
if (j != -1) /* is there an EMPTY space? */
i = j;
h1 = j;
else
tb->nuse++;
ts = tb->hash[i] = newone_s(str, l, h);
ts = tb->hash[h1] = newone_s(str, l, h);
return ts;
}
static TaggedString *insert_u (void *buff, int tag, stringtable *tb)
{
static TaggedString *insert_u (void *buff, int tag, stringtable *tb) {
TaggedString *ts;
unsigned long h = (unsigned long)buff;
int size = tb->size;
int i;
int j = -1;
int h1;
if ((long)tb->nuse*3 >= (long)size*2) {
grow(tb);
size = tb->size;
}
for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
h1 = h%size;
while ((ts = tb->hash[h1]) != NULL) {
if (ts == &EMPTY)
j = i;
else if (ts->constindex < 0 && /* is a udata? */
(tag == ts->u.d.tag || tag == LUA_ANYTAG) &&
buff == ts->u.d.v)
j = h1;
else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)
return ts;
if (++i == size) i=0;
h1 += (h&(size-2)) + 1; /* double hashing */
if (h1 >= size) h1 -= size;
}
/* not found */
if (j != -1) /* is there an EMPTY space? */
i = j;
h1 = j;
else
tb->nuse++;
ts = tb->hash[i] = newone_u(buff, tag, h);
ts = tb->hash[h1] = newone_u(buff, tag, h);
return ts;
}
TaggedString *luaS_createudata (void *udata, int tag)
{
return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]);
TaggedString *luaS_createudata (void *udata, int tag) {
int t = ((unsigned)udata%NUM_HASHUDATA)+NUM_HASHSTR;
return insert_u(udata, tag, &L->string_root[t]);
}
TaggedString *luaS_newlstr (char *str, long l)
{
int i = (l==0)?0:(unsigned char)str[0];
return insert_s(str, l, &L->string_root[i%NUM_HASHS]);
TaggedString *luaS_newlstr (char *str, long l) {
int t = (l==0) ? 0 : ((int)((unsigned char)str[0]*l))%NUM_HASHSTR;
return insert_s(str, l, &L->string_root[t]);
}
TaggedString *luaS_new (char *str)
{
TaggedString *luaS_new (char *str) {
return luaS_newlstr(str, strlen(str));
}
TaggedString *luaS_newfixedstring (char *str)
{
TaggedString *luaS_newfixedstring (char *str) {
TaggedString *ts = luaS_new(str);
if (ts->head.marked == 0)
ts->head.marked = 2; /* avoid GC */
@@ -197,8 +189,7 @@ TaggedString *luaS_newfixedstring (char *str)
}
void luaS_free (TaggedString *l)
{
void luaS_free (TaggedString *l) {
while (l) {
TaggedString *next = (TaggedString *)l->head.next;
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
@@ -212,8 +203,7 @@ void luaS_free (TaggedString *l)
** Garbage collection functions.
*/
static void remove_from_list (GCnode *l)
{
static void remove_from_list (GCnode *l) {
while (l) {
GCnode *next = l->next;
while (next && !next->marked)
@@ -223,8 +213,7 @@ static void remove_from_list (GCnode *l)
}
TaggedString *luaS_collector (void)
{
TaggedString *luaS_collector (void) {
TaggedString *frees = NULL;
int i;
remove_from_list(&(L->rootglobal));
@@ -247,18 +236,18 @@ TaggedString *luaS_collector (void)
}
TaggedString *luaS_collectudata (void)
{
TaggedString *luaS_collectudata (void) {
TaggedString *frees = NULL;
int i;
L->rootglobal.next = NULL; /* empty list of globals */
for (i=0; i<NUM_HASHS; i++) {
for (i=NUM_HASHSTR; i<NUM_HASHS; i++) {
stringtable *tb = &L->string_root[i];
int j;
for (j=0; j<tb->size; j++) {
TaggedString *t = tb->hash[j];
if (t == NULL || t == &EMPTY || t->constindex != -1)
continue; /* get only user data */
if (t == NULL || t == &EMPTY)
continue;
LUA_ASSERT(t->constindex == -1, "must be userdata");
t->head.next = (GCnode *)frees;
frees = t;
tb->hash[j] = &EMPTY;
@@ -268,8 +257,7 @@ TaggedString *luaS_collectudata (void)
}
void luaS_freeall (void)
{
void luaS_freeall (void) {
int i;
for (i=0; i<NUM_HASHS; i++) {
stringtable *tb = &L->string_root[i];
@@ -285,8 +273,7 @@ void luaS_freeall (void)
}
void luaS_rawsetglobal (TaggedString *ts, TObject *newval)
{
void luaS_rawsetglobal (TaggedString *ts, TObject *newval) {
ts->u.s.globalval = *newval;
if (ts->head.next == (GCnode *)ts) { /* is not in list? */
ts->head.next = L->rootglobal.next;
@@ -295,8 +282,7 @@ void luaS_rawsetglobal (TaggedString *ts, TObject *newval)
}
char *luaS_travsymbol (int (*fn)(TObject *))
{
char *luaS_travsymbol (int (*fn)(TObject *)) {
TaggedString *g;
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
if (fn(&g->u.s.globalval))
@@ -305,8 +291,7 @@ char *luaS_travsymbol (int (*fn)(TObject *))
}
int luaS_globaldefined (char *name)
{
int luaS_globaldefined (char *name) {
TaggedString *ts = luaS_new(name);
return ts->u.s.globalval.ttype != LUA_T_NIL;
}

407
lstrlib.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lstrlib.c,v 1.17 1998/06/29 18:24:06 roberto Exp roberto $
** $Id: lstrlib.c,v 1.31 1999/05/14 12:24:04 roberto Exp roberto $
** Standard library for strings and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -32,33 +32,31 @@ static void str_len (void)
}
static void closeandpush (void)
{
static void closeandpush (void) {
lua_pushlstring(luaL_buffer(), luaL_getsize());
}
static long posrelat (long pos, long len)
{
static long posrelat (long pos, long len) {
/* relative string position: negative means back from end */
return (pos>=0) ? pos : len+pos+1;
}
static void str_sub (void)
{
static void str_sub (void) {
long l;
char *s = luaL_check_lstr(1, &l);
long start = posrelat(luaL_check_number(2), l);
long end = posrelat(luaL_opt_number(3, -1), l);
if (1 <= start && start <= end && end <= l)
long start = posrelat(luaL_check_long(2), l);
long end = posrelat(luaL_opt_long(3, -1), l);
if (start < 1) start = 1;
if (end > l) end = l;
if (start <= end)
lua_pushlstring(s+start-1, end-start+1);
else lua_pushstring("");
}
static void str_lower (void)
{
static void str_lower (void) {
long l;
int i;
char *s = luaL_check_lstr(1, &l);
@@ -69,8 +67,7 @@ static void str_lower (void)
}
static void str_upper (void)
{
static void str_upper (void) {
long l;
int i;
char *s = luaL_check_lstr(1, &l);
@@ -84,7 +81,7 @@ static void str_rep (void)
{
long l;
char *s = luaL_check_lstr(1, &l);
int n = (int)luaL_check_number(2);
int n = luaL_check_int(2);
luaL_resetbuffer();
while (n-- > 0)
addnchar(s, l);
@@ -92,38 +89,42 @@ static void str_rep (void)
}
static void str_byte (void)
{
static void str_byte (void) {
long l;
char *s = luaL_check_lstr(1, &l);
long pos = posrelat(luaL_opt_number(2, 1), l);
long pos = posrelat(luaL_opt_long(2, 1), l);
luaL_arg_check(0<pos && pos<=l, 2, "out of range");
lua_pushnumber((unsigned char)s[pos-1]);
}
static void str_char (void) {
int i = 0;
luaL_resetbuffer();
while (lua_getparam(++i) != LUA_NOOBJECT) {
double c = luaL_check_number(i);
luaL_arg_check((unsigned char)c == c, i, "invalid value");
luaL_addchar((int)c);
luaL_addchar((unsigned char)c);
}
closeandpush();
}
/*
** =======================================================
** {======================================================
** PATTERN MATCHING
** =======================================================
*/
#define MAX_CAPT 9
#ifndef MAX_CAPT
#define MAX_CAPT 32 /* arbitrary limit */
#endif
struct Capture {
int level; /* total number of captures (finished or unfinished) */
char *src_end; /* end ('\0') of source string */
int level; /* total number of captures (finished or unfinished) */
struct {
char *init;
int len; /* -1 signals unfinished capture */
@@ -132,19 +133,20 @@ struct Capture {
#define ESC '%'
#define SPECIALS "^$*?.([%-"
#define SPECIALS "^$*+?.([%-"
static void push_captures (struct Capture *cap)
{
static void push_captures (struct Capture *cap) {
int i;
for (i=0; i<cap->level; i++)
lua_pushlstring(cap->capture[i].init, cap->capture[i].len);
for (i=0; i<cap->level; i++) {
int l = cap->capture[i].len;
if (l == -1) lua_error("unfinished capture");
lua_pushlstring(cap->capture[i].init, l);
}
}
static int check_cap (int l, struct Capture *cap)
{
static int check_cap (int l, struct Capture *cap) {
l -= '1';
if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
lua_error("invalid capture index");
@@ -152,8 +154,7 @@ static int check_cap (int l, struct Capture *cap)
}
static int capture_to_close (struct Capture *cap)
{
static int capture_to_close (struct Capture *cap) {
int level = cap->level;
for (level--; level>=0; level--)
if (cap->capture[level].len == -1) return level;
@@ -162,14 +163,25 @@ static int capture_to_close (struct Capture *cap)
}
static char *bracket_end (char *p)
{
return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']');
char *luaI_classend (char *p) {
switch (*p++) {
case ESC:
if (*p == '\0')
luaL_verror("incorrect pattern (ends with `%c')", ESC);
return p+1;
case '[':
if (*p == '^') p++;
if (*p == ']') p++;
p = strchr(p, ']');
if (!p) lua_error("incorrect pattern (missing `]')");
return p+1;
default:
return p;
}
}
static int matchclass (int c, int cl)
{
static int matchclass (int c, int cl) {
int res;
switch (tolower(cl)) {
case 'a' : res = isalpha(c); break;
@@ -180,57 +192,63 @@ static int matchclass (int c, int cl)
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((unsigned char)cl) ? res : !res);
return (islower(cl) ? res : !res);
}
int luaI_singlematch (int c, char *p, char **ep)
{
static int matchbracketclass (int c, char *p, char *end) {
int sig = 1;
if (*(p+1) == '^') {
sig = 0;
p++; /* skip the '^' */
}
while (++p < end) {
if (*p == ESC) {
p++;
if ((p < end) && matchclass(c, (unsigned char)*p))
return sig;
}
else if ((*(p+1) == '-') && (p+2 < end)) {
p+=2;
if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p)
return sig;
}
else if ((unsigned char)*p == c) return sig;
}
return !sig;
}
int luaI_singlematch (int c, char *p, char *ep) {
switch (*p) {
case '.': /* matches any char */
*ep = p+1;
return 1;
case '\0': /* end of pattern; matches nothing */
*ep = p;
return 0;
case ESC:
if (*(++p) == '\0')
luaL_verror("incorrect pattern (ends with `%c')", ESC);
*ep = p+1;
return matchclass(c, (unsigned char)*p);
case '[': {
char *end = bracket_end(p+1);
int sig = *(p+1) == '^' ? (p++, 0) : 1;
if (end == NULL) lua_error("incorrect pattern (missing `]')");
*ep = end+1;
while (++p < end) {
if (*p == ESC) {
if (((p+1) < end) && matchclass(c, (unsigned char)*++p))
return sig;
}
else if ((*(p+1) == '-') && (p+2 < end)) {
p+=2;
if ((unsigned char)*(p-2) <= c && c <= (unsigned char)*p)
return sig;
}
else if ((unsigned char)*p == c) return sig;
}
return !sig;
}
return matchclass(c, (unsigned char)*(p+1));
case '[':
return matchbracketclass(c, p, ep-1);
default:
*ep = p+1;
return ((unsigned char)*p == c);
}
}
static char *matchbalance (char *s, int b, int e, struct Capture *cap)
{
if (*s != b) return NULL;
static char *match (char *s, char *p, struct Capture *cap);
static char *matchbalance (char *s, char *p, struct Capture *cap) {
if (*p == 0 || *(p+1) == 0)
lua_error("unbalanced pattern");
if (*s != *p) return NULL;
else {
int b = *p;
int e = *(p+1);
int cont = 1;
while (++s < cap->src_end) {
if (*s == e) {
@@ -243,101 +261,120 @@ static char *matchbalance (char *s, int b, int e, struct Capture *cap)
}
static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
{
if (*p == ESC) {
p++;
if (isdigit((unsigned char)*p)) { /* capture */
int l = check_cap(*p, cap);
int len = cap->capture[l].len;
*ep = p+1;
if (cap->src_end-s >= len && memcmp(cap->capture[l].init, s, len) == 0)
return s+len;
else return NULL;
}
else if (*p == 'b') { /* balanced string */
p++;
if (*p == 0 || *(p+1) == 0)
lua_error("unbalanced pattern");
*ep = p+2;
return matchbalance(s, *p, *(p+1), cap);
}
else p--; /* and go through */
static char *max_expand (char *s, char *p, char *ep, struct Capture *cap) {
int i = 0; /* counts maximum expand for item */
while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep))
i++;
/* keeps trying to match mith the maximum repetitions */
while (i>=0) {
char *res = match((s+i), ep+1, cap);
if (res) return res;
i--; /* else didn't match; reduce 1 repetition to try again */
}
/* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */
return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ?
s+1 : NULL;
return NULL;
}
static char *match (char *s, char *p, struct Capture *cap)
{
static char *min_expand (char *s, char *p, char *ep, struct Capture *cap) {
for (;;) {
char *res = match(s, ep+1, cap);
if (res != NULL)
return res;
else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep))
s++; /* try with one more repetition */
else return NULL;
}
}
static char *start_capt (char *s, char *p, struct Capture *cap) {
char *res;
int level = cap->level;
if (level >= MAX_CAPT) lua_error("too many captures");
cap->capture[level].init = s;
cap->capture[level].len = -1;
cap->level = level+1;
if ((res=match(s, p+1, cap)) == NULL) /* match failed? */
cap->level--; /* undo capture */
return res;
}
static char *end_capt (char *s, char *p, struct Capture *cap) {
int l = capture_to_close(cap);
char *res;
cap->capture[l].len = s - cap->capture[l].init; /* close capture */
if ((res = match(s, p+1, cap)) == NULL) /* match failed? */
cap->capture[l].len = -1; /* undo capture */
return res;
}
static char *match_capture (char *s, int level, struct Capture *cap) {
int l = check_cap(level, cap);
int len = cap->capture[l].len;
if (cap->src_end-s >= len &&
memcmp(cap->capture[l].init, s, len) == 0)
return s+len;
else return NULL;
}
static char *match (char *s, char *p, struct Capture *cap) {
init: /* using goto's to optimize tail recursion */
switch (*p) {
case '(': { /* start capture */
char *res;
if (cap->level >= MAX_CAPT) lua_error("too many captures");
cap->capture[cap->level].init = s;
cap->capture[cap->level].len = -1;
cap->level++;
if ((res=match(s, p+1, cap)) == NULL) /* match failed? */
cap->level--; /* undo capture */
return res;
}
case ')': { /* end capture */
int l = capture_to_close(cap);
char *res;
cap->capture[l].len = s - cap->capture[l].init; /* close capture */
if ((res = match(s, p+1, cap)) == NULL) /* match failed? */
cap->capture[l].len = -1; /* undo capture */
return res;
}
case '\0': case '$': /* (possibly) end of pattern */
if (*p == 0 || (*(p+1) == 0 && s == cap->src_end))
return s;
/* else go through */
default: { /* it is a pattern item */
char *ep; /* get what is next */
char *s1 = matchitem(s, p, cap, &ep);
case '(': /* start capture */
return start_capt(s, p, cap);
case ')': /* end capture */
return end_capt(s, p, cap);
case ESC: /* may be %[0-9] or %b */
if (isdigit((unsigned char)(*(p+1)))) { /* capture? */
s = match_capture(s, *(p+1), cap);
if (s == NULL) return NULL;
p+=2; goto init; /* else return match(p+2, s, cap) */
}
else if (*(p+1) == 'b') { /* balanced string? */
s = matchbalance(s, p+2, cap);
if (s == NULL) return NULL;
p+=4; goto init; /* else return match(p+4, s, cap); */
}
else 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 == cap->src_end) ? s : NULL; /* check end of string */
else goto dflt;
default: dflt: { /* it is a pattern item */
char *ep = luaI_classend(p); /* points to what is next */
int m = s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep);
switch (*ep) {
case '*': { /* repetition */
char *res;
if (s1 && s1>s && ((res=match(s1, p, cap)) != NULL))
return res;
p=ep+1; goto init; /* else return match(s, ep+1, cap); */
}
case '?': { /* optional */
char *res;
if (s1 && ((res=match(s1, ep+1, cap)) != NULL))
if (m && ((res=match(s+1, ep+1, cap)) != NULL))
return res;
p=ep+1; goto init; /* else return match(s, ep+1, cap); */
}
case '-': { /* repetition */
char *res;
if ((res = match(s, ep+1, cap)) != NULL)
return res;
else if (s1 && s1>s) {
s = s1;
goto init; /* return match(s1, p, cap); */
}
else
return NULL;
}
case '*': /* 0 or more repetitions */
return max_expand(s, p, ep, cap);
case '+': /* 1 or more repetitions */
return (m ? max_expand(s+1, p, ep, cap) : NULL);
case '-': /* 0 or more repetitions (minimum) */
return min_expand(s, p, ep, cap);
default:
if (s1) { s=s1; p=ep; goto init; } /* return match(s1, ep, cap); */
else return NULL;
if (!m) return NULL;
s++; p=ep; goto init; /* else return match(s+1, ep, cap); */
}
}
}
}
static void str_find (void)
{
static void str_find (void) {
long l;
char *s = luaL_check_lstr(1, &l);
char *p = luaL_check_string(2);
long init = posrelat(luaL_opt_number(3, 1), l) - 1;
long init = posrelat(luaL_opt_long(3, 1), l) - 1;
struct Capture cap;
luaL_arg_check(0 <= init && init <= l, 3, "out of range");
if (lua_getparam(4) != LUA_NOOBJECT ||
@@ -368,8 +405,7 @@ static void str_find (void)
}
static void add_s (lua_Object newp, struct Capture *cap)
{
static void add_s (lua_Object newp, struct Capture *cap) {
if (lua_isstring(newp)) {
char *news = lua_getstring(newp);
int l = lua_strlen(newp);
@@ -411,13 +447,12 @@ static void add_s (lua_Object newp, struct Capture *cap)
}
static void str_gsub (void)
{
static void str_gsub (void) {
long srcl;
char *src = luaL_check_lstr(1, &srcl);
char *p = luaL_check_string(2);
lua_Object newp = lua_getparam(3);
int max_s = (int)luaL_opt_number(4, srcl+1);
int max_s = luaL_opt_int(4, srcl+1);
int anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0;
struct Capture cap;
@@ -445,26 +480,33 @@ static void str_gsub (void)
lua_pushnumber(n); /* number of substitutions */
}
/* }====================================================== */
static void luaI_addquoted (char *s)
{
static void luaI_addquoted (int arg) {
long l;
char *s = luaL_check_lstr(arg, &l);
luaL_addchar('"');
for (; *s; s++) {
if (strchr("\"\\\n", *s))
luaL_addchar('\\');
luaL_addchar(*s);
while (l--) {
switch (*s) {
case '"': case '\\': case '\n':
luaL_addchar('\\');
luaL_addchar(*s);
break;
case '\0': addnchar("\\000", 4); break;
default: luaL_addchar(*s);
}
s++;
}
luaL_addchar('"');
}
#define MAX_FORMAT 200
/* maximum size of each format specification (such as '%-099.99d') */
#define MAX_FORMAT 20 /* arbitrary limit */
static void str_format (void)
{
static void str_format (void) {
int arg = 1;
char *strfrmt = luaL_check_string(arg);
struct Capture cap;
cap.src_end = strfrmt+strlen(strfrmt)+1;
luaL_resetbuffer();
while (*strfrmt) {
if (*strfrmt != '%')
@@ -472,34 +514,28 @@ static void str_format (void)
else if (*++strfrmt == '%')
luaL_addchar(*strfrmt++); /* %% */
else { /* format item */
char form[MAX_FORMAT]; /* store the format ('%...') */
char *buff;
struct Capture cap;
char form[MAX_FORMAT]; /* to store the format ('%...') */
char *buff; /* to store the formatted item */
char *initf = strfrmt;
form[0] = '%';
cap.level = 0;
if (isdigit((unsigned char)initf[0]) && initf[1] == '$') {
arg = initf[0] - '0';
if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
arg = *initf - '0';
initf += 2; /* skip the 'n$' */
}
arg++;
cap.src_end = strfrmt+strlen(strfrmt)+1;
cap.level = 0;
strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
if (cap.capture[0].len > 2 || cap.capture[1].len > 2) /* < 100? */
if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
strfrmt-initf > MAX_FORMAT-2)
lua_error("invalid format (width or precision too long)");
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
form[strfrmt-initf+2] = 0;
buff = luaL_openspace(1000); /* to store the formatted value */
buff = luaL_openspace(512); /* 512 > soid luaI_addquot99.99f', -1e308) */
switch (*strfrmt++) {
case 'q':
luaI_addquoted(luaL_check_string(arg));
continue;
case 's': {
char *s = luaL_check_string(arg);
buff = luaL_openspace(strlen(s));
sprintf(buff, form, s);
break;
}
case 'c': case 'd': case 'i':
sprintf(buff, form, (int)luaL_check_number(arg));
sprintf(buff, form, luaL_check_int(arg));
break;
case 'o': case 'u': case 'x': case 'X':
sprintf(buff, form, (unsigned int)luaL_check_number(arg));
@@ -507,6 +543,23 @@ static void str_format (void)
case 'e': case 'E': case 'f': case 'g': case 'G':
sprintf(buff, form, luaL_check_number(arg));
break;
case 'q':
luaI_addquoted(arg);
continue; /* skip the "addsize" at the end */
case 's': {
long l;
char *s = luaL_check_lstr(arg, &l);
if (cap.capture[1].len == 0 && l >= 100) {
/* no precision and string is too big to be formatted;
keep original string */
addnchar(s, l);
continue; /* skip the "addsize" at the end */
}
else {
sprintf(buff, form, s);
break;
}
}
default: /* also treat cases 'pnLlh' */
lua_error("invalid option in `format'");
}
@@ -524,7 +577,7 @@ static struct luaL_reg strlib[] = {
{"strupper", str_upper},
{"strchar", str_char},
{"strrep", str_rep},
{"ascii", str_byte}, /* for compatibility */
{"ascii", str_byte}, /* for compatibility with 3.0 and earlier */
{"strbyte", str_byte},
{"format", str_format},
{"strfind", str_find},

183
ltable.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltable.c,v 1.11 1998/01/13 18:06:27 roberto Exp roberto $
** $Id: ltable.c,v 1.21 1999/02/23 14:57:28 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -20,14 +20,11 @@
#define nodevector(t) ((t)->node)
#define REHASH_LIMIT 0.70 /* avoid more than this % full */
#define TagDefault LUA_T_ARRAY;
static long int hashindex (TObject *ref)
{
static long int hashindex (TObject *ref) {
long int h;
switch (ttype(ref)) {
case LUA_T_NUMBER:
@@ -56,61 +53,45 @@ static long int hashindex (TObject *ref)
}
static int present (Hash *t, TObject *key)
{
Node *luaH_present (Hash *t, TObject *key) {
int tsize = nhash(t);
long int h = hashindex(key);
int h1 = h%tsize;
TObject *rf = ref(node(t, h1));
if (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf)) {
int h2 = h%(tsize-2) + 1;
do {
h1 += h2;
if (h1 >= tsize) h1 -= tsize;
rf = ref(node(t, h1));
} while (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf));
Node *n = node(t, h1);
/* keep looking until an entry with "ref" equal to key or nil */
while ((ttype(ref(n)) == ttype(key)) ? !luaO_equalval(key, ref(n))
: ttype(ref(n)) != LUA_T_NIL) {
h1 += (h&(tsize-2)) + 1; /* double hashing */
if (h1 >= tsize) h1 -= tsize;
n = node(t, h1);
}
return h1;
return n;
}
/*
** Alloc a vector node
*/
static Node *hashnodecreate (int nhash)
{
Node *v = luaM_newvector(nhash, Node);
int i;
for (i=0; i<nhash; i++)
ttype(ref(&v[i])) = LUA_T_NIL;
return v;
}
/*
** Delete a hash
*/
static void hashdelete (Hash *t)
{
luaM_free(nodevector(t));
luaM_free(t);
}
void luaH_free (Hash *frees)
{
void luaH_free (Hash *frees) {
while (frees) {
Hash *next = (Hash *)frees->head.next;
L->nblocks -= gcsize(frees->nhash);
hashdelete(frees);
luaM_free(nodevector(frees));
luaM_free(frees);
frees = next;
}
}
Hash *luaH_new (int nhash)
{
static Node *hashnodecreate (int nhash) {
Node *v = luaM_newvector(nhash, Node);
int i;
for (i=0; i<nhash; i++)
ttype(ref(&v[i])) = ttype(val(&v[i])) = LUA_T_NIL;
return v;
}
Hash *luaH_new (int nhash) {
Hash *t = luaM_new(Hash);
nhash = luaO_redimension((int)((float)nhash/REHASH_LIMIT));
nhash = luaO_redimension(nhash*3/2);
nodevector(t) = hashnodecreate(nhash);
nhash(t) = nhash;
nuse(t) = 0;
@@ -121,96 +102,76 @@ Hash *luaH_new (int nhash)
}
static int newsize (Hash *t)
{
static int newsize (Hash *t) {
Node *v = t->node;
int size = nhash(t);
int realuse = 0;
int i;
for (i=0; i<size; i++) {
if (ttype(ref(v+i)) != LUA_T_NIL && ttype(val(v+i)) != LUA_T_NIL)
if (ttype(val(v+i)) != LUA_T_NIL)
realuse++;
}
if (2*(realuse+1) <= size) /* +1 is the new element */
return size; /* don't need to grow, just rehash */
else
return luaO_redimension(size);
return luaO_redimension((realuse+1)*2); /* +1 is the new element */
}
static void rehash (Hash *t)
{
static void rehash (Hash *t) {
int nold = nhash(t);
Node *vold = nodevector(t);
int nnew = newsize(t);
int i;
nodevector(t) = hashnodecreate(nnew);
nhash(t) = nnew;
nuse(t) = 0;
for (i=0; i<nold; i++) {
Node *n = vold+i;
if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL)
*node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */
if (ttype(val(n)) != LUA_T_NIL) {
*luaH_present(t, ref(n)) = *n; /* copy old node to new hash */
nuse(t)++;
}
}
L->nblocks += gcsize(nnew)-gcsize(nold);
luaM_free(vold);
}
/*
** If the hash node is present, return its pointer, otherwise return
** null.
*/
TObject *luaH_get (Hash *t, TObject *ref)
{
int h = present(t, ref);
if (ttype(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h));
else return NULL;
}
/*
** If the hash node is present, return its pointer, otherwise create a luaM_new
** node for the given reference and also return its pointer.
*/
TObject *luaH_set (Hash *t, TObject *ref)
{
Node *n = node(t, present(t, ref));
if (ttype(ref(n)) == LUA_T_NIL) {
nuse(t)++;
if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT) {
rehash(t);
n = node(t, present(t, ref));
}
*ref(n) = *ref;
ttype(val(n)) = LUA_T_NIL;
}
return (val(n));
}
static Node *hashnext (Hash *t, int i)
{
Node *n;
int tsize = nhash(t);
if (i >= tsize)
return NULL;
n = node(t, i);
while (ttype(ref(n)) == LUA_T_NIL || ttype(val(n)) == LUA_T_NIL) {
if (++i >= tsize)
return NULL;
n = node(t, i);
}
return node(t, i);
}
Node *luaH_next (TObject *o, TObject *r)
{
Hash *t = avalue(o);
if (ttype(r) == LUA_T_NIL)
return hashnext(t, 0);
void luaH_set (Hash *t, TObject *ref, TObject *val) {
Node *n = luaH_present(t, ref);
if (ttype(ref(n)) != LUA_T_NIL)
*val(n) = *val;
else {
int i = present(t, r);
Node *n = node(t, i);
luaL_arg_check(ttype(ref(n))!=LUA_T_NIL && ttype(val(n))!=LUA_T_NIL,
2, "key not found");
return hashnext(t, i+1);
TObject buff;
buff = *val; /* rehash may invalidate this address */
if ((long)nuse(t)*3L > (long)nhash(t)*2L) {
rehash(t);
n = luaH_present(t, ref);
}
nuse(t)++;
*ref(n) = *ref;
*val(n) = buff;
}
}
int luaH_pos (Hash *t, TObject *r) {
Node *n = luaH_present(t, r);
luaL_arg_check(ttype(val(n)) != LUA_T_NIL, 2, "key not found");
return n-(t->node);
}
void luaH_setint (Hash *t, int ref, TObject *val) {
TObject index;
ttype(&index) = LUA_T_NUMBER;
nvalue(&index) = ref;
luaH_set(t, &index, val);
}
TObject *luaH_getint (Hash *t, int ref) {
TObject index;
ttype(&index) = LUA_T_NUMBER;
nvalue(&index) = ref;
return luaH_get(t, &index);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltable.h,v 1.4 1997/11/19 17:29:23 roberto Exp roberto $
** $Id: ltable.h,v 1.10 1999/01/25 17:40:10 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -15,10 +15,16 @@
#define val(n) (&(n)->val)
#define nhash(t) ((t)->nhash)
#define luaH_get(t,ref) (val(luaH_present((t), (ref))))
#define luaH_move(t,from,to) (luaH_setint(t, to, luaH_getint(t, from)))
Hash *luaH_new (int nhash);
void luaH_free (Hash *frees);
TObject *luaH_get (Hash *t, TObject *ref);
TObject *luaH_set (Hash *t, TObject *ref);
Node *luaH_next (TObject *o, TObject *r);
Node *luaH_present (Hash *t, TObject *key);
void luaH_set (Hash *t, TObject *ref, TObject *val);
int luaH_pos (Hash *t, TObject *r);
void luaH_setint (Hash *t, int ref, TObject *val);
TObject *luaH_getint (Hash *t, int ref);
#endif

91
ltm.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.c,v 1.15 1998/03/11 13:59:50 roberto Exp roberto $
** $Id: ltm.c,v 1.24 1999/02/26 15:48:55 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -22,8 +22,7 @@ char *luaT_eventname[] = { /* ORDER IM */
};
static int luaI_checkevent (char *name, char *list[])
{
static int luaI_checkevent (char *name, char *list[]) {
int e = luaL_findstring(name, list);
if (e < 0)
luaL_verror("`%.50s' is not a valid event name", name);
@@ -35,7 +34,7 @@ static int luaI_checkevent (char *name, char *list[])
/* events in LUA_T_NIL are all allowed, since this is used as a
* 'placeholder' for "default" fallbacks
*/
static char validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */
static char luaT_validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */
{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
@@ -45,71 +44,59 @@ static char validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
};
static int validevent (int t, int e)
{ /* ORDER LUA_T */
return (t < LUA_T_NIL) ? 1 : validevents[-t][e];
static int luaT_validevent (int t, int e) { /* ORDER LUA_T */
return (t < LUA_T_NIL) ? 1 : luaT_validevents[-t][e];
}
static void init_entry (int tag)
{
static void init_entry (int tag) {
int i;
for (i=0; i<IM_N; i++)
ttype(luaT_getim(tag, i)) = LUA_T_NIL;
}
void luaT_init (void)
{
void luaT_init (void) {
int t;
L->IMtable_size = NUM_TAGS*2;
L->last_tag = -(NUM_TAGS-1);
L->IMtable = luaM_newvector(L->IMtable_size, struct IM);
luaM_growvector(L->IMtable, 0, NUM_TAGS, struct IM, arrEM, MAX_INT);
for (t=L->last_tag; t<=0; t++)
init_entry(t);
}
int lua_newtag (void)
{
int lua_newtag (void) {
--L->last_tag;
if ((-L->last_tag) >= L->IMtable_size)
L->IMtable_size = luaM_growvector(&L->IMtable, L->IMtable_size,
struct IM, memEM, MAX_INT);
luaM_growvector(L->IMtable, -(L->last_tag), 1, struct IM, arrEM, MAX_INT);
init_entry(L->last_tag);
return L->last_tag;
}
static void checktag (int tag)
{
static void checktag (int tag) {
if (!(L->last_tag <= tag && tag <= 0))
luaL_verror("%d is not a valid tag", tag);
}
void luaT_realtag (int tag)
{
void luaT_realtag (int tag) {
if (!(L->last_tag <= tag && tag < LUA_T_NIL))
luaL_verror("tag %d is not result of `newtag'", tag);
luaL_verror("tag %d was not created by `newtag'", tag);
}
int lua_copytagmethods (int tagto, int tagfrom)
{
int lua_copytagmethods (int tagto, int tagfrom) {
int e;
checktag(tagto);
checktag(tagfrom);
for (e=0; e<IM_N; e++) {
if (validevent(tagto, e))
if (luaT_validevent(tagto, e))
*luaT_getim(tagto, e) = *luaT_getim(tagfrom, e);
}
return tagto;
}
int luaT_efectivetag (TObject *o)
{
int luaT_effectivetag (TObject *o) {
int t;
switch (t = ttype(o)) {
case LUA_T_ARRAY:
@@ -131,36 +118,34 @@ int luaT_efectivetag (TObject *o)
}
TObject *luaT_gettagmethod (int t, char *event)
{
TObject *luaT_gettagmethod (int t, char *event) {
int e = luaI_checkevent(event, luaT_eventname);
checktag(t);
if (validevent(t, e))
if (luaT_validevent(t, e))
return luaT_getim(t,e);
else
return &luaO_nilobject;
}
void luaT_settagmethod (int t, char *event, TObject *func)
{
TObject temp = *func;
void luaT_settagmethod (int t, char *event, TObject *func) {
TObject temp;
int e = luaI_checkevent(event, luaT_eventname);
checktag(t);
if (!validevent(t, e))
luaL_verror("settagmethod: cannot change tag method `%.20s' for tag %d",
luaT_eventname[e], t);
if (!luaT_validevent(t, e))
luaL_verror("cannot change tag method `%.20s' for type `%.20s'%.20s",
luaT_eventname[e], luaO_typenames[-t],
(t == LUA_T_ARRAY || t == LUA_T_USERDATA) ? " with default tag"
: "");
temp = *func;
*func = *luaT_getim(t,e);
*luaT_getim(t, e) = temp;
}
char *luaT_travtagmethods (int (*fn)(TObject *))
{
char *luaT_travtagmethods (int (*fn)(TObject *)) { /* ORDER IM */
int e;
if (fn(&L->errorim))
return "error";
for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { /* ORDER IM */
for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) {
int t;
for (t=0; t>=L->last_tag; t--)
if (fn(luaT_getim(t,e)))
@@ -177,6 +162,7 @@ char *luaT_travtagmethods (int (*fn)(TObject *))
#ifdef LUA_COMPAT2_5
#include "lapi.h"
#include "lstring.h"
static void errorFB (void)
{
@@ -191,23 +177,20 @@ static void errorFB (void)
static void nilFB (void) { }
static void typeFB (void)
{
static void typeFB (void) {
lua_error("unexpected type");
}
static void fillvalids (IMS e, TObject *func)
{
static void fillvalids (IMS e, TObject *func) {
int t;
for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
if (validevent(t, e))
if (luaT_validevent(t, e))
*luaT_getim(t, e) = *func;
}
void luaT_setfallback (void)
{
void luaT_setfallback (void) {
static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL};
TObject oldfunc;
lua_CFunction replace;
@@ -215,11 +198,13 @@ void luaT_setfallback (void)
lua_Object func = lua_getparam(2);
luaL_arg_check(lua_isfunction(func), 2, "function expected");
switch (luaL_findstring(name, oldnames)) {
case 0: /* old error fallback */
oldfunc = L->errorim;
L->errorim = *luaA_Address(func);
case 0: { /* old error fallback */
TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
oldfunc = *em;
*em = *luaA_Address(func);
replace = errorFB;
break;
}
case 1: /* old getglobal fallback */
oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL);
*luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func);

6
ltm.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.h,v 1.3 1997/11/19 17:29:23 roberto Exp roberto $
** $Id: ltm.h,v 1.4 1997/11/26 18:53:45 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -45,14 +45,14 @@ struct IM {
#define luaT_getim(tag,event) (&L->IMtable[-(tag)].int_method[event])
#define luaT_getimbyObj(o,e) (luaT_getim(luaT_efectivetag(o),(e)))
#define luaT_getimbyObj(o,e) (luaT_getim(luaT_effectivetag(o),(e)))
extern char *luaT_eventname[];
void luaT_init (void);
void luaT_realtag (int tag);
int luaT_efectivetag (TObject *o);
int luaT_effectivetag (TObject *o);
void luaT_settagmethod (int t, char *event, TObject *func);
TObject *luaT_gettagmethod (int t, char *event);
char *luaT_travtagmethods (int (*fn)(TObject *));

64
lua.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.c,v 1.13 1998/01/19 19:49:49 roberto Exp roberto $
** $Id: lua.c,v 1.20 1999/06/24 19:42:02 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -15,12 +15,6 @@
#include "lualib.h"
#ifndef OLD_ANSI
#include <locale.h>
#else
#define setlocale(a,b) 0
#endif
#ifdef _POSIX_SOURCE
#include <unistd.h>
#else
@@ -32,27 +26,33 @@ typedef void (*handler)(int); /* type for signal actions */
static void laction (int i);
static handler lreset (void)
{
lua_linehook = NULL;
lua_callhook = NULL;
static lua_LHFunction old_linehook = NULL;
static lua_CHFunction old_callhook = NULL;
static handler lreset (void) {
return signal(SIGINT, laction);
}
static void lstop (void)
{
static void lstop (void) {
lua_setlinehook(old_linehook);
lua_setcallhook(old_callhook);
lreset();
lua_error("interrupted!");
}
static void laction (int i)
{
lua_linehook = (lua_LHFunction)lstop;
lua_callhook = (lua_CHFunction)lstop;
static void laction (int i) {
signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop,
terminate process (default action) */
old_linehook = lua_setlinehook((lua_LHFunction)lstop);
old_callhook = lua_setcallhook((lua_CHFunction)lstop);
}
static int ldo (int (*f)(char *), char *name)
{
static int ldo (int (*f)(char *), char *name) {
int res;
handler h = lreset();
res = f(name); /* dostring | dofile */
@@ -61,8 +61,7 @@ static int ldo (int (*f)(char *), char *name)
}
static void print_message (void)
{
static void print_message (void) {
fprintf(stderr,
"Lua: command line options:\n"
" -v print version information\n"
@@ -76,8 +75,7 @@ static void print_message (void)
}
static void assign (char *arg)
{
static void assign (char *arg) {
if (strlen(arg) >= 500)
fprintf(stderr, "lua: shell argument too long");
else {
@@ -90,13 +88,11 @@ static void assign (char *arg)
}
}
#define BUF_SIZE 512
static void manual_input (int prompt)
{
static void manual_input (int prompt) {
int cont = 1;
while (cont) {
char buffer[BUF_SIZE];
char buffer[BUFSIZ];
int i = 0;
lua_beginblock();
if (prompt)
@@ -112,13 +108,13 @@ static void manual_input (int prompt)
buffer[i-1] = '\n';
else break;
}
else if (i >= BUF_SIZE-1) {
else if (i >= BUFSIZ-1) {
fprintf(stderr, "lua: argument line too long\n");
break;
}
else buffer[i++] = c;
else buffer[i++] = (char)c;
}
buffer[i] = 0;
buffer[i] = '\0';
ldo(lua_dostring, buffer);
lua_endblock();
}
@@ -129,11 +125,9 @@ static void manual_input (int prompt)
int main (int argc, char *argv[])
{
int i;
setlocale(LC_ALL, "");
lua_iolibopen();
lua_strlibopen();
lua_mathlibopen();
lua_open();
lua_pushstring("> "); lua_setglobal("_PROMPT");
lua_userinit();
if (argc < 2) { /* no arguments? */
if (isatty(0)) {
printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT);
@@ -155,7 +149,7 @@ int main (int argc, char *argv[])
manual_input(0);
break;
case 'd':
lua_debug = 1;
lua_setdebug(1);
break;
case 'v':
printf("%s %s\n(written by %s)\n\n",

29
lua.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.22 1998/06/15 21:34:14 roberto Exp roberto $
** $Id: lua.h,v 1.31 1999/04/15 12:33:19 roberto Exp roberto $
** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: lua@tecgraf.puc-rio.br
@@ -11,8 +11,8 @@
#ifndef lua_h
#define lua_h
#define LUA_VERSION "Lua 3.1"
#define LUA_COPYRIGHT "Copyright (C) 1994-1998 TeCGraf, PUC-Rio"
#define LUA_VERSION "Lua 3.2"
#define LUA_COPYRIGHT "Copyright (C) 1994-1999 TeCGraf, PUC-Rio"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
@@ -20,19 +20,18 @@
#define LUA_ANYTAG (-1)
typedef void (*lua_CFunction) (void);
typedef unsigned int lua_Object;
typedef struct lua_State lua_State;
extern lua_State *lua_state;
typedef void (*lua_CFunction) (void);
typedef unsigned int lua_Object;
void lua_open (void);
void lua_close (void);
lua_State *lua_setstate (lua_State *st);
lua_Object lua_settagmethod (int tag, char *event); /* In: new method */
lua_Object lua_gettagmethod (int tag, char *event);
lua_Object lua_seterrormethod (void); /* In: new method */
int lua_newtag (void);
int lua_copytagmethods (int tagto, int tagfrom);
@@ -90,6 +89,9 @@ lua_Object lua_rawgettable (void); /* In: table, index */
int lua_tag (lua_Object object);
char *lua_nextvar (char *varname); /* Out: value */
int lua_next (lua_Object o, int i);
/* Out: ref, value */
int lua_ref (int lock); /* In: value */
lua_Object lua_getref (int ref);
@@ -101,29 +103,23 @@ long lua_collectgarbage (long limit);
/* =============================================================== */
/* some useful macros/derived functions */
/* some useful macros/functions */
int (lua_call) (char *name);
#define lua_call(name) lua_callfunction(lua_getglobal(name))
void (lua_pushref) (int ref);
#define lua_pushref(ref) lua_pushobject(lua_getref(ref))
int (lua_refobject) (lua_Object o, int l);
#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l))
void (lua_register) (char *n, lua_CFunction f);
#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n))
void (lua_pushuserdata) (void *u);
#define lua_pushuserdata(u) lua_pushusertag(u, 0)
void (lua_pushcfunction) (lua_CFunction f);
#define lua_pushcfunction(f) lua_pushcclosure(f, 0)
int (lua_clonetag) (int t);
#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t))
lua_Object lua_seterrormethod (void); /* In: new method */
/* ==========================================================================
** for compatibility with old versions. Avoid using these macros/functions
@@ -162,7 +158,7 @@ lua_Object lua_setfallback (char *event, lua_CFunction fallback);
/******************************************************************************
* Copyright (c) 1994-1998 TeCGraf, PUC-Rio. All rights reserved.
* Copyright (c) 1994-1999 TeCGraf, PUC-Rio. All rights reserved.
*
* Permission is hereby granted, without written agreement and without license
* or royalty fees, to use, copy, modify, and distribute this software and its
@@ -192,5 +188,6 @@ lua_Object lua_setfallback (char *event, lua_CFunction fallback);
* The Lua language and this implementation have been entirely designed and
* written by Waldemar Celes Filho, Roberto Ierusalimschy and
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
*
* This implementation contains no third-party code.
******************************************************************************/

View File

@@ -1,5 +1,5 @@
/*
** $Id: luadebug.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
** $Id: luadebug.h,v 1.5 1999/02/04 17:47:59 roberto Exp roberto $
** Debugging API
** See Copyright Notice in lua.h
*/
@@ -17,17 +17,18 @@ typedef void (*lua_LHFunction) (int line);
typedef void (*lua_CHFunction) (lua_Function func, char *file, int line);
lua_Function lua_stackedfunction (int level);
void lua_funcinfo (lua_Object func, char **filename, int *linedefined);
void lua_funcinfo (lua_Object func, char **source, int *linedefined);
int lua_currentline (lua_Function func);
char *lua_getobjname (lua_Object o, char **name);
lua_Object lua_getlocal (lua_Function func, int local_number, char **name);
int lua_setlocal (lua_Function func, int local_number);
int lua_nups (lua_Function func);
extern lua_LHFunction lua_linehook;
extern lua_CHFunction lua_callhook;
extern int lua_debug;
lua_LHFunction lua_setlinehook (lua_LHFunction func);
lua_CHFunction lua_setcallhook (lua_CHFunction func);
int lua_setdebug (int debug);
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lualib.h,v 1.3 1997/12/17 20:48:58 roberto Exp roberto $
** $Id: lualib.h,v 1.5 1999/01/08 16:47:44 roberto Exp roberto $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -10,12 +10,13 @@
#include "lua.h"
void lua_iolibopen (void);
void lua_strlibopen (void);
void lua_mathlibopen (void);
void lua_dblibopen (void);
void lua_userinit (void);
/* To keep compatibility with old versions */
@@ -28,7 +29,8 @@ void lua_mathlibopen (void);
/* Auxiliary functions (private) */
int luaI_singlematch (int c, char *p, char **ep);
char *luaI_classend (char *p);
int luaI_singlematch (int c, char *p, char *ep);
#endif

193
lundump.c
View File

@@ -1,105 +1,104 @@
/*
** $Id: lundump.c,v 1.10 1998/06/25 15:50:09 lhf Exp $
** $Id: lundump.c,v 1.21 1999/07/02 19:34:26 lhf Exp $
** load bytecodes from files
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <string.h>
#include "lauxlib.h"
#include "lfunc.h"
#include "lmem.h"
#include "lopcodes.h"
#include "lstring.h"
#include "lundump.h"
#define LoadBlock(b,size,Z) ezread(Z,b,size)
#define LoadNative(t,Z) LoadBlock(&t,sizeof(t),Z)
#if ID_NUMBER==ID_NATIVE
#define doLoadNumber(f,Z) LoadNative(f,Z)
#else
#define doLoadNumber(f,Z) f=LoadNumber(Z)
#endif
static void unexpectedEOZ(ZIO* Z)
static void unexpectedEOZ (ZIO* Z)
{
luaL_verror("unexpected end of file in %s",zname(Z));
}
static int ezgetc(ZIO* Z)
static int ezgetc (ZIO* Z)
{
int c=zgetc(Z);
if (c==EOZ) unexpectedEOZ(Z);
return c;
}
static void ezread(ZIO* Z, void* b, int n)
static void ezread (ZIO* Z, void* b, int n)
{
int r=zread(Z,b,n);
if (r!=0) unexpectedEOZ(Z);
}
static unsigned int LoadWord(ZIO* Z)
static unsigned int LoadWord (ZIO* Z)
{
unsigned int hi=ezgetc(Z);
unsigned int lo=ezgetc(Z);
return (hi<<8)|lo;
}
static unsigned long LoadLong(ZIO* Z)
static unsigned long LoadLong (ZIO* Z)
{
unsigned long hi=LoadWord(Z);
unsigned long lo=LoadWord(Z);
return (hi<<16)|lo;
}
#if ID_NUMBER==ID_REAL4
/* LUA_NUMBER */
/* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */
static float LoadFloat(ZIO* Z)
/*
* convert number from text
*/
double luaU_str2d (char* b, char* where)
{
int negative=(b[0]=='-');
double x=luaO_str2d(b+negative);
if (x<0) luaL_verror("cannot convert number '%s' in %s",b,where);
return negative ? -x : x;
}
static real LoadNumber (ZIO* Z, int native)
{
real x;
if (native)
{
LoadBlock(&x,sizeof(x),Z);
return x;
}
else
{
char b[256];
int size=ezgetc(Z);
LoadBlock(b,size,Z);
b[size]=0;
return luaU_str2d(b,zname(Z));
}
}
static int LoadInt (ZIO* Z, char* message)
{
unsigned long l=LoadLong(Z);
float f=*(float*)&l;
return f;
unsigned int i=l;
if (i!=l) luaL_verror(message,l,zname(Z));
return i;
}
#endif
#if ID_NUMBER==ID_REAL8
/* LUA_NUMBER */
/* assumes sizeof(long)==4 and sizeof(double)==8 (IEEE) */
static double LoadDouble(ZIO* Z)
{
unsigned long l[2];
double f;
int x=1;
if (*(char*)&x==1) /* little-endian */
{
l[1]=LoadLong(Z);
l[0]=LoadLong(Z);
}
else /* big-endian */
{
l[0]=LoadLong(Z);
l[1]=LoadLong(Z);
}
f=*(double*)l;
return f;
}
#endif
#define PAD 5 /* two word operands plus opcode */
static Byte* LoadCode(ZIO* Z)
static Byte* LoadCode (ZIO* Z)
{
unsigned long size=LoadLong(Z);
unsigned int s=size;
void* b;
if (s!=size) luaL_verror("code too long (%ld bytes) in %s",size,zname(Z));
b=luaM_malloc(size);
int size=LoadInt(Z,"code too long (%ld bytes) in %s");
Byte* b=luaM_malloc(size+PAD);
LoadBlock(b,size,Z);
if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z));
memset(b+size,ENDCODE,PAD); /* pad code for safety */
return b;
}
static TaggedString* LoadTString(ZIO* Z)
static TaggedString* LoadTString (ZIO* Z)
{
int size=LoadWord(Z);
long size=LoadLong(Z);
if (size==0)
return NULL;
else
@@ -110,65 +109,65 @@ static TaggedString* LoadTString(ZIO* Z)
}
}
static void LoadLocals(TProtoFunc* tf, ZIO* Z)
static void LoadLocals (TProtoFunc* tf, ZIO* Z)
{
int i,n=LoadWord(Z);
int i,n=LoadInt(Z,"too many locals (%ld) in %s");
if (n==0) return;
tf->locvars=luaM_newvector(n+1,LocVar);
for (i=0; i<n; i++)
{
tf->locvars[i].line=LoadWord(Z);
tf->locvars[i].line=LoadInt(Z,"too many lines (%ld) in %s");
tf->locvars[i].varname=LoadTString(Z);
}
tf->locvars[i].line=-1; /* flag end of vector */
tf->locvars[i].varname=NULL;
}
static TProtoFunc* LoadFunction(ZIO* Z);
static TProtoFunc* LoadFunction (ZIO* Z, int native);
static void LoadConstants(TProtoFunc* tf, ZIO* Z)
static void LoadConstants (TProtoFunc* tf, ZIO* Z, int native)
{
int i,n=LoadWord(Z);
int i,n=LoadInt(Z,"too many constants (%ld) in %s");
tf->nconsts=n;
if (n==0) return;
tf->consts=luaM_newvector(n,TObject);
for (i=0; i<n; i++)
{
TObject* o=tf->consts+i;
int c=ezgetc(Z);
switch (c)
ttype(o)=-ezgetc(Z); /* ttype(o) is negative - ORDER LUA_T */
switch (ttype(o))
{
case ID_NUM:
ttype(o)=LUA_T_NUMBER;
doLoadNumber(nvalue(o),Z);
case LUA_T_NUMBER:
nvalue(o)=LoadNumber(Z,native);
break;
case ID_STR:
ttype(o)=LUA_T_STRING;
case LUA_T_STRING:
tsvalue(o)=LoadTString(Z);
break;
case ID_FUN:
ttype(o)=LUA_T_PROTO;
tfvalue(o)=LoadFunction(Z);
case LUA_T_PROTO:
tfvalue(o)=LoadFunction(Z,native);
break;
default:
luaL_verror("bad constant #%d in %s: type=%d ('%c')",i,zname(Z),c,c);
case LUA_T_NIL:
break;
default: /* cannot happen */
luaU_badconstant("load",i,o,tf);
break;
}
}
}
static TProtoFunc* LoadFunction(ZIO* Z)
static TProtoFunc* LoadFunction (ZIO* Z, int native)
{
TProtoFunc* tf=luaF_newproto();
tf->lineDefined=LoadWord(Z);
tf->fileName=LoadTString(Z);
tf->lineDefined=LoadInt(Z,"lineDefined too large (%ld) in %s");
tf->source=LoadTString(Z);
if (tf->source==NULL) tf->source=luaS_new(zname(Z));
tf->code=LoadCode(Z);
LoadLocals(tf,Z);
LoadConstants(tf,Z);
LoadConstants(tf,Z,native);
return tf;
}
static void LoadSignature(ZIO* Z)
static void LoadSignature (ZIO* Z)
{
char* s=SIGNATURE;
while (*s!=0 && ezgetc(Z)==*s)
@@ -176,10 +175,10 @@ static void LoadSignature(ZIO* Z)
if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
}
static void LoadHeader(ZIO* Z)
static int LoadHeader (ZIO* Z)
{
int version,id,sizeofR;
real f=-TEST_NUMBER,tf=TEST_NUMBER;
int version,sizeofR;
int native;
LoadSignature(Z);
version=ezgetc(Z);
if (version>VERSION)
@@ -190,32 +189,36 @@ static void LoadHeader(ZIO* Z)
luaL_verror(
"%s too old: version=0x%02x; expected at least 0x%02x",
zname(Z),version,VERSION0);
id=ezgetc(Z); /* test number representation */
sizeofR=ezgetc(Z);
if (id!=ID_NUMBER || sizeofR!=sizeof(real))
native=(sizeofR!=0);
if (native) /* test number representation */
{
luaL_verror("unknown number signature in %s: "
"read 0x%02x%02x; expected 0x%02x%02x",
zname(Z),id,sizeofR,ID_NUMBER,sizeof(real));
if (sizeofR!=sizeof(real))
luaL_verror("unknown number size in %s: read %d; expected %d",
zname(Z),sizeofR,sizeof(real));
else
{
real tf=TEST_NUMBER;
real f=LoadNumber(Z,native);
if ((long)f!=(long)tf)
luaL_verror("unknown number format in %s: "
"read " NUMBER_FMT "; expected " NUMBER_FMT,
zname(Z),f,tf);
}
}
doLoadNumber(f,Z);
if (f!=tf)
luaL_verror("unknown number representation in %s: "
"read " NUMBER_FMT "; expected " NUMBER_FMT "", /* LUA_NUMBER */
zname(Z),(double)f,(double)tf);
return native;
}
static TProtoFunc* LoadChunk(ZIO* Z)
static TProtoFunc* LoadChunk (ZIO* Z)
{
LoadHeader(Z);
return LoadFunction(Z);
return LoadFunction(Z,LoadHeader(Z));
}
/*
** load one chunk from a file or buffer
** return main if ok and NULL at EOF
*/
TProtoFunc* luaU_undump1(ZIO* Z)
TProtoFunc* luaU_undump1 (ZIO* Z)
{
int c=zgetc(Z);
if (c==ID_CHUNK)
@@ -224,3 +227,13 @@ TProtoFunc* luaU_undump1(ZIO* Z)
luaL_verror("%s is not a Lua binary file",zname(Z));
return NULL;
}
/*
* handle constants that cannot happen
*/
void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf)
{
int t=ttype(o);
char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t];
luaL_verror("cannot %s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lundump.h,v 1.7 1998/06/25 15:50:09 lhf Exp $
** $Id: lundump.h,v 1.15 1999/07/02 19:34:26 lhf Exp $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -10,72 +10,30 @@
#include "lobject.h"
#include "lzio.h"
TProtoFunc* luaU_undump1(ZIO* Z); /* load one chunk */
TProtoFunc* luaU_undump1 (ZIO* Z); /* load one chunk */
void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf);
/* handle cases that cannot happen */
double luaU_str2d (char* b, char* where);
/* convert number from text */
#define SIGNATURE "Lua"
#define VERSION 0x31 /* last format change was in 3.1 */
#define VERSION0 0x31 /* last major change was in 3.1 */
/* definitions for headers of binary files */
#define VERSION 0x32 /* last format change was in 3.2 */
#define VERSION0 0x32 /* last major change was in 3.2 */
#define ID_CHUNK 27 /* binary files start with ESC... */
#define SIGNATURE "Lua" /* ...followed by this signature */
#define IsMain(f) (f->lineDefined==0)
/* formats for error messages */
#define SOURCE "<%s:%d>"
#define IN " in %p " SOURCE
#define INLOC tf,tf->source->str,tf->lineDefined
#define ID_CHUNK 27 /* ESC */
#define ID_NUM 'N'
#define ID_STR 'S'
#define ID_FUN 'F'
/* format for numbers in listings and error messages */
#ifndef NUMBER_FMT
#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
#endif
/* number representation */
#define ID_INT4 'l' /* 4-byte integers */
#define ID_REAL4 'f' /* 4-byte reals */
#define ID_REAL8 'd' /* 8-byte reals */
#define ID_NATIVE '?' /* whatever your machine uses */
/*
* use a multiple of PI for testing number representation.
* multiplying by 1E8 gives notrivial integer values.
*/
/* a multiple of PI for testing native format */
/* multiplying by 1E8 gives non-trivial integer values */
#define TEST_NUMBER 3.14159265358979323846E8
/* LUA_NUMBER
* choose one below for the number representation in precompiled chunks.
* the default is ID_REAL8 because the default for LUA_NUM_TYPE is double.
* if your machine does not use IEEE 754, use ID_NATIVE.
* the next version will support conversion to/from IEEE 754.
*
* if you change LUA_NUM_TYPE, make sure you set ID_NUMBER accordingly,
* specially if sizeof(long)!=4.
* for types other than the ones listed below, you'll have to write your own
* dump and undump routines.
*/
#ifndef ID_NUMBER
#define ID_NUMBER ID_NATIVE
#endif
#if 0
#define ID_NUMBER ID_INT4
#define ID_NUMBER ID_REAL4
#define ID_NUMBER ID_REAL8
#define ID_NUMBER ID_NATIVE
#endif
#endif
#if ID_NUMBER==ID_REAL4
#define DumpNumber DumpFloat
#define LoadNumber LoadFloat
#define SIZEOF_NUMBER 4
#elif ID_NUMBER==ID_REAL8
#define DumpNumber DumpDouble
#define LoadNumber LoadDouble
#define SIZEOF_NUMBER 8
#elif ID_NUMBER==ID_INT4
#define DumpNumber DumpLong
#define LoadNumber LoadLong
#define SIZEOF_NUMBER 4
#elif ID_NUMBER==ID_NATIVE
#define DumpNumber DumpNative
#define LoadNumber LoadNative
#define SIZEOF_NUMBER sizeof(real)
#else
#error bad ID_NUMBER
#endif

606
lvm.c
View File

@@ -1,11 +1,14 @@
/*
** $Id: lvm.c,v 1.29 1998/05/31 22:18:24 roberto Exp roberto $
** $Id: lvm.c,v 1.57 1999/05/21 19:41:49 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
@@ -13,6 +16,7 @@
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
@@ -27,9 +31,7 @@
#endif
#define skip_word(pc) (pc+=2)
#define get_word(pc) ((*(pc)<<8)+(*((pc)+1)))
#define next_word(pc) (pc+=2, get_word(pc-2))
#define highbyte(x) ((x)<<8)
/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */
@@ -37,45 +39,47 @@
static TaggedString *strconc (TaggedString *l, TaggedString *r)
{
size_t nl = l->u.s.len;
size_t nr = r->u.s.len;
char *buffer = luaL_openspace(nl+nr+1);
static TaggedString *strconc (TaggedString *l, TaggedString *r) {
long nl = l->u.s.len;
long nr = r->u.s.len;
char *buffer = luaL_openspace(nl+nr);
memcpy(buffer, l->str, nl);
memcpy(buffer+nl, r->str, nr);
return luaS_newlstr(buffer, nl+nr);
}
int luaV_tonumber (TObject *obj)
{ /* LUA_NUMBER */
double t;
char c;
int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */
if (ttype(obj) != LUA_T_STRING)
return 1;
else if (sscanf(svalue(obj), "%lf %c",&t, &c) == 1) {
nvalue(obj) = (real)t;
else {
double t;
char *e = svalue(obj);
int sig = 1;
while (isspace((unsigned char)*e)) e++;
if (*e == '-') {
e++;
sig = -1;
}
else if (*e == '+') e++;
/* no digit before or after decimal point? */
if (!isdigit((unsigned char)*e) && !isdigit((unsigned char)*(e+1)))
return 2;
t = luaO_str2d(e);
if (t<0) return 2;
nvalue(obj) = (real)t*sig;
ttype(obj) = LUA_T_NUMBER;
return 0;
}
else
return 2;
}
int luaV_tostring (TObject *obj)
{ /* LUA_NUMBER */
int luaV_tostring (TObject *obj) { /* LUA_NUMBER */
if (ttype(obj) != LUA_T_NUMBER)
return 1;
else {
char s[60];
real f = nvalue(obj);
int i;
if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i=(int)f) == f)
sprintf (s, "%d", i);
else
sprintf (s, NUMBER_FMT, nvalue(obj));
char s[32]; /* 16 digits, signal, point and \0 (+ some extra...) */
sprintf(s, "%.16g", (double)nvalue(obj));
tsvalue(obj) = luaS_new(s);
ttype(obj) = LUA_T_STRING;
return 0;
@@ -83,8 +87,15 @@ int luaV_tostring (TObject *obj)
}
void luaV_closure (int nelems)
{
void luaV_setn (Hash *t, int val) {
TObject index, value;
ttype(&index) = LUA_T_STRING; tsvalue(&index) = luaS_new("n");
ttype(&value) = LUA_T_NUMBER; nvalue(&value) = val;
luaH_set(t, &index, &value);
}
void luaV_closure (int nelems) {
if (nelems > 0) {
struct Stack *S = &L->stack;
Closure *c = luaF_newclosure(nelems);
@@ -101,99 +112,110 @@ void luaV_closure (int nelems)
** Function to index a table.
** Receives the table at top-2 and the index at top-1.
*/
void luaV_gettable (void)
{
struct Stack *S = &L->stack;
void luaV_gettable (void) {
TObject *table = L->stack.top-2;
TObject *im;
if (ttype(S->top-2) != LUA_T_ARRAY) /* not a table, get "gettable" method */
im = luaT_getimbyObj(S->top-2, IM_GETTABLE);
if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
im = luaT_getimbyObj(table, IM_GETTABLE);
if (ttype(im) == LUA_T_NIL)
lua_error("indexed expression not a table");
}
else { /* object is a table... */
int tg = (S->top-2)->value.a->htag;
int tg = table->value.a->htag;
im = luaT_getim(tg, IM_GETTABLE);
if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */
TObject *h = luaH_get(avalue(S->top-2), S->top-1);
if (h != NULL && ttype(h) != LUA_T_NIL) {
--S->top;
*(S->top-1) = *h;
TObject *h = luaH_get(avalue(table), table+1);
if (ttype(h) == LUA_T_NIL &&
(ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)) {
/* result is nil and there is an "index" tag method */
luaD_callTM(im, 2, 1); /* calls it */
}
else if (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)
luaD_callTM(im, 2, 1);
else {
--S->top;
ttype(S->top-1) = LUA_T_NIL;
L->stack.top--;
*table = *h; /* "push" result into table position */
}
return;
}
/* else it has a "gettable" method, go through to next command */
}
/* object is not a table, or it has a "gettable" method */
if (ttype(im) != LUA_T_NIL)
luaD_callTM(im, 2, 1);
else
lua_error("indexed expression not a table");
luaD_callTM(im, 2, 1);
}
/*
** Function to store indexed based on values at the stack.top
** mode = 0: raw store (without tag methods)
** mode = 1: normal store (with tag methods)
** mode = 2: "deep L->stack.stack" store (with tag methods)
** Receives table at *t, index at *(t+1) and value at top.
*/
void luaV_settable (TObject *t, int mode)
{
void luaV_settable (TObject *t) {
struct Stack *S = &L->stack;
TObject *im = (mode == 0) ? NULL : luaT_getimbyObj(t, IM_SETTABLE);
if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) {
TObject *h = luaH_set(avalue(t), t+1);
*h = *(S->top-1);
S->top -= (mode == 2) ? 1 : 3;
}
else { /* object is not a table, and/or has a specific "settable" method */
if (im && ttype(im) != LUA_T_NIL) {
if (mode == 2) {
*(S->top+1) = *(L->stack.top-1);
*(S->top) = *(t+1);
*(S->top-1) = *t;
S->top += 2; /* WARNING: caller must assure stack space */
}
luaD_callTM(im, 3, 0);
}
else
TObject *im;
if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
im = luaT_getimbyObj(t, IM_SETTABLE);
if (ttype(im) == LUA_T_NIL)
lua_error("indexed expression not a table");
}
else { /* object is a table... */
im = luaT_getim(avalue(t)->htag, IM_SETTABLE);
if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */
luaH_set(avalue(t), t+1, S->top-1);
S->top--; /* pop value */
return;
}
/* else it has a "settable" method, go through to next command */
}
/* object is not a table, or it has a "settable" method */
/* prepare arguments and call the tag method */
*(S->top+1) = *(L->stack.top-1);
*(S->top) = *(t+1);
*(S->top-1) = *t;
S->top += 2; /* WARNING: caller must assure stack space */
luaD_callTM(im, 3, 0);
}
void luaV_getglobal (TaggedString *ts)
{
/* WARNING: caller must assure stack space */
TObject *value = &ts->u.s.globalval;
TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
if (ttype(im) == LUA_T_NIL) { /* default behavior */
*L->stack.top++ = *value;
}
void luaV_rawsettable (TObject *t) {
if (ttype(t) != LUA_T_ARRAY)
lua_error("indexed expression not a table");
else {
struct Stack *S = &L->stack;
ttype(S->top) = LUA_T_STRING;
tsvalue(S->top) = ts;
S->top++;
*S->top++ = *value;
luaD_callTM(im, 2, 1);
luaH_set(avalue(t), t+1, S->top-1);
S->top -= 3;
}
}
void luaV_setglobal (TaggedString *ts)
{
void luaV_getglobal (TaggedString *ts) {
/* WARNING: caller must assure stack space */
/* only userdata, tables and nil can have getglobal tag methods */
static char valid_getglobals[] = {1, 0, 0, 1, 0, 0, 1, 0}; /* ORDER LUA_T */
TObject *value = &ts->u.s.globalval;
if (valid_getglobals[-ttype(value)]) {
TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
struct Stack *S = &L->stack;
ttype(S->top) = LUA_T_STRING;
tsvalue(S->top) = ts;
S->top++;
*S->top++ = *value;
luaD_callTM(im, 2, 1);
return;
}
/* else no tag method: go through to default behavior */
}
*L->stack.top++ = *value; /* default behavior */
}
void luaV_setglobal (TaggedString *ts) {
TObject *oldvalue = &ts->u.s.globalval;
TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
if (ttype(im) == LUA_T_NIL) /* default behavior */
if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
luaS_rawsetglobal(ts, --L->stack.top);
else {
/* WARNING: caller must assure stack space */
struct Stack *S = &L->stack;
TObject newvalue = *(S->top-1);
TObject newvalue;
newvalue = *(S->top-1);
ttype(S->top-1) = LUA_T_STRING;
tsvalue(S->top-1) = ts;
*S->top++ = *oldvalue;
@@ -225,7 +247,7 @@ static void call_arith (IMS event)
}
static int strcomp (char *l, long ll, char *r, long lr)
static int luaV_strcomp (char *l, long ll, char *r, long lr)
{
for (;;) {
long temp = strcoll(l, r);
@@ -242,18 +264,17 @@ static int strcomp (char *l, long ll, char *r, long lr)
}
}
static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
lua_Type ttype_great, IMS op)
{
void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
lua_Type ttype_great, IMS op) {
struct Stack *S = &L->stack;
TObject *l = S->top-2;
TObject *r = S->top-1;
int result;
real result;
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1;
result = nvalue(l)-nvalue(r);
else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
result = strcomp(svalue(l), tsvalue(l)->u.s.len,
svalue(r), tsvalue(r)->u.s.len);
result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
svalue(r), tsvalue(r)->u.s.len);
else {
call_binTM(op, "unexpected type in comparison");
return;
@@ -265,27 +286,16 @@ static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
}
void luaV_pack (StkId firstel, int nvararg, TObject *tab)
{
void luaV_pack (StkId firstel, int nvararg, TObject *tab) {
TObject *firstelem = L->stack.stack+firstel;
int i;
Hash *htab;
if (nvararg < 0) nvararg = 0;
avalue(tab) = luaH_new(nvararg+1); /* +1 for field 'n' */
htab = avalue(tab) = luaH_new(nvararg+1); /* +1 for field 'n' */
ttype(tab) = LUA_T_ARRAY;
for (i=0; i<nvararg; i++) {
TObject index;
ttype(&index) = LUA_T_NUMBER;
nvalue(&index) = i+1;
*(luaH_set(avalue(tab), &index)) = *(firstelem+i);
}
/* store counter in field "n" */ {
TObject index, extra;
ttype(&index) = LUA_T_STRING;
tsvalue(&index) = luaS_new("n");
ttype(&extra) = LUA_T_NUMBER;
nvalue(&extra) = nvararg;
*(luaH_set(avalue(tab), &index)) = extra;
}
for (i=0; i<nvararg; i++)
luaH_setint(htab, i+1, firstelem+i);
luaV_setn(htab, nvararg); /* store counter in field "n" */
}
@@ -305,12 +315,11 @@ static void adjust_varargs (StkId first_extra_arg)
** [stack+base,top). Returns n such that the the results are between
** [stack+n,top).
*/
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
{
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
struct Stack *S = &L->stack; /* to optimize */
Byte *pc = tf->code;
register Byte *pc = tf->code;
TObject *consts = tf->consts;
if (lua_callhook)
if (L->callhook)
luaD_callHook(base, tf, 0);
luaD_checkstack((*pc++)+EXTRA_STACK);
if (*pc < ZEROVARARG)
@@ -319,228 +328,159 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
luaC_checkGC();
adjust_varargs(base+(*pc++)-ZEROVARARG);
}
while (1) {
int aux;
switch ((OpCode)(aux = *pc++)) {
for (;;) {
register int aux = 0;
switchentry:
switch ((OpCode)*pc++) {
case PUSHNIL0:
ttype(S->top++) = LUA_T_NIL;
case ENDCODE:
S->top = S->stack + base;
goto ret;
case RETCODE:
base += *pc++;
goto ret;
case CALL: aux = *pc++;
luaD_calln(*pc++, aux);
break;
case PUSHNIL:
aux = *pc++;
case TAILCALL: aux = *pc++;
luaD_calln(*pc++, MULT_RET);
base += aux;
goto ret;
case PUSHNIL: aux = *pc++;
do {
ttype(S->top++) = LUA_T_NIL;
} while (aux--);
break;
case PUSHNUMBER:
aux = *pc++; goto pushnumber;
case POP: aux = *pc++;
S->top -= aux;
break;
case PUSHNUMBERW:
aux = next_word(pc); goto pushnumber;
case PUSHNUMBER0: case PUSHNUMBER1: case PUSHNUMBER2:
aux -= PUSHNUMBER0;
pushnumber:
case PUSHNUMBERW: aux += highbyte(*pc++);
case PUSHNUMBER: aux += *pc++;
ttype(S->top) = LUA_T_NUMBER;
nvalue(S->top) = aux;
S->top++;
break;
case PUSHLOCAL:
aux = *pc++; goto pushlocal;
case PUSHNUMBERNEGW: aux += highbyte(*pc++);
case PUSHNUMBERNEG: aux += *pc++;
ttype(S->top) = LUA_T_NUMBER;
nvalue(S->top) = -aux;
S->top++;
break;
case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3:
case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7:
aux -= PUSHLOCAL0;
pushlocal:
case PUSHCONSTANTW: aux += highbyte(*pc++);
case PUSHCONSTANT: aux += *pc++;
*S->top++ = consts[aux];
break;
case PUSHUPVALUE: aux = *pc++;
*S->top++ = cl->consts[aux+1];
break;
case PUSHLOCAL: aux = *pc++;
*S->top++ = *((S->stack+base) + aux);
break;
case GETGLOBALW:
aux = next_word(pc); goto getglobal;
case GETGLOBAL:
aux = *pc++; goto getglobal;
case GETGLOBAL0: case GETGLOBAL1: case GETGLOBAL2: case GETGLOBAL3:
case GETGLOBAL4: case GETGLOBAL5: case GETGLOBAL6: case GETGLOBAL7:
aux -= GETGLOBAL0;
getglobal:
case GETGLOBALW: aux += highbyte(*pc++);
case GETGLOBAL: aux += *pc++;
luaV_getglobal(tsvalue(&consts[aux]));
break;
case GETTABLE:
luaV_gettable();
break;
luaV_gettable();
break;
case GETDOTTEDW:
aux = next_word(pc); goto getdotted;
case GETDOTTED:
aux = *pc++; goto getdotted;
case GETDOTTED0: case GETDOTTED1: case GETDOTTED2: case GETDOTTED3:
case GETDOTTED4: case GETDOTTED5: case GETDOTTED6: case GETDOTTED7:
aux -= GETDOTTED0;
getdotted:
case GETDOTTEDW: aux += highbyte(*pc++);
case GETDOTTED: aux += *pc++;
*S->top++ = consts[aux];
luaV_gettable();
break;
case PUSHSELFW:
aux = next_word(pc); goto pushself;
case PUSHSELF:
aux = *pc++; goto pushself;
case PUSHSELF0: case PUSHSELF1: case PUSHSELF2: case PUSHSELF3:
case PUSHSELF4: case PUSHSELF5: case PUSHSELF6: case PUSHSELF7:
aux -= PUSHSELF0;
pushself: {
TObject receiver = *(S->top-1);
case PUSHSELFW: aux += highbyte(*pc++);
case PUSHSELF: aux += *pc++; {
TObject receiver;
receiver = *(S->top-1);
*S->top++ = consts[aux];
luaV_gettable();
*S->top++ = receiver;
break;
}
case PUSHCONSTANTW:
aux = next_word(pc); goto pushconstant;
case PUSHCONSTANT:
aux = *pc++; goto pushconstant;
case PUSHCONSTANT0: case PUSHCONSTANT1: case PUSHCONSTANT2:
case PUSHCONSTANT3: case PUSHCONSTANT4: case PUSHCONSTANT5:
case PUSHCONSTANT6: case PUSHCONSTANT7:
aux -= PUSHCONSTANT0;
pushconstant:
*S->top++ = consts[aux];
break;
case PUSHUPVALUE:
aux = *pc++; goto pushupvalue;
case PUSHUPVALUE0: case PUSHUPVALUE1:
aux -= PUSHUPVALUE0;
pushupvalue:
*S->top++ = cl->consts[aux+1];
break;
case SETLOCAL:
aux = *pc++; goto setlocal;
case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL3:
case SETLOCAL4: case SETLOCAL5: case SETLOCAL6: case SETLOCAL7:
aux -= SETLOCAL0;
setlocal:
*((S->stack+base) + aux) = *(--S->top);
break;
case SETGLOBALW:
aux = next_word(pc); goto setglobal;
case SETGLOBAL:
aux = *pc++; goto setglobal;
case SETGLOBAL0: case SETGLOBAL1: case SETGLOBAL2: case SETGLOBAL3:
case SETGLOBAL4: case SETGLOBAL5: case SETGLOBAL6: case SETGLOBAL7:
aux -= SETGLOBAL0;
setglobal:
luaV_setglobal(tsvalue(&consts[aux]));
break;
case SETTABLE0:
luaV_settable(S->top-3, 1);
break;
case SETTABLE:
luaV_settable(S->top-3-(*pc++), 2);
break;
case SETLISTW:
aux = next_word(pc); aux *= LFIELDS_PER_FLUSH; goto setlist;
case SETLIST:
aux = *(pc++) * LFIELDS_PER_FLUSH; goto setlist;
case SETLIST0:
aux = 0;
setlist: {
int n = *(pc++);
TObject *arr = S->top-n-1;
for (; n; n--) {
ttype(S->top) = LUA_T_NUMBER;
nvalue(S->top) = n+aux;
*(luaH_set(avalue(arr), S->top)) = *(S->top-1);
S->top--;
}
break;
}
case SETMAP0:
aux = 0; goto setmap;
case SETMAP:
aux = *pc++;
setmap: {
TObject *arr = S->top-(2*aux)-3;
do {
*(luaH_set(avalue(arr), S->top-2)) = *(S->top-1);
S->top-=2;
} while (aux--);
break;
}
case POP:
aux = *pc++; goto pop;
case POP0: case POP1:
aux -= POP0;
pop:
S->top -= (aux+1);
break;
case CREATEARRAYW:
aux = next_word(pc); goto createarray;
case CREATEARRAY0: case CREATEARRAY1:
aux -= CREATEARRAY0; goto createarray;
case CREATEARRAY:
aux = *pc++;
createarray:
case CREATEARRAYW: aux += highbyte(*pc++);
case CREATEARRAY: aux += *pc++;
luaC_checkGC();
avalue(S->top) = luaH_new(aux);
ttype(S->top) = LUA_T_ARRAY;
S->top++;
break;
case EQOP: case NEQOP: {
case SETLOCAL: aux = *pc++;
*((S->stack+base) + aux) = *(--S->top);
break;
case SETGLOBALW: aux += highbyte(*pc++);
case SETGLOBAL: aux += *pc++;
luaV_setglobal(tsvalue(&consts[aux]));
break;
case SETTABLEPOP:
luaV_settable(S->top-3);
S->top -= 2; /* pop table and index */
break;
case SETTABLE:
luaV_settable(S->top-3-(*pc++));
break;
case SETLISTW: aux += highbyte(*pc++);
case SETLIST: aux += *pc++; {
int n = *(pc++);
Hash *arr = avalue(S->top-n-1);
aux *= LFIELDS_PER_FLUSH;
for (; n; n--)
luaH_setint(arr, n+aux, --S->top);
break;
}
case SETMAP: aux = *pc++; {
Hash *arr = avalue(S->top-(2*aux)-3);
do {
luaH_set(arr, S->top-2, S->top-1);
S->top-=2;
} while (aux--);
break;
}
case NEQOP: aux = 1;
case EQOP: {
int res = luaO_equalObj(S->top-2, S->top-1);
if (aux) res = !res;
S->top--;
if (aux == NEQOP) res = !res;
ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
nvalue(S->top-1) = 1;
break;
}
case LTOP:
comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
break;
case LEOP:
comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
luaV_comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
break;
case GTOP:
comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
luaV_comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
break;
case GEOP:
comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
luaV_comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
break;
case ADDOP: {
@@ -624,98 +564,47 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
nvalue(S->top-1) = 1;
break;
case ONTJMPW:
aux = next_word(pc); goto ontjmp;
case ONTJMP:
aux = *pc++;
ontjmp:
case ONTJMPW: aux += highbyte(*pc++);
case ONTJMP: aux += *pc++;
if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
else S->top--;
break;
case ONFJMPW:
aux = next_word(pc); goto onfjmp;
case ONFJMP:
aux = *pc++;
onfjmp:
case ONFJMPW: aux += highbyte(*pc++);
case ONFJMP: aux += *pc++;
if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
else S->top--;
break;
case JMPW:
aux = next_word(pc); goto jmp;
case JMP:
aux = *pc++;
jmp:
case JMPW: aux += highbyte(*pc++);
case JMP: aux += *pc++;
pc += aux;
break;
case IFFJMPW:
aux = next_word(pc); goto iffjmp;
case IFFJMP:
aux = *pc++;
iffjmp:
case IFFJMPW: aux += highbyte(*pc++);
case IFFJMP: aux += *pc++;
if (ttype(--S->top) == LUA_T_NIL) pc += aux;
break;
case IFTUPJMPW:
aux = next_word(pc); goto iftupjmp;
case IFTUPJMP:
aux = *pc++;
iftupjmp:
case IFTUPJMPW: aux += highbyte(*pc++);
case IFTUPJMP: aux += *pc++;
if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
break;
case IFFUPJMPW:
aux = next_word(pc); goto iffupjmp;
case IFFUPJMP:
aux = *pc++;
iffupjmp:
case IFFUPJMPW: aux += highbyte(*pc++);
case IFFUPJMP: aux += *pc++;
if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
break;
case CLOSUREW:
aux = next_word(pc); goto closure;
case CLOSURE:
aux = *pc++;
closure:
case CLOSUREW: aux += highbyte(*pc++);
case CLOSURE: aux += *pc++;
*S->top++ = consts[aux];
luaV_closure(*pc++);
luaC_checkGC();
break;
case CALLFUNC:
aux = *pc++; goto callfunc;
case CALLFUNC0: case CALLFUNC1:
aux -= CALLFUNC0;
callfunc: {
StkId newBase = (S->top-S->stack)-(*pc++);
luaD_call(newBase, aux);
break;
}
case ENDCODE:
S->top = S->stack + base;
/* goes through */
case RETCODE:
if (lua_callhook)
luaD_callHook(base, NULL, 1);
return (base + ((aux==RETCODE) ? *pc : 0));
case SETLINEW:
aux = next_word(pc); goto setline;
case SETLINE:
aux = *pc++;
setline:
case SETLINEW: aux += highbyte(*pc++);
case SETLINE: aux += *pc++;
if ((S->stack+base-1)->ttype != LUA_T_LINE) {
/* open space for LINE value */
luaD_openstack((S->top-S->stack)-base);
@@ -723,15 +612,24 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
(S->stack+base-1)->ttype = LUA_T_LINE;
}
(S->stack+base-1)->value.i = aux;
if (lua_linehook)
if (L->linehook)
luaD_lineHook(aux);
break;
#ifdef DEBUG
default:
LUA_INTERNALERROR("opcode doesn't match");
#endif
case LONGARGW: aux += highbyte(*pc++);
case LONGARG: aux += *pc++;
aux = highbyte(highbyte(aux));
goto switchentry; /* do not reset "aux" */
case CHECKSTACK: aux = *pc++;
LUA_ASSERT((S->top-S->stack)-base == aux && S->last >= S->top,
"wrong stack size");
break;
}
}
} ret:
if (L->callhook)
luaD_callHook(0, NULL, 1);
return base;
}

9
lvm.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.h,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $
** $Id: lvm.h,v 1.7 1998/12/30 17:26:49 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -10,6 +10,7 @@
#include "ldo.h"
#include "lobject.h"
#include "ltm.h"
#define tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (luaV_tonumber(o) != 0))
@@ -19,11 +20,15 @@
void luaV_pack (StkId firstel, int nvararg, TObject *tab);
int luaV_tonumber (TObject *obj);
int luaV_tostring (TObject *obj);
void luaV_setn (Hash *t, int val);
void luaV_gettable (void);
void luaV_settable (TObject *t, int mode);
void luaV_settable (TObject *t);
void luaV_rawsettable (TObject *t);
void luaV_getglobal (TaggedString *ts);
void luaV_setglobal (TaggedString *ts);
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base);
void luaV_closure (int nelems);
void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
lua_Type ttype_great, IMS op);
#endif

22
lzio.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lzio.c,v 1.2 1997/11/21 19:00:46 roberto Exp roberto $
** $Id: lzio.c,v 1.6 1999/03/04 14:49:18 roberto Exp roberto $
** a generic input stream interface
** See Copyright Notice in lua.h
*/
@@ -15,11 +15,11 @@
/* ----------------------------------------------------- memory buffers --- */
static int zmfilbuf (ZIO* z)
{
static int zmfilbuf (ZIO* z) {
return EOZ;
}
ZIO* zmopen (ZIO* z, char* b, int size, char *name)
{
if (b==NULL) return NULL;
@@ -41,9 +41,10 @@ ZIO* zsopen (ZIO* z, char* s, char *name)
/* -------------------------------------------------------------- FILEs --- */
static int zffilbuf (ZIO* z)
{
int n=fread(z->buffer,1,ZBSIZE,z->u);
static int zffilbuf (ZIO* z) {
int n;
if (feof((FILE *)z->u)) return EOZ;
n=fread(z->buffer,1,ZBSIZE,z->u);
if (n==0) return EOZ;
z->n=n-1;
z->p=z->buffer;
@@ -64,16 +65,15 @@ ZIO* zFopen (ZIO* z, FILE* f, char *name)
/* --------------------------------------------------------------- read --- */
int zread (ZIO *z, void *b, int n)
{
int zread (ZIO *z, void *b, int n) {
while (n) {
int m;
if (z->n == 0) {
if (z->filbuf(z) == EOZ)
return n; /* retorna quantos faltaram ler */
zungetc(z); /* poe o resultado de filbuf no buffer */
return n; /* return number of missing bytes */
zungetc(z); /* put result from 'filbuf' in the buffer */
}
m = (n <= z->n) ? n : z->n; /* minimo de n e z->n */
m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
memcpy(b, z->p, m);
z->n -= m;
z->p += m;

View File

@@ -1,5 +1,5 @@
#
## $Id: makefile,v 1.12 1998/05/27 13:03:40 roberto Exp roberto $
## $Id: makefile,v 1.18 1999/02/23 15:01:29 roberto Exp roberto $
## Makefile
## See Copyright Notice in lua.h
#
@@ -12,13 +12,15 @@
# define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant
#
# define (undefine) OLD_ANSI if your system does NOT have some new ANSI
# facilities (e.g. strerror, locale.h, memmove). Although they are ANSI,
# SunOS does not comply; so, add "-DOLD_ANSI" on SunOS
# facilities (e.g. strerror, locale.h, memmove). SunOS does not comply;
# so, add "-DOLD_ANSI" on SunOS
#
# define LUA_COMPAT2_5 if yous system does need to be compatible with
# version 2.5 (or older)
#
# define LUA_NUM_TYPE if you need numbers to be different from double
# (for instance, -DLUA_NUM_TYPE=float)
#
CONFIG = -DPOPEN -D_POSIX_SOURCE
#CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG
@@ -30,6 +32,10 @@ CWARNS = -Wall -Wmissing-prototypes -Wshadow -pedantic -Wpointer-arith -Wcast-al
CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2
# To make early versions
CO_OPTIONS =
AR = ar
ARFLAGS = rvl
@@ -58,7 +64,9 @@ LUAOBJS = \
LIBOBJS = \
liolib.o \
lmathlib.o \
lstrlib.o
lstrlib.o \
ldblib.o \
linit.o
lua : lua.o liblua.a liblualib.a
@@ -80,45 +88,53 @@ clear :
rcsclean
rm -f *.o
rm -f
co lua.h lualib.h luadebug.h
co $(CO_OPTIONS) lua.h lualib.h luadebug.h
%.h : RCS/%.h,v
co $@
co $(CO_OPTIONS) $@
%.c : RCS/%.c,v
co $@
co $(CO_OPTIONS) $@
lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h lfunc.h \
lgc.h lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.h
lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h \
luadebug.h lfunc.h lgc.h lmem.h lstring.h ltable.h ltm.h lvm.h
lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h
lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h \
luadebug.h
lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \
ldo.h lstate.h lfunc.h lmem.h lstring.h ltable.h ltm.h lundump.h \
lzio.h
ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \
lparser.h lzio.h ltm.h luadebug.h lundump.h lvm.h
lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h
lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \
lstring.h ltable.h ltm.h
ldo.h lstate.h luadebug.h lfunc.h lmem.h lstring.h ltable.h ltm.h \
lundump.h lzio.h lvm.h
ldblib.o: ldblib.c lauxlib.h lua.h luadebug.h lualib.h
ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
lmem.h lparser.h lzio.h lstring.h ltm.h lundump.h lvm.h
lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h luadebug.h
lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
lmem.h lstring.h ltable.h ltm.h
linit.o: linit.c lua.h lualib.h
liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h
llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \
lparser.h lstate.h lstring.h luadebug.h
lparser.h lstate.h luadebug.h lstring.h
lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h
lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h
lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h luadebug.h
lobject.o: lobject.c lobject.h lua.h
lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h lfunc.h \
llex.h lzio.h lmem.h lopcodes.h lparser.h lstring.h luadebug.h
lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h lfunc.h \
lgc.h llex.h lzio.h lmem.h lstring.h ltable.h ltm.h
lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h lstring.h
lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h \
luadebug.h lfunc.h llex.h lzio.h lmem.h lopcodes.h lparser.h \
lstring.h
lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h \
luadebug.h lfunc.h lgc.h llex.h lzio.h lmem.h lstring.h ltable.h \
ltm.h
lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h luadebug.h \
lstring.h
lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h
ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltable.h
ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltm.h
ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h lstate.h \
luadebug.h ltable.h
ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h luadebug.h \
ltm.h
lua.o: lua.c lua.h luadebug.h lualib.h
lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \
lstring.h lundump.h lzio.h
lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h lfunc.h lgc.h \
lmem.h lopcodes.h lstring.h ltable.h ltm.h luadebug.h lvm.h
lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h \
lfunc.h lgc.h lmem.h lopcodes.h lstring.h ltable.h ltm.h lvm.h
lzio.o: lzio.c lzio.h

File diff suppressed because it is too large Load Diff