Compare commits

...

153 Commits

Author SHA1 Message Date
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 3356 additions and 2537 deletions

36
bugs
View File

@@ -31,7 +31,7 @@ Tue Jan 27 17:12:36 EDT 1998
** lstring.c / ltable.c ** lstring.c / ltable.c
Wed Jan 28 14:48:12 EDT 1998 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 ** lstrlib.c
Mon Mar 9 15:26:09 EST 1998 Mon Mar 9 15:26:09 EST 1998
@@ -41,3 +41,37 @@ Mon Mar 9 15:26:09 EST 1998
Mon May 18 19:20:00 EST 1998 Mon May 18 19:20:00 EST 1998
>> arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int. >> 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.
** 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.
** 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.
** lzio.c
Thu Mar 4 11:49:37 EST 1999
>> file stream cannot call fread after EOF.

213
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.41 1999/03/04 21:17:26 roberto Exp roberto $
** Lua API ** Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -25,17 +25,16 @@
char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n" char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
"$Autores: " LUA_AUTHORS " $"; "$Authors: " LUA_AUTHORS " $";
TObject *luaA_Address (lua_Object o) TObject *luaA_Address (lua_Object o) {
{ return (o != LUA_NOOBJECT) ? Address(o) : NULL;
return Address(o);
} }
static int normalized_type (TObject *o) static lua_Type normalized_type (TObject *o)
{ {
int t = ttype(o); int t = ttype(o);
switch (t) { switch (t) {
@@ -71,12 +70,8 @@ void luaA_packresults (void)
} }
int luaA_passresults (void) int luaA_passresults (void) {
{ L->Cstack.base = L->Cstack.lua2C; /* position of first result */
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;
return L->Cstack.num; 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); luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
L->stack.stack[L->Cstack.base++] = *o; L->stack.stack[L->Cstack.base++] = *o;
return L->Cstack.base; /* this is +1 real position (see Ref) */ 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); luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
L->stack.stack[L->Cstack.base++] = *(--L->stack.top); L->stack.stack[L->Cstack.base++] = *(--L->stack.top);
return L->Cstack.base; /* this is +1 real position (see Ref) */ 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); checkCparams(1);
return put_luaObjectonTop(); return put_luaObjectonTop();
} }
@@ -150,12 +150,12 @@ lua_Object lua_settagmethod (int tag, char *event)
} }
lua_Object lua_seterrormethod (void) lua_Object lua_seterrormethod (void) {
{ lua_Object temp;
TObject temp = L->errorim;
checkCparams(1); checkCparams(1);
L->errorim = *(--L->stack.top); temp = lua_getglobal("_ERRORMESSAGE");
return put_luaObject(&temp); lua_setglobal("_ERRORMESSAGE");
return temp;
} }
@@ -173,28 +173,23 @@ lua_Object lua_rawgettable (void)
if (ttype(L->stack.top-2) != LUA_T_ARRAY) if (ttype(L->stack.top-2) != LUA_T_ARRAY)
lua_error("indexed expression not a table in rawgettable"); lua_error("indexed expression not a table in rawgettable");
else { else {
TObject *h = luaH_get(avalue(L->stack.top-2), L->stack.top-1); *(L->stack.top-2) = *luaH_get(avalue(L->stack.top-2), L->stack.top-1);
--L->stack.top; --L->stack.top;
if (h != NULL)
*(L->stack.top-1) = *h;
else
ttype(L->stack.top-1) = LUA_T_NIL;
} }
return put_luaObjectonTop(); return put_luaObjectonTop();
} }
void lua_settable (void) void lua_settable (void) {
{
checkCparams(3); 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); checkCparams(3);
luaV_settable(L->stack.top-3, 0); luaV_rawsettable(L->stack.top-3);
} }
@@ -426,22 +421,108 @@ void lua_settag (int tag)
break; break;
default: default:
luaL_verror("cannot change the tag of a %.20s", 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--; 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_LHFunction lua_setlinehook (lua_LHFunction func) {
lua_CHFunction lua_callhook = NULL; lua_LHFunction old = L->linehook;
lua_LHFunction lua_linehook = NULL; 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) lua_Function lua_stackedfunction (int level)
@@ -457,6 +538,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) int lua_currentline (lua_Function func)
{ {
TObject *f = Address(func); TObject *f = Address(func);
@@ -465,8 +552,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 */ /* check whether func is a Lua function */
if (lua_tag(func) != LUA_T_PROTO) if (lua_tag(func) != LUA_T_PROTO)
return LUA_NOOBJECT; return LUA_NOOBJECT;
@@ -477,7 +563,7 @@ lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
if (*name) { if (*name) {
/* if "*name", there must be a LUA_T_LINE */ /* if "*name", there must be a LUA_T_LINE */
/* therefore, f+2 points to function base */ /* therefore, f+2 points to function base */
return Ref((f+2)+(local_number-1)); return put_luaObject((f+2)+(local_number-1));
} }
else else
return LUA_NOOBJECT; return LUA_NOOBJECT;
@@ -508,18 +594,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)) if (!lua_isfunction(func))
lua_error("API - `funcinfo' called with a non-function value"); lua_error("API - `funcinfo' called with a non-function value");
else { else {
TObject *f = luaA_protovalue(Address(func)); TObject *f = luaA_protovalue(Address(func));
if (normalized_type(f) == LUA_T_PROTO) { if (normalized_type(f) == LUA_T_PROTO) {
*filename = tfvalue(f)->fileName->str; *source = tfvalue(f)->source->str;
*linedefined = tfvalue(f)->lineDefined; *linedefined = tfvalue(f)->lineDefined;
} }
else { else {
*filename = "(C)"; *source = "(C)";
*linedefined = -1; *linedefined = -1;
} }
} }
@@ -534,16 +619,19 @@ static int checkfunc (TObject *o)
char *lua_getobjname (lua_Object o, char **name) char *lua_getobjname (lua_Object o, char **name)
{ /* try to find a name for given function */ { /* try to find a name for given function */
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc */ set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
if ((*name = luaT_travtagmethods(checkfunc)) != NULL) if ((*name = luaS_travsymbol(checkfunc)) != NULL)
return "tag-method";
else if ((*name = luaS_travsymbol(checkfunc)) != NULL)
return "global"; return "global";
else if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
return "tag-method";
else return ""; else return "";
} }
/* }====================================================== */
/* /*
** ======================================================= ** {======================================================
** BLOCK mechanism ** BLOCK mechanism
** ======================================================= ** =======================================================
*/ */
@@ -583,26 +671,7 @@ lua_Object lua_getref (int ref)
return (o ? put_luaObject(o) : LUA_NOOBJECT); 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); }

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 ** Auxiliary functions from Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -16,5 +16,7 @@ TObject *luaA_Address (lua_Object o);
void luaA_pushobject (TObject *o); void luaA_pushobject (TObject *o);
void luaA_packresults (void); void luaA_packresults (void);
int luaA_passresults (void); int luaA_passresults (void);
TaggedString *luaA_nextvar (TaggedString *g);
int luaA_next (Hash *t, int i);
#endif #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 ** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -10,9 +10,10 @@
#include <string.h> #include <string.h>
/* Please Notice: This file uses only the official API of Lua /* Please Notice: This file uses only the official API of Lua
** Any function declared here could be written as an application ** Any function declared here could be written as an application function.
** function. With care, these functions can be used by other libraries. ** With care, these functions can be used by other libraries.
*/ */
#include "lauxlib.h" #include "lauxlib.h"
#include "lua.h" #include "lua.h"
#include "luadebug.h" #include "luadebug.h"
@@ -27,12 +28,13 @@ int luaL_findstring (char *name, char *list[]) {
return -1; /* name not found */ 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; char *funcname;
lua_getobjname(lua_stackedfunction(0), &funcname); lua_getobjname(f, &funcname);
numarg -= lua_nups(f);
if (funcname == NULL) if (funcname == NULL)
funcname = "???"; funcname = "?";
if (extramsg == NULL) if (extramsg == NULL)
luaL_verror("bad argument #%d to function `%.50s'", numarg, funcname); luaL_verror("bad argument #%d to function `%.50s'", numarg, funcname);
else else
@@ -109,3 +111,23 @@ void luaL_verror (char *fmt, ...)
lua_error(buff); 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 ** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h ** 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)) #define luaL_opt_string(n, d) (luaL_opt_lstr((n), (d), NULL))
char *luaL_opt_lstr (int numArg, char *def, long *len); char *luaL_opt_lstr (int numArg, char *def, long *len);
double luaL_check_number (int numArg); 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); 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_functionarg (int arg);
lua_Object luaL_tablearg (int arg); lua_Object luaL_tablearg (int arg);
lua_Object luaL_nonnullarg (int numArg); lua_Object luaL_nonnullarg (int numArg);
@@ -42,6 +46,8 @@ int luaL_newbuffer (int size);
void luaL_oldbuffer (int old); void luaL_oldbuffer (int old);
char *luaL_buffer (void); char *luaL_buffer (void);
int luaL_findstring (char *name, char *list[]); 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 #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 ** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -16,70 +16,60 @@
** Auxiliary buffer ** Auxiliary buffer
-------------------------------------------------------*/ -------------------------------------------------------*/
#define BUFF_STEP 32
#define EXTRABUFF 32
#define openspace(size) if (L->Mbuffnext+(size) > L->Mbuffsize) Openspace(size) #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 */ lua_State *l = L; /* to optimize */
int base = l->Mbuffbase-l->Mbuffer; size += EXTRABUFF;
l->Mbuffsize *= 2; l->Mbuffsize = l->Mbuffnext+size;
if (l->Mbuffnext+size > l->Mbuffsize) /* still not big enough? */ luaM_growvector(l->Mbuffer, l->Mbuffnext, size, char, arrEM, MAX_INT);
l->Mbuffsize = l->Mbuffnext+size;
l->Mbuffer = luaM_realloc(l->Mbuffer, l->Mbuffsize);
l->Mbuffbase = l->Mbuffer+base;
} }
char *luaL_openspace (int size) char *luaL_openspace (int size) {
{
openspace(size); openspace(size);
return L->Mbuffer+L->Mbuffnext; return L->Mbuffer+L->Mbuffnext;
} }
void luaL_addchar (int c) void luaL_addchar (int c) {
{ openspace(1);
openspace(BUFF_STEP); L->Mbuffer[L->Mbuffnext++] = (char)c;
L->Mbuffer[L->Mbuffnext++] = c;
} }
void luaL_resetbuffer (void) void luaL_resetbuffer (void) {
{ L->Mbuffnext = L->Mbuffbase;
L->Mbuffnext = L->Mbuffbase-L->Mbuffer;
} }
void luaL_addsize (int n) void luaL_addsize (int n) {
{
L->Mbuffnext += n; L->Mbuffnext += n;
} }
int luaL_getsize (void) int luaL_getsize (void) {
{ return L->Mbuffnext-L->Mbuffbase;
return L->Mbuffnext-(L->Mbuffbase-L->Mbuffer);
} }
int luaL_newbuffer (int size) int luaL_newbuffer (int size) {
{ int old = L->Mbuffbase;
int old = L->Mbuffbase-L->Mbuffer;
openspace(size); openspace(size);
L->Mbuffbase = L->Mbuffer+L->Mbuffnext; L->Mbuffbase = L->Mbuffnext;
return old; return old;
} }
void luaL_oldbuffer (int old) void luaL_oldbuffer (int old) {
{ L->Mbuffnext = L->Mbuffbase;
L->Mbuffnext = L->Mbuffbase-L->Mbuffer; L->Mbuffbase = old;
L->Mbuffbase = L->Mbuffer+old;
} }
char *luaL_buffer (void) char *luaL_buffer (void) {
{ return L->Mbuffer+L->Mbuffbase;
return 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.55 1999/03/01 20:22:16 roberto Exp roberto $
** Built-in functions ** Built-in functions
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -23,11 +23,18 @@
#include "ltm.h" #include "ltm.h"
#include "lua.h" #include "lua.h"
#include "lundump.h" #include "lundump.h"
#include "lvm.h"
static void pushstring (TaggedString *s) /*
{ ** {======================================================
** Auxiliary functions
** =======================================================
*/
static void pushtagstring (TaggedString *s) {
TObject o; TObject o;
o.ttype = LUA_T_STRING; o.ttype = LUA_T_STRING;
o.value.ts = s; o.value.ts = s;
@@ -35,209 +42,123 @@ static void pushstring (TaggedString *s)
} }
static void nextvar (void) static real getsize (Hash *h) {
{ real max = 0;
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));
int i; int i;
for (i=0; i<avalue(&t)->nhash; i++) { for (i = 0; i<nhash(h); i++) {
Node *nd = &(avalue(&t)->node[i]); Node *n = h->node+i;
if (ttype(ref(nd)) != LUA_T_NIL && ttype(val(nd)) != LUA_T_NIL) { if (ttype(ref(n)) == LUA_T_NUMBER &&
luaA_pushobject(&f); ttype(val(n)) != LUA_T_NIL &&
luaA_pushobject(ref(nd)); nvalue(ref(n)) > max)
luaA_pushobject(val(nd)); max = nvalue(ref(n));
luaD_call((L->stack.top-L->stack.stack)-2, 1); }
if (ttype(L->stack.top-1) != LUA_T_NIL) return max;
return; }
L->stack.top--;
}
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) /*
{ ** If your system does not support "stdout", just remove this function.
long l; ** If you need, you can define your own "print" function, following this
char *s = luaL_check_lstr(1, &l); ** model but changing "fputs" to put the strings at a proper place
if (*s == ID_CHUNK) ** (a console window or a log file, for instance).
lua_error("`dostring' cannot run pre-compiled code"); */
if (lua_dobuffer(s, l, luaL_opt_string(2, NULL)) == 0) #define MAXPRINT 40
if (luaA_passresults() == 0) static void luaB_print (void) {
lua_pushuserdata(NULL); /* at least one result to signal no errors */ lua_Object args[MAXPRINT];
}
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");
lua_Object obj; lua_Object obj;
int i = 1; int n = 0;
while ((obj = lua_getparam(i++)) != LUA_NOOBJECT) { int i;
luaA_pushobject(&ts->u.s.globalval); while ((obj = lua_getparam(n+1)) != LUA_NOOBJECT) {
lua_pushobject(obj); luaL_arg_check(n < MAXPRINT, n+1, "too many arguments");
luaD_call((L->stack.top-L->stack.stack)-1, 1); args[n++] = obj;
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--;
} }
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) static void luaB_tonumber (void) {
{ int base = luaL_opt_int(2, 10);
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);
if (base == 10) { /* standard conversion */ if (base == 10) { /* standard conversion */
lua_Object o = lua_getparam(1); lua_Object o = lua_getparam(1);
if (lua_isnumber(o)) if (lua_isnumber(o)) lua_pushnumber(lua_getnumber(o));
lua_pushnumber(lua_getnumber(o)); else lua_pushnil(); /* not a number */
} }
else { else {
char *s = luaL_check_string(1); char *s = luaL_check_string(1);
unsigned long n; long n;
luaL_arg_check(0 <= base && base <= 36, 2, "base out of range"); luaL_arg_check(0 <= base && base <= 36, 2, "base out of range");
n = strtol(s, &s, base); 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 */ if (*s) lua_pushnil(); /* invalid format: return nil */
else lua_pushnumber(n); else lua_pushnumber(n);
} }
} }
static void luaI_error (void) static void luaB_error (void) {
{
lua_error(lua_getstring(lua_getparam(1))); lua_error(lua_getstring(lua_getparam(1)));
} }
static void luaB_setglobal (void) {
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)
{
char *n = luaL_check_string(1); char *n = luaL_check_string(1);
lua_Object value = luaL_nonnullarg(2); lua_Object value = luaL_nonnullarg(2);
lua_pushobject(value); lua_pushobject(value);
@@ -245,8 +166,7 @@ static void setglobal (void)
lua_pushobject(value); /* return given value */ lua_pushobject(value); /* return given value */
} }
static void rawsetglobal (void) static void luaB_rawsetglobal (void) {
{
char *n = luaL_check_string(1); char *n = luaL_check_string(1);
lua_Object value = luaL_nonnullarg(2); lua_Object value = luaL_nonnullarg(2);
lua_pushobject(value); lua_pushobject(value);
@@ -254,51 +174,111 @@ static void rawsetglobal (void)
lua_pushobject(value); /* return given value */ lua_pushobject(value); /* return given value */
} }
static void getglobal (void) static void luaB_getglobal (void) {
{
lua_pushobject(lua_getglobal(luaL_check_string(1))); 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))); lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
} }
static void luatag (void) static void luaB_luatag (void) {
{
lua_pushnumber(lua_tag(lua_getparam(1))); lua_pushnumber(lua_tag(lua_getparam(1)));
} }
static void luaB_settag (void) {
static int getnarg (lua_Object table) lua_Object o = luaL_tablearg(1);
{ lua_pushobject(o);
lua_Object temp; lua_settag(luaL_check_int(2));
/* temp = table.n */ lua_pushobject(o); /* return first argument */
lua_pushobject(table); lua_pushstring("n"); temp = lua_rawgettable();
return (lua_isnumber(temp) ? lua_getnumber(temp) : MAX_INT);
} }
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 f = luaL_nonnullarg(1);
lua_Object arg = luaL_tablearg(2); Hash *arg = gethash(2);
char *options = luaL_opt_string(3, ""); char *options = luaL_opt_string(3, "");
lua_Object err = lua_getparam(4); lua_Object err = lua_getparam(4);
int narg = getnarg(arg); int narg = (int)getnarg(arg);
int i, status; int i, status;
if (err != LUA_NOOBJECT) { /* set new error method */ if (err != LUA_NOOBJECT) { /* set new error method */
lua_pushobject(err); lua_pushobject(err);
err = lua_seterrormethod(); err = lua_seterrormethod();
} }
/* push arg[1...n] */ /* push arg[1...n] */
for (i=0; i<narg; i++) { luaD_checkstack(narg);
lua_Object temp; for (i=0; i<narg; i++)
/* temp = arg[i+1] */ *(L->stack.top++) = *luaH_getint(arg, i+1);
lua_pushobject(arg); lua_pushnumber(i+1); temp = lua_rawgettable();
if (narg == MAX_INT && lua_isnil(temp))
break;
lua_pushobject(temp);
}
status = lua_callfunction(f); status = lua_callfunction(f);
if (err != LUA_NOOBJECT) { /* restore old error method */ if (err != LUA_NOOBJECT) { /* restore old error method */
lua_pushobject(err); lua_pushobject(err);
@@ -312,7 +292,7 @@ static void luaI_call (void)
else else
lua_error(NULL); lua_error(NULL);
} }
else { /* no errors */ else { /* no errors */
if (strchr(options, 'p')) if (strchr(options, 'p'))
luaA_packresults(); luaA_packresults();
else else
@@ -321,91 +301,299 @@ static void luaI_call (void)
} }
static void settag (void) static void luaB_nextvar (void) {
{ TObject *o = luaA_Address(luaL_nonnullarg(1));
lua_Object o = luaL_tablearg(1); TaggedString *g;
lua_pushobject(o); if (ttype(o) == LUA_T_NIL)
lua_settag(luaL_check_number(2)); g = NULL;
lua_pushobject(o); /* returns first argument */ 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) static void luaB_next (void) {
{ Hash *a = gethash(1);
lua_pushnumber(lua_newtag()); 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) static void luaB_tostring (void) {
{ lua_Object obj = lua_getparam(1);
lua_pushnumber(lua_copytagmethods(luaL_check_number(1), TObject *o = luaA_Address(obj);
luaL_check_number(2))); 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) static void luaB_type (void) {
{ lua_Object o = luaL_nonnullarg(1);
lua_pushobject(luaL_nonnullarg(1)); lua_pushstring(luaO_typename(luaA_Address(o)));
lua_pushobject(luaL_nonnullarg(2)); lua_pushnumber(lua_tag(o));
lua_pushobject(lua_rawgettable());
} }
/* }====================================================== */
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);
TObject *f = luaA_Address(luaL_functionarg(2));
int i;
int n = (int)getnarg(t);
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);
TObject *f = luaA_Address(luaL_functionarg(2));
int i;
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) {
TObject *f = luaA_Address(luaL_functionarg(1));
GCnode *g;
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); /* increment field "n" */
for ( ;n>=pos; n--)
luaH_move(a, n, n+1);
luaH_setint(a, pos, luaA_Address(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)); /* push result */
luaV_setn(a, n-1); /* decrement field "n" */
for ( ;pos<n; pos++)
luaH_move(a, pos+1, pos);
}
/* {
** 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 (TObject *f, TObject *a, TObject *b) {
/* notice: the caller (auxsort) must check stack space */
if (f) {
*(L->stack.top) = *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, TObject *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);
TObject *f = luaA_Address(func);
luaL_arg_check(!f || lua_isfunction(func), 2, "function expected");
luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */
auxsort(a, 1, n, f);
lua_pushobject(t);
}
/* }}===================================================== */
/*
** ====================================================== */
#ifdef DEBUG
/*
** {======================================================
** some DEBUG functions ** some DEBUG functions
** ======================================================= ** =======================================================
*/ */
#ifdef DEBUG
static void mem_query (void) static void mem_query (void) {
{
lua_pushnumber(totalmem); lua_pushnumber(totalmem);
lua_pushnumber(numblocks); 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); char *s = luaL_check_string(1);
GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next : GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next :
(s[0]=='p') ? L->rootproto.next : L->rootglobal.next; (s[0]=='p') ? L->rootproto.next : L->rootglobal.next;
@@ -418,8 +606,7 @@ static void countlist (void)
} }
static void testC (void) static void testC (void) {
{
#define getnum(s) ((*s++) - '0') #define getnum(s) ((*s++) - '0')
#define getname(s) (nome[0] = *s++, nome) #define getname(s) (nome[0] = *s++, nome)
@@ -428,7 +615,7 @@ static void testC (void)
char nome[2]; char nome[2];
char *s = luaL_check_string(1); char *s = luaL_check_string(1);
nome[1] = 0; nome[1] = 0;
while (1) { for (;;) {
switch (*s++) { switch (*s++) {
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
@@ -454,11 +641,17 @@ static void testC (void)
case '=': lua_setglobal(getname(s)); break; case '=': lua_setglobal(getname(s)); break;
case 's': lua_pushstring(getname(s)); break; case 's': lua_pushstring(getname(s)); break;
case 'o': lua_pushobject(reg[getnum(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_gettable(); break;
case 'I': reg[getnum(s)] = lua_rawgettable(); break; case 'I': reg[getnum(s)] = lua_rawgettable(); break;
case 't': lua_settable(); break; case 't': lua_settable(); break;
case 'T': lua_rawsettable(); 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)); default: luaL_verror("unknown command in `testC': %c", *(s-1));
} }
if (*s == 0) return; if (*s == 0) return;
@@ -466,13 +659,12 @@ static void testC (void)
} }
} }
/* }====================================================== */
#endif #endif
/*
** Internal functions static struct luaL_reg builtin_funcs[] = {
*/
static struct luaL_reg int_funcs[] = {
#ifdef LUA_COMPAT2_5 #ifdef LUA_COMPAT2_5
{"setfallback", luaT_setfallback}, {"setfallback", luaT_setfallback},
#endif #endif
@@ -480,46 +672,54 @@ static struct luaL_reg int_funcs[] = {
{"testC", testC}, {"testC", testC},
{"totalmem", mem_query}, {"totalmem", mem_query},
{"count", countlist}, {"count", countlist},
{"querystr", query_strings},
#endif #endif
{"assert", luaI_assert}, {"_ALERT", luaB_alert},
{"call", luaI_call}, {"_ERRORMESSAGE", error_message},
{"collectgarbage", luaI_collectgarbage}, {"call", luaB_call},
{"dofile", internaldofile}, {"collectgarbage", luaB_collectgarbage},
{"copytagmethods", copytagmethods}, {"copytagmethods", luaB_copytagmethods},
{"dostring", internaldostring}, {"dofile", luaB_dofile},
{"error", luaI_error}, {"dostring", luaB_dostring},
{"foreach", foreach}, {"error", luaB_error},
{"foreachvar", foreachvar}, {"getglobal", luaB_getglobal},
{"getglobal", getglobal}, {"gettagmethod", luaB_gettagmethod},
{"newtag", newtag}, {"newtag", luaB_newtag},
{"next", next}, {"next", luaB_next},
{"nextvar", nextvar}, {"nextvar", luaB_nextvar},
{"print", luaI_print}, {"print", luaB_print},
{"rawgetglobal", rawgetglobal}, {"rawgetglobal", luaB_rawgetglobal},
{"rawgettable", rawgettable}, {"rawgettable", luaB_rawgettable},
{"rawsetglobal", rawsetglobal}, {"rawsetglobal", luaB_rawsetglobal},
{"rawsettable", rawsettable}, {"rawsettable", luaB_rawsettable},
{"seterrormethod", seterrormethod}, {"seterrormethod", luaB_seterrormethod},
{"setglobal", setglobal}, {"setglobal", luaB_setglobal},
{"settagmethod", settagmethod}, {"settag", luaB_settag},
{"gettagmethod", gettagmethod}, {"settagmethod", luaB_settagmethod},
{"settag", settag}, {"tag", luaB_luatag},
{"tonumber", tonumber}, {"tonumber", luaB_tonumber},
{"tostring", to_string}, {"tostring", luaB_tostring},
{"tag", luatag}, {"type", luaB_type},
{"type", luaI_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 */ /* pre-register mem error messages, to avoid loop when error arises */
luaS_newfixedstring(tableEM); luaS_newfixedstring(tableEM);
luaS_newfixedstring(memEM); 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_pushstring(LUA_VERSION);
lua_setglobal("_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])));
}

138
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.40 1999/03/10 14:23:07 roberto Exp roberto $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -10,6 +10,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "lauxlib.h"
#include "ldo.h" #include "ldo.h"
#include "lfunc.h" #include "lfunc.h"
#include "lgc.h" #include "lgc.h"
@@ -17,6 +18,7 @@
#include "lobject.h" #include "lobject.h"
#include "lparser.h" #include "lparser.h"
#include "lstate.h" #include "lstate.h"
#include "lstring.h"
#include "ltm.h" #include "ltm.h"
#include "lua.h" #include "lua.h"
#include "luadebug.h" #include "luadebug.h"
@@ -32,37 +34,22 @@
/*
** Error messages
*/
static void stderrorim (void)
{
fprintf(stderr, "lua error: %s\n", lua_getstring(lua_getparam(1)));
}
#define STACK_UNIT 128 #define STACK_UNIT 128
void luaD_init (void) void luaD_init (void) {
{
L->stack.stack = luaM_newvector(STACK_UNIT, TObject); L->stack.stack = luaM_newvector(STACK_UNIT, TObject);
L->stack.top = L->stack.stack; L->stack.top = L->stack.stack;
L->stack.last = L->stack.stack+(STACK_UNIT-1); 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; struct Stack *S = &L->stack;
if (S->last-S->top <= n) { if (S->last-S->top <= n) {
StkId top = S->top-S->stack; StkId top = S->top-S->stack;
int stacksize = (S->last-S->stack)+1+STACK_UNIT+n; int stacksize = (S->last-S->stack)+STACK_UNIT+n;
S->stack = luaM_reallocvector(S->stack, stacksize, TObject); luaM_reallocvector(S->stack, stacksize, TObject);
S->last = S->stack+(stacksize-1); S->last = S->stack+(stacksize-1);
S->top = S->stack + top; S->top = S->stack + top;
if (stacksize >= STACK_LIMIT) { /* stack overflow? */ if (stacksize >= STACK_LIMIT) { /* stack overflow? */
@@ -78,8 +65,7 @@ void luaD_checkstack (int n)
/* /*
** Adjust stack. Set top to the given value, pushing NILs if needed. ** 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); int diff = newtop-(L->stack.top-L->stack.stack);
if (diff <= 0) if (diff <= 0)
L->stack.top += diff; L->stack.top += diff;
@@ -107,7 +93,7 @@ void luaD_lineHook (int line)
struct C_Lua_Stack oldCLS = L->Cstack; struct C_Lua_Stack oldCLS = L->Cstack;
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
L->Cstack.num = 0; L->Cstack.num = 0;
(*lua_linehook)(line); (*L->linehook)(line);
L->stack.top = L->stack.stack+old_top; L->stack.top = L->stack.stack+old_top;
L->Cstack = oldCLS; L->Cstack = oldCLS;
} }
@@ -119,13 +105,13 @@ void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn)
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
L->Cstack.num = 0; L->Cstack.num = 0;
if (isreturn) if (isreturn)
(*lua_callhook)(LUA_NOOBJECT, "(return)", 0); (*L->callhook)(LUA_NOOBJECT, "(return)", 0);
else { else {
TObject *f = L->stack.stack+base-1; TObject *f = L->stack.stack+base-1;
if (tf) if (tf)
(*lua_callhook)(Ref(f), tf->fileName->str, tf->lineDefined); (*L->callhook)(Ref(f), tf->source->str, tf->lineDefined);
else else
(*lua_callhook)(Ref(f), "(C)", -1); (*L->callhook)(Ref(f), "(C)", -1);
} }
L->stack.top = L->stack.stack+old_top; L->stack.top = L->stack.stack+old_top;
L->Cstack = oldCLS; L->Cstack = oldCLS;
@@ -146,10 +132,10 @@ static StkId callC (lua_CFunction f, StkId base)
CS->num = numarg; CS->num = numarg;
CS->lua2C = base; CS->lua2C = base;
CS->base = base+numarg; /* == top-stack */ CS->base = base+numarg; /* == top-stack */
if (lua_callhook) if (L->callhook)
luaD_callHook(base, NULL, 0); luaD_callHook(base, NULL, 0);
(*f)(); /* do the actual call */ (*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); luaD_callHook(base, NULL, 1);
firstResult = CS->base; firstResult = CS->base;
*CS = oldCLS; *CS = oldCLS;
@@ -172,11 +158,10 @@ 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); luaD_openstack(nParams);
*(L->stack.top-nParams-1) = *f; *(L->stack.top-nParams-1) = *f;
luaD_call((L->stack.top-L->stack.stack)-nParams, nResults); luaD_calln(nParams, nResults);
} }
@@ -230,6 +215,10 @@ void luaD_call (StkId base, int nResults)
} }
void luaD_calln (int nArgs, int nResults) {
luaD_call((L->stack.top-L->stack.stack)-nArgs, nResults);
}
/* /*
** Traverse all objects on L->stack.stack ** Traverse all objects on L->stack.stack
@@ -243,25 +232,26 @@ void luaD_travstack (int (*fn)(TObject *))
static void message (char *s) static void message (char *s) {
{ TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
TObject im = L->errorim; if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
if (ttype(&im) != LUA_T_NIL) { ttype(em) == LUA_T_CLOSURE) {
*L->stack.top = *em;
incr_top;
lua_pushstring(s); lua_pushstring(s);
luaD_callTM(&im, 1, 0); luaD_calln(1, 0);
} }
} }
/* /*
** Reports an error, and jumps up to the available recover label ** 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 (s) message(s);
if (L->errorJmp) if (L->errorJmp)
longjmp(*((jmp_buf *)L->errorJmp), 1); longjmp(*((jmp_buf *)L->errorJmp), 1);
else { else {
fprintf (stderr, "lua: exit(1). Unable to recover\n"); message("exit(1). Unable to recover.\n");
exit(1); exit(1);
} }
} }
@@ -274,9 +264,9 @@ static void do_callinc (int nResults)
{ {
StkId base = L->Cstack.base; StkId base = L->Cstack.base;
luaD_call(base+1, nResults); luaD_call(base+1, nResults);
L->Cstack.lua2C = base; /* position of the luaM_new results */ L->Cstack.lua2C = base; /* position of the new results */
L->Cstack.num = (L->stack.top-L->stack.stack) - base; /* number of 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 */ L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
} }
@@ -284,18 +274,17 @@ static void do_callinc (int nResults)
** Execute a protected call. Assumes that function is at L->Cstack.base and ** Execute a protected call. Assumes that function is at L->Cstack.base and
** parameters are on top of it. Leave nResults on the stack. ** parameters are on top of it. Leave nResults on the stack.
*/ */
int luaD_protectedrun (int nResults) int luaD_protectedrun (int nResults) {
{
jmp_buf myErrorJmp;
int status;
volatile struct C_Lua_Stack oldCLS = L->Cstack; volatile struct C_Lua_Stack oldCLS = L->Cstack;
jmp_buf myErrorJmp;
volatile int status;
jmp_buf *volatile oldErr = L->errorJmp; jmp_buf *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp; L->errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp) == 0) { if (setjmp(myErrorJmp) == 0) {
do_callinc(nResults); do_callinc(nResults);
status = 0; 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->Cstack = oldCLS;
L->stack.top = L->stack.stack+L->Cstack.base; L->stack.top = L->stack.stack+L->Cstack.base;
status = 1; status = 1;
@@ -308,18 +297,20 @@ int luaD_protectedrun (int nResults)
/* /*
** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load ** 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;
jmp_buf myErrorJmp;
volatile int status; volatile int status;
TProtoFunc *volatile tf; TProtoFunc *volatile tf;
jmp_buf myErrorJmp;
jmp_buf *volatile oldErr = L->errorJmp; jmp_buf *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp; L->errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp) == 0) { if (setjmp(myErrorJmp) == 0) {
tf = bin ? luaU_undump1(z) : luaY_parser(z); tf = bin ? luaU_undump1(z) : luaY_parser(z);
status = 0; 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; tf = NULL;
status = 1; status = 1;
} }
@@ -334,9 +325,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 status;
int debug = L->debug; /* save debug status */
do { do {
long old_blocks = (luaC_checkGC(), L->nblocks); long old_blocks = (luaC_checkGC(), L->nblocks);
status = protectedparser(z, bin); status = protectedparser(z, bin);
@@ -349,6 +340,7 @@ static int do_main (ZIO *z, int bin)
L->GCthreshold -= newelems2; L->GCthreshold -= newelems2;
} }
} while (bin && status == 0); } while (bin && status == 0);
L->debug = debug; /* restore debug status */
return status; return status;
} }
@@ -364,23 +356,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; ZIO z;
int status; int status;
int c; int c;
int bin; int bin;
char source[MAXFILENAME];
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r"); FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
if (f == NULL) if (f == NULL)
return 2; return 2;
if (filename == NULL)
filename = "(stdin)";
c = fgetc(f); c = fgetc(f);
ungetc(c, f); ungetc(c, f);
bin = (c == ID_CHUNK); bin = (c == ID_CHUNK);
if (bin) if (bin)
f = freopen(filename, "rb", f); /* set binary mode */ 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); status = do_main(&z, bin);
if (f != stdin) if (f != stdin)
fclose(f); fclose(f);
@@ -388,40 +381,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) { 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) { int lua_dobuffer (char *buff, int size, char *name) {
char newname[SIZE_PREF+25];
ZIO z; ZIO z;
int status; if (!name) name = "?";
if (name==NULL) {
build_name(buff, newname);
name = newname;
}
luaZ_mopen(&z, buff, size, name); luaZ_mopen(&z, buff, size, name);
status = do_main(&z, buff[0]==ID_CHUNK); return do_main(&z, buff[0]==ID_CHUNK);
return status;
} }

3
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.4 1997/12/15 16:17:20 roberto Exp roberto $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -36,6 +36,7 @@ void luaD_openstack (int nelems);
void luaD_lineHook (int line); void luaD_lineHook (int line);
void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn); void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn);
void luaD_call (StkId base, int nResults); void luaD_call (StkId base, int nResults);
void luaD_calln (int nArgs, int nResults);
void luaD_callTM (TObject *f, int nParams, int nResults); void luaD_callTM (TObject *f, int nParams, int nResults);
int luaD_protectedrun (int nResults); int luaD_protectedrun (int nResults);
void luaD_gcIM (TObject *o); void luaD_gcIM (TObject *o);

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 ** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -31,7 +31,7 @@ TProtoFunc *luaF_newproto (void)
TProtoFunc *f = luaM_new(TProtoFunc); TProtoFunc *f = luaM_new(TProtoFunc);
f->code = NULL; f->code = NULL;
f->lineDefined = 0; f->lineDefined = 0;
f->fileName = NULL; f->source = NULL;
f->consts = NULL; f->consts = NULL;
f->nconsts = 0; f->nconsts = 0;
f->locvars = NULL; 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 ** Garbage Collector
** See Copyright Notice in lua.h ** 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; int ref;
if (ttype(o) == LUA_T_NIL) if (ttype(o) == LUA_T_NIL)
ref = -1; /* special ref for nil */ ref = -1; /* special ref for nil */
else { else {
for (ref=0; ref<L->refSize; ref++) for (ref=0; ref<L->refSize; ref++)
if (L->refArray[ref].status == FREE) if (L->refArray[ref].status == FREE)
goto found; break;
/* no more empty spaces */ { if (ref == L->refSize) { /* no more empty spaces? */
int oldSize = L->refSize; luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT);
L->refSize = luaM_growvector(&L->refArray, L->refSize, struct ref, L->refSize++;
refEM, MAX_INT); }
for (ref=oldSize; ref<L->refSize; ref++)
L->refArray[ref].status = FREE;
ref = oldSize;
} found:
L->refArray[ref].o = *o; L->refArray[ref].o = *o;
L->refArray[ref].status = lock ? LOCK : HOLD; 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) { if (!f->head.marked) {
LocVar *v = f->locvars;
int i; int i;
f->head.marked = 1; f->head.marked = 1;
if (f->fileName) strmark(f->source);
strmark(f->fileName);
for (i=0; i<f->nconsts; i++) for (i=0; i<f->nconsts; i++)
markobject(&f->consts[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();
}

538
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.37 1999/04/05 19:47:05 roberto Exp roberto $
** Standard I/O (and system) library ** Standard I/O (and system) library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -20,6 +20,7 @@
#ifndef OLD_ANSI #ifndef OLD_ANSI
#include <locale.h> #include <locale.h>
#else #else
/* no support for locale and for strerror: fake them */
#define setlocale(a,b) 0 #define setlocale(a,b) 0
#define LC_ALL 0 #define LC_ALL 0
#define LC_COLLATE 0 #define LC_COLLATE 0
@@ -31,10 +32,12 @@
#endif #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 FINPUT "_INPUT"
#define FOUTPUT "_OUTPUT" #define FOUTPUT "_OUTPUT"
@@ -43,95 +46,131 @@
#ifdef POPEN #ifdef POPEN
FILE *popen(); FILE *popen();
int pclose(); int pclose();
#define CLOSEFILE(f) {if (pclose(f) == -1) fclose(f);}
#else #else
/* no support for popen */
#define popen(x,y) NULL /* that is, popen always fails */ #define popen(x,y) NULL /* that is, popen always fails */
#define pclose(x) (-1) #define CLOSEFILE(f) {fclose(f);}
#endif #endif
static int gettag (int i)
{
return lua_getnumber(lua_getparam(i));
}
static void pushresult (int i) {
static void pushresult (int i)
{
if (i) if (i)
lua_pushuserdata(NULL); lua_pushuserdata(NULL);
else { else {
lua_pushnil(); lua_pushnil();
lua_pushstring(strerror(errno)); 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_isuserdata(f)) {
if (lua_tag(f) == gettag(CLOSEDTAG)) int tag = gettag();
if (lua_tag(f) == CLOSEDTAG(tag))
lua_error("cannot access a closed file"); lua_error("cannot access a closed file");
return lua_tag(f) == gettag(IOTAG); return lua_tag(f) == tag;
} }
else return 0; else return 0;
} }
static FILE *getfile (char *name)
{ static FILE *getfilebyname (char *name) {
lua_Object f = lua_getglobal(name); lua_Object f = lua_getglobal(name);
if (!ishandler(f)) if (!ishandle(f))
luaL_verror("global variable `%.50s' is not a file handle", name); luaL_verror("global variable `%.50s' is not a file handle", name);
return lua_getuserdata(f); return lua_getuserdata(f);
} }
static FILE *getfileparam (char *name, int *arg) static FILE *getfile (int arg) {
{ lua_Object f = lua_getparam(arg);
lua_Object f = lua_getparam(*arg); return (ishandle(f)) ? lua_getuserdata(f) : NULL;
if (ishandler(f)) { }
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)++; (*arg)++;
return lua_getuserdata(f); return f;
} }
else else
return getfile(name); return getfilebyname(name);
} }
static void closefile (char *name) static void closefile (FILE *f) {
{ if (f != stdin && f != stdout) {
FILE *f = getfile(name); int tag = gettag();
if (f == stdin || f == stdout) return; CLOSEFILE(f);
if (pclose(f) == -1) lua_pushusertag(f, tag);
fclose(f); lua_settag(CLOSEDTAG(tag));
lua_pushobject(lua_getglobal(name)); }
lua_settag(gettag(CLOSEDTAG));
} }
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_pushusertag(f, tag);
lua_setglobal(name); lua_setglobal(name);
} }
static void setreturn (FILE *f, char *name) static void setreturn (FILE *f, char *name) {
{ int tag = gettag();
int tag = gettag(IOTAG);
setfile(f, name, tag); setfile(f, name, tag);
lua_pushusertag(f, tag); lua_pushusertag(f, tag);
} }
static void io_readfrom (void) static void io_readfrom (void) {
{
FILE *current; FILE *current;
lua_Object f = lua_getparam(FIRSTARG); lua_Object f = lua_getparam(FIRSTARG);
if (f == LUA_NOOBJECT) { if (f == LUA_NOOBJECT) {
closefile(FINPUT); closefile(getfilebyname(FINPUT));
current = stdin; current = stdin;
} }
else if (lua_tag(f) == gettag(IOTAG)) else if (lua_tag(f) == gettag()) /* deprecated option */
current = lua_getuserdata(f); current = lua_getuserdata(f);
else { else {
char *s = luaL_check_string(FIRSTARG); char *s = luaL_check_string(FIRSTARG);
@@ -145,19 +184,18 @@ static void io_readfrom (void)
} }
static void io_writeto (void) static void io_writeto (void) {
{
FILE *current; FILE *current;
lua_Object f = lua_getparam(FIRSTARG); lua_Object f = lua_getparam(FIRSTARG);
if (f == LUA_NOOBJECT) { if (f == LUA_NOOBJECT) {
closefile(FOUTPUT); closefile(getfilebyname(FOUTPUT));
current = stdout; current = stdout;
} }
else if (lua_tag(f) == gettag(IOTAG)) else if (lua_tag(f) == gettag()) /* deprecated option */
current = lua_getuserdata(f); current = lua_getuserdata(f);
else { else {
char *s = luaL_check_string(FIRSTARG); char *s = luaL_check_string(FIRSTARG);
current = (*s == '|') ? popen(s+1,"w") : fopen(s,"w"); current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w");
if (current == NULL) { if (current == NULL) {
pushresult(0); pushresult(0);
return; return;
@@ -167,10 +205,8 @@ static void io_writeto (void)
} }
static void io_appendto (void) static void io_appendto (void) {
{ FILE *fp = fopen(luaL_check_string(FIRSTARG), "a");
char *s = luaL_check_string(FIRSTARG);
FILE *fp = fopen (s, "a");
if (fp != NULL) if (fp != NULL)
setreturn(fp, FOUTPUT); setreturn(fp, FOUTPUT);
else else
@@ -178,127 +214,208 @@ static void io_appendto (void)
} }
/*
** {======================================================
** 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 */ #define NEED_OTHER (EOF-1) /* just some flag different from EOF */
static void read_until (FILE *f, int lim) { static int read_pattern (FILE *f, char *p) {
int l = 0; int inskip = 0; /* {skip} level */
int c; int c = NEED_OTHER;
for (c = getc(f); c != EOF && c != lim; c = getc(f)) { while (*p != '\0') {
luaL_addchar(c); switch (*p) {
l++; case '{':
} inskip++;
if (l > 0 || c == lim) /* read anything? */ p++;
lua_pushlstring(luaL_buffer(), l); continue;
} case '}':
if (!inskip) lua_error("unbalanced braces in read pattern");
static void io_read (void) { inskip--;
int arg = FIRSTARG; p++;
FILE *f = getfileparam(FINPUT, &arg); continue;
char *p = luaL_opt_string(arg, NULL); default: {
luaL_resetbuffer(); char *ep; /* get what is next */
if (p == NULL) /* default: read a line */ int m; /* match result */
read_until(f, '\n'); if (c == NEED_OTHER) c = getc(f);
else if (p[0] == '.' && p[1] == '*' && p[2] == 0) /* p = ".*" */ if (c != EOF)
read_until(f, EOF); m = luaI_singlematch(c, p, &ep);
else { else {
int l = 0; /* number of chars read in buffer */ luaI_singlematch(0, p, &ep); /* to set "ep" */
int inskip = 0; /* to control {skips} */ m = 0; /* EOF matches no pattern */
int c = NEED_OTHER; }
while (*p) { if (m) {
switch (*p) { if (!inskip) luaL_addchar(c);
case '{': c = NEED_OTHER;
inskip++; }
p++; switch (*ep) {
continue; case '*': /* repetition */
case '}': if (!m) p = ep+1; /* else stay in (repeat) the same item */
if (inskip == 0) continue;
lua_error("unbalanced braces in read pattern"); case '?': /* optional */
inskip--; p = ep+1; /* continues reading the pattern */
p++; continue;
continue; default:
default: { if (!m) goto break_while; /* pattern fails? */
char *ep; /* get what is next */ p = ep; /* else continues reading the pattern */
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;
}
}
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 */
}
} }
} }
} break_while: }
if (c >= 0) /* not EOF nor NEED_OTHER? */ } break_while:
ungetc(c, f); if (c != NEED_OTHER) ungetc(c, f);
if (l > 0 || *p == 0) /* read something or did not fail? */ return (*p == '\0');
lua_pushlstring(luaL_buffer(), l);
}
} }
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%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; int arg = FIRSTARG;
FILE *f = getfileparam(FOUTPUT, &arg); FILE *f = getfileparam(FOUTPUT, &arg);
int status = 1; int status = 1;
char *s; char *s;
long l; long l;
while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL) 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); 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))); lua_pushnumber(system(luaL_check_string(1)));
} }
static void io_remove (void) static void io_remove (void) {
{
pushresult(remove(luaL_check_string(1)) == 0); pushresult(remove(luaL_check_string(1)) == 0);
} }
static void io_rename (void) static void io_rename (void) {
{
pushresult(rename(luaL_check_string(1), pushresult(rename(luaL_check_string(1),
luaL_check_string(2)) == 0); luaL_check_string(2)) == 0);
} }
static void io_tmpname (void) static void io_tmpname (void) {
{
lua_pushstring(tmpnam(NULL)); 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 */ lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
} }
@@ -308,12 +425,11 @@ static void io_clock (void) {
} }
static void io_date (void) static void io_date (void) {
{ char b[256];
time_t t;
struct tm *tm;
char *s = luaL_opt_string(1, "%c"); char *s = luaL_opt_string(1, "%c");
char b[BUFSIZ]; struct tm *tm;
time_t t;
time(&t); tm = localtime(&t); time(&t); tm = localtime(&t);
if (strftime(b,sizeof(b),s,tm)) if (strftime(b,sizeof(b),s,tm))
lua_pushstring(b); lua_pushstring(b);
@@ -322,8 +438,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, static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC,
LC_TIME}; LC_TIME};
static char *catnames[] = {"all", "collate", "ctype", "monetary", static char *catnames[] = {"all", "collate", "ctype", "monetary",
@@ -334,115 +449,140 @@ static void setloc (void)
} }
static void io_exit (void) static void io_exit (void) {
{
lua_Object o = lua_getparam(1); lua_Object o = lua_getparam(1);
exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 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]; char buffer[250];
fprintf(stderr, "lua_debug> "); fprintf(stderr, "lua_debug> ");
if (fgets(buffer, sizeof(buffer), stdin) == 0) return; if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
if (strcmp(buffer, "cont\n") == 0) return; strcmp(buffer, "cont\n") == 0)
return;
lua_dostring(buffer); lua_dostring(buffer);
} }
} }
static void lua_printstack (FILE *f)
{ #define MESSAGESIZE 150
#define MAXMESSAGE (MESSAGESIZE*10)
#define MAXSRC 40
static void errorfb (void) {
char buff[MAXMESSAGE];
int level = 1; /* skip level 0 (it's this function) */ int level = 1; /* skip level 0 (it's this function) */
lua_Object func; lua_Object func;
sprintf(buff, "lua error: %.200s\n", lua_getstring(lua_getparam(1)));
while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) { while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
char *name; char *name;
int currentline; int currentline;
char *filename; char *chunkname;
char buffchunk[MAXSRC];
int linedefined; int linedefined;
lua_funcinfo(func, &filename, &linedefined); lua_funcinfo(func, &chunkname, &linedefined);
fprintf(f, (level==2) ? "Active Stack:\n\t" : "\t"); luaL_chunkid(buffchunk, chunkname, sizeof(buffchunk));
if (level == 2) strcat(buff, "Active Stack:\n");
strcat(buff, "\t");
if (strlen(buff) > MAXMESSAGE-MESSAGESIZE) {
strcat(buff, "...\n");
break; /* buffer is full */
}
switch (*lua_getobjname(func, &name)) { switch (*lua_getobjname(func, &name)) {
case 'g': case 'g':
fprintf(f, "function %s", name); sprintf(buff+strlen(buff), "function `%.50s'", name);
break; break;
case 't': case 't':
fprintf(f, "`%s' tag method", name); sprintf(buff+strlen(buff), "`%.50s' tag method", name);
break; break;
default: { default: {
if (linedefined == 0) if (linedefined == 0)
fprintf(f, "main of %s", filename); sprintf(buff+strlen(buff), "main of %.50s", buffchunk);
else if (linedefined < 0) else if (linedefined < 0)
fprintf(f, "%s", filename); sprintf(buff+strlen(buff), "%.50s", buffchunk);
else else
fprintf(f, "function (%s:%d)", filename, linedefined); sprintf(buff+strlen(buff), "function <%d:%.50s>",
filename = NULL; linedefined, buffchunk);
chunkname = NULL;
} }
} }
if ((currentline = lua_currentline(func)) > 0) if ((currentline = lua_currentline(func)) > 0)
fprintf(f, " at line %d", currentline); sprintf(buff+strlen(buff), " at line %d", currentline);
if (filename) if (chunkname)
fprintf(f, " [in file %s]", filename); sprintf(buff+strlen(buff), " [%.50s]", buffchunk);
fprintf(f, "\n"); 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[] = { static struct luaL_reg iolib[] = {
{"setlocale", setloc}, {"_ERRORMESSAGE", errorfb},
{"execute", io_execute}, {"clock", io_clock},
{"remove", io_remove}, {"date", io_date},
{"rename", io_rename}, {"debug", io_debug},
{"tmpname", io_tmpname}, {"execute", io_execute},
{"getenv", io_getenv}, {"exit", io_exit},
{"date", io_date}, {"getenv", io_getenv},
{"clock", io_clock}, {"remove", io_remove},
{"exit", io_exit}, {"rename", io_rename},
{"debug", io_debug}, {"setlocale", setloc},
{"print_stack", errorfb} {"tmpname", io_tmpname}
}; };
static struct luaL_reg iolibtag[] = { static struct luaL_reg iolibtag[] = {
{"readfrom", io_readfrom}, {"appendto", io_appendto},
{"writeto", io_writeto}, {"closefile", io_close},
{"appendto", io_appendto}, {"flush", io_flush},
{"read", io_read}, {"openfile", io_open},
{"write", io_write} {"read", io_read},
{"readfrom", io_readfrom},
{"seek", io_seek},
{"write", io_write},
{"writeto", io_writeto}
}; };
static void openwithtags (void)
{ static void openwithtags (void) {
int iotag = lua_newtag();
int closedtag = lua_newtag();
int i; 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++) { 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(iotag);
lua_pushnumber(closedtag); lua_pushcclosure(iolibtag[i].func, 1);
lua_pushcclosure(iolibtag[i].func, 2);
lua_setglobal(iolibtag[i].name); lua_setglobal(iolibtag[i].name);
} }
/* predefined file handles */
setfile(stdin, FINPUT, iotag); setfile(stdin, FINPUT, iotag);
setfile(stdout, FOUTPUT, iotag); setfile(stdout, FOUTPUT, iotag);
setfile(stdin, "_STDIN", iotag); setfile(stdin, "_STDIN", iotag);
setfile(stdout, "_STDOUT", iotag); setfile(stdout, "_STDOUT", iotag);
setfile(stderr, "_STDERR", 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]))); luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
openwithtags(); openwithtags();
lua_pushcfunction(errorfb);
lua_seterrormethod();
} }

109
llex.c
View File

@@ -1,6 +1,6 @@
/* /*
** $Id: llex.c,v 1.22 1998/06/19 18:47:06 roberto Exp roberto $ ** $Id: llex.c,v 1.33 1999/03/11 18:59:19 roberto Exp roberto $
** Lexical Analizer ** Lexical Analyzer
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -20,9 +20,6 @@
int lua_debug=0;
#define next(LS) (LS->current = zgetc(LS->lex_z)) #define next(LS) (LS->current = zgetc(LS->lex_z))
@@ -35,8 +32,7 @@ char *reserved [] = {"and", "do", "else", "elseif", "end", "function",
"until", "while"}; "until", "while"};
void luaX_init (void) void luaX_init (void) {
{
int i; int i;
for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
TaggedString *ts = luaS_new(reserved[i]); TaggedString *ts = luaS_new(reserved[i]);
@@ -45,24 +41,28 @@ void luaX_init (void)
} }
#define MAXSRC 40
void luaX_syntaxerror (LexState *ls, char *s, char *token) { 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>"; token = "<eof>";
luaL_verror("%.100s;\n last token read: `%.50s' at line %d in chunk `%.50s'", luaL_verror("%.100s;\n last token read: `%.50s' at line %d in %.50s",
s, token, ls->linenumber, zname(ls->lex_z)); s, token, ls->linenumber, buff);
} }
void luaX_error (LexState *ls, char *s) { void luaX_error (LexState *ls, char *s) {
save(0); save('\0');
luaX_syntaxerror(ls, s, luaL_buffer()); 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) { if (token < 255) {
s[0] = token; s[0] = (char)token;
s[1] = 0; s[1] = '\0';
} }
else else
strcpy(s, reserved[token-FIRST_RESERVED]); strcpy(s, reserved[token-FIRST_RESERVED]);
@@ -71,7 +71,7 @@ void luaX_token2str (LexState *ls, int token, char *s) {
static void luaX_invalidchar (LexState *ls, int c) { static void luaX_invalidchar (LexState *ls, int c) {
char buff[10]; char buff[10];
sprintf(buff, "0x%X", c); sprintf(buff, "0x%02X", c);
luaX_syntaxerror(ls, "invalid control char", buff); luaX_syntaxerror(ls, "invalid control char", buff);
} }
@@ -138,7 +138,7 @@ static void readname (LexState *LS, char *buff)
buff[PRAGMASIZE] = 0; buff[PRAGMASIZE] = 0;
luaX_syntaxerror(LS, "pragma too long", buff); luaX_syntaxerror(LS, "pragma too long", buff);
} }
buff[i++] = LS->current; buff[i++] = (char)LS->current;
next(LS); next(LS);
} }
buff[i] = 0; buff[i] = 0;
@@ -174,10 +174,10 @@ static void inclinenumber (LexState *LS)
readname(LS, buff); readname(LS, buff);
switch (luaL_findstring(buff, pragmas)) { switch (luaL_findstring(buff, pragmas)) {
case 0: /* debug */ case 0: /* debug */
if (!skip) lua_debug = 1; if (!skip) L->debug = 1;
break; break;
case 1: /* nodebug */ case 1: /* nodebug */
if (!skip) lua_debug = 0; if (!skip) L->debug = 0;
break; break;
case 2: /* endinput */ case 2: /* endinput */
if (!skip) { if (!skip) {
@@ -221,6 +221,7 @@ static void inclinenumber (LexState *LS)
} }
/* /*
** ======================================================= ** =======================================================
** LEXICAL ANALIZER ** LEXICAL ANALIZER
@@ -229,12 +230,9 @@ static void inclinenumber (LexState *LS)
static int read_long_string (LexState *LS) {
static int read_long_string (LexState *LS)
{
int cont = 0; int cont = 0;
while (1) { for (;;) {
switch (LS->current) { switch (LS->current) {
case EOZ: case EOZ:
luaX_error(LS, "unfinished long string"); luaX_error(LS, "unfinished long string");
@@ -262,17 +260,16 @@ static int read_long_string (LexState *LS)
save_and_next(LS); save_and_next(LS);
} }
} endloop: } endloop:
save_and_next(LS); /* pass the second ']' */ save_and_next(LS); /* skip the second ']' */
LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+2, LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+2),
L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4); L->Mbuffnext-L->Mbuffbase-4);
return STRING; return STRING;
} }
int luaX_lex (LexState *LS) { int luaX_lex (LexState *LS) {
double a;
luaL_resetbuffer(); luaL_resetbuffer();
while (1) { for (;;) {
switch (LS->current) { switch (LS->current) {
case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */ case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
@@ -347,7 +344,7 @@ int luaX_lex (LexState *LS) {
c = 10*c + (LS->current-'0'); c = 10*c + (LS->current-'0');
next(LS); next(LS);
} while (++i<3 && isdigit(LS->current)); } while (++i<3 && isdigit(LS->current));
if (c >= 256) if (c != (unsigned char)c)
luaX_error(LS, "escape sequence too large"); luaX_error(LS, "escape sequence too large");
save(c); save(c);
} }
@@ -364,8 +361,8 @@ int luaX_lex (LexState *LS) {
} }
} }
save_and_next(LS); /* skip delimiter */ save_and_next(LS); /* skip delimiter */
LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+1, LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+1),
L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-2); L->Mbuffnext-L->Mbuffbase-2);
return STRING; return STRING;
} }
@@ -382,15 +379,11 @@ int luaX_lex (LexState *LS) {
else return CONC; /* .. */ else return CONC; /* .. */
} }
else if (!isdigit(LS->current)) return '.'; else if (!isdigit(LS->current)) return '.';
/* LS->current is a digit: goes through to number */ goto fraction; /* LS->current is a digit: goes through to number */
a=0.0;
goto fraction;
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
a=0.0;
do { do {
a = 10.0*a + (LS->current-'0');
save_and_next(LS); save_and_next(LS);
} while (isdigit(LS->current)); } while (isdigit(LS->current));
if (LS->current == '.') { if (LS->current == '.') {
@@ -402,35 +395,19 @@ int luaX_lex (LexState *LS) {
} }
} }
fraction: fraction:
{ double da=0.1; while (isdigit(LS->current))
while (isdigit(LS->current)) save_and_next(LS);
{ if (toupper(LS->current) == 'E') {
a += (LS->current-'0')*da; save_and_next(LS); /* read 'E' */
da /= 10.0; save_and_next(LS); /* read '+', '-' or first digit */
while (isdigit(LS->current))
save_and_next(LS); 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: case EOZ:
if (LS->iflevel > 0) if (LS->iflevel > 0)
@@ -450,9 +427,9 @@ int luaX_lex (LexState *LS) {
do { do {
save_and_next(LS); save_and_next(LS);
} while (isalnum(LS->current) || LS->current == '_'); } while (isalnum(LS->current) || LS->current == '_');
save(0); save('\0');
ts = luaS_new(L->Mbuffbase); ts = luaS_new(L->Mbuffer+L->Mbuffbase);
if (ts->head.marked >= 'A') if (ts->head.marked >= FIRST_RESERVED)
return ts->head.marked; /* reserved word */ return ts->head.marked; /* reserved word */
LS->seminfo.ts = ts; LS->seminfo.ts = ts;
return NAME; return NAME;

8
llex.h
View File

@@ -1,6 +1,6 @@
/* /*
** $Id: llex.h,v 1.8 1998/05/27 13:03:40 roberto Exp roberto $ ** $Id: llex.h,v 1.10 1998/07/24 18:02:38 roberto Exp roberto $
** Lexical Analizer ** Lexical Analyzer
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -30,7 +30,7 @@ enum RESERVED {
/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */ /* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
struct ifState { 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 condition; /* true if $if condition is true */
int skip; /* true if part must be skipped */ int skip; /* true if part must be skipped */
}; };
@@ -56,7 +56,7 @@ void luaX_setinput (LexState *LS, ZIO *z);
int luaX_lex (LexState *LS); int luaX_lex (LexState *LS);
void luaX_syntaxerror (LexState *ls, char *s, char *token); void luaX_syntaxerror (LexState *ls, char *s, char *token);
void luaX_error (LexState *ls, char *s); void luaX_error (LexState *ls, char *s);
void luaX_token2str (LexState *ls, int token, char *s); void luaX_token2str (int token, char *s);
#endif #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.15 1999/01/04 12:41:12 roberto Exp roberto $
** Lua standard mathematical library ** Lua standard mathematical library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -12,107 +12,95 @@
#include "lua.h" #include "lua.h"
#include "lualib.h" #include "lualib.h"
#ifdef M_PI
#define PI M_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 #else
#define PI ((double)3.14159265358979323846) #define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
#define TORAD(a) ((a)*RADIANS_PER_DEGREE)
#endif #endif
#define FROMRAD(a) ((a)*(180.0/PI)) static void math_abs (void) {
#define TORAD(a) ((a)*(PI/180.0)) lua_pushnumber(fabs(luaL_check_number(1)));
static void math_abs (void)
{
double d = luaL_check_number(1);
if (d < 0) d = -d;
lua_pushnumber(d);
} }
static void math_sin (void) static void math_sin (void) {
{
lua_pushnumber(sin(TORAD(luaL_check_number(1)))); 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)))); 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)))); 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)))); 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)))); 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)))); 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)))); 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))); lua_pushnumber(ceil(luaL_check_number(1)));
} }
static void math_floor (void) static void math_floor (void) {
{
lua_pushnumber(floor(luaL_check_number(1))); 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))); 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))); 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))); 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))); lua_pushnumber(log(luaL_check_number(1)));
} }
static void math_log10 (void) static void math_log10 (void) {
{
lua_pushnumber(log10(luaL_check_number(1))); lua_pushnumber(log10(luaL_check_number(1)));
} }
static void math_exp (void) static void math_exp (void) {
{
lua_pushnumber(exp(luaL_check_number(1))); lua_pushnumber(exp(luaL_check_number(1)));
} }
static void math_deg (void) static void math_deg (void) {
{ lua_pushnumber(luaL_check_number(1)/RADIANS_PER_DEGREE);
lua_pushnumber(luaL_check_number(1)*(180.0/PI));
} }
static void math_rad (void) static void math_rad (void) {
{ lua_pushnumber(luaL_check_number(1)*RADIANS_PER_DEGREE);
lua_pushnumber(luaL_check_number(1)*(PI/180.0));
} }
static void math_frexp (void) { static void math_frexp (void) {
@@ -122,13 +110,12 @@ static void math_frexp (void) {
} }
static void math_ldexp (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; int i = 1;
double dmin = luaL_check_number(i); double dmin = luaL_check_number(i);
while (lua_getparam(++i) != LUA_NOOBJECT) { while (lua_getparam(++i) != LUA_NOOBJECT) {
@@ -140,8 +127,7 @@ static void math_min (void)
} }
static void math_max (void) static void math_max (void) {
{
int i = 1; int i = 1;
double dmax = luaL_check_number(i); double dmax = luaL_check_number(i);
while (lua_getparam(++i) != LUA_NOOBJECT) { while (lua_getparam(++i) != LUA_NOOBJECT) {
@@ -153,22 +139,27 @@ static void math_max (void)
} }
static void math_random (void) static void math_random (void) {
{ /* the '%' avoids the (rare) case of r==1, and is needed also because on
/* the '%' is needed because on some systems (SunOS!) "rand()" may */ some systems (SunOS!) "rand()" may return a value bigger than RAND_MAX */
/* return a value bigger than RAND_MAX... */
double r = (double)(rand()%RAND_MAX) / (double)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) if (l == 0)
lua_pushnumber(r); lua_pushnumber(r);
else else {
lua_pushnumber((int)(r*l)+1); 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) static void math_randomseed (void) {
{ srand(luaL_check_int(1));
srand(luaL_check_number(1));
} }
@@ -201,10 +192,8 @@ static struct luaL_reg mathlib[] = {
/* /*
** Open math library ** Open math library
*/ */
void lua_mathlibopen (void) void lua_mathlibopen (void) {
{
luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0]))); luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
lua_pushstring("deg"); lua_setglobal("_TRIGMODE");
lua_pushcfunction(math_pow); lua_pushcfunction(math_pow);
lua_pushnumber(0); /* to get its tag */ lua_pushnumber(0); /* to get its tag */
lua_settagmethod(lua_tag(lua_pop()), "pow"); lua_settagmethod(lua_tag(lua_pop()), "pow");

90
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.13 1999/02/26 15:50:10 roberto Exp roberto $
** Interface to Memory Manager ** Interface to Memory Manager
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -12,41 +12,59 @@
#include "lua.h" #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) #define MINSIZE 16 /* minimum size for "growing" vectors */
{
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;
}
#ifndef DEBUG #ifndef DEBUG
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 ^ 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 */
if (newn >= limit)
lua_error(errormsg);
newn = power2(newn);
if (newn > limit)
newn = limit;
return luaM_realloc(block, newn*size);
}
}
/* /*
** generic allocation routine. ** 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; size_t s = (size_t)size;
if (s != size) if (s != size)
lua_error("Allocation Error: Block too big"); lua_error("memory allocation error: block too big");
if (size == 0) { if (size == 0) {
if (block) { free(block); /* block may be NULL, that is OK for free */
free(block);
}
return NULL; return NULL;
} }
block = block ? realloc(block, s) : malloc(s); block = realloc(block, s);
if (block == NULL) if (block == NULL)
lua_error(memEM); lua_error(memEM);
return block; return block;
@@ -60,6 +78,15 @@ void *luaM_realloc (void *block, unsigned long size)
#include <string.h> #include <string.h>
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);
return luaM_realloc(block, newn*size);
}
#define HEADER (sizeof(double)) #define HEADER (sizeof(double))
#define MARK 55 #define MARK 55
@@ -68,8 +95,7 @@ unsigned long numblocks = 0;
unsigned long totalmem = 0; unsigned long totalmem = 0;
static void *checkblock (void *block) static void *checkblock (void *block) {
{
unsigned long *b = (unsigned long *)((char *)block - HEADER); unsigned long *b = (unsigned long *)((char *)block - HEADER);
unsigned long size = *b; unsigned long size = *b;
LUA_ASSERT(*(((char *)b)+size+HEADER) == MARK, LUA_ASSERT(*(((char *)b)+size+HEADER) == MARK,
@@ -80,26 +106,22 @@ static void *checkblock (void *block)
} }
void *luaM_realloc (void *block, unsigned long size) void *luaM_realloc (void *block, unsigned long size) {
{
unsigned long realsize = HEADER+size+1; unsigned long realsize = HEADER+size+1;
if (realsize != (size_t)realsize) if (realsize != (size_t)realsize)
lua_error("Allocation Error: Block too big"); lua_error("memory allocation error: block too big");
if (size == 0) { /* ANSI dosen't need this, but some machines... */ if (size == 0) {
if (block) { if (block) {
unsigned long *b = (unsigned long *)((char *)block - HEADER); unsigned long *b = (unsigned long *)((char *)block - HEADER);
memset(block, -1, *b); /* erase block */ memset(block, -1, *b); /* erase block */
block = checkblock(block); block = checkblock(block);
free(block);
} }
free(block);
return NULL; return NULL;
} }
if (block) { if (block)
block = checkblock(block); block = checkblock(block);
block = (unsigned long *)realloc(block, realsize); block = (unsigned long *)realloc(block, realsize);
}
else
block = (unsigned long *)malloc(realsize);
if (block == NULL) if (block == NULL)
lua_error(memEM); lua_error(memEM);
totalmem += size; totalmem += size;

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 ** Interface to Memory Manager
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -8,10 +8,7 @@
#define lmem_h #define lmem_h
#ifndef NULL #include <stdlib.h>
#define NULL 0
#endif
/* memory error messages */ /* memory error messages */
#define codeEM "code size overflow" #define codeEM "code size overflow"
@@ -19,18 +16,19 @@
#define refEM "reference table overflow" #define refEM "reference table overflow"
#define tableEM "table overflow" #define tableEM "table overflow"
#define memEM "not enough memory" #define memEM "not enough memory"
#define arrEM "internal array bigger than `int' limit"
void *luaM_realloc (void *oldblock, unsigned long size); 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); char *errormsg, unsigned long limit);
#define luaM_free(b) luaM_realloc((b), 0) #define luaM_free(b) luaM_realloc((b), 0)
#define luaM_malloc(t) luaM_realloc(NULL, (t)) #define luaM_malloc(t) luaM_realloc(NULL, (t))
#define luaM_new(t) ((t *)luaM_malloc(sizeof(t))) #define luaM_new(t) ((t *)luaM_malloc(sizeof(t)))
#define luaM_newvector(n,t) ((t *)luaM_malloc((n)*sizeof(t))) #define luaM_newvector(n,t) ((t *)luaM_malloc((n)*sizeof(t)))
#define luaM_growvector(old,n,t,e,l) \ #define luaM_growvector(v,nelems,inc,t,e,l) \
(luaM_growaux((void**)old,n,sizeof(t),e,l)) ((v)=(t *)luaM_growaux(v,nelems,inc,sizeof(t),e,l))
#define luaM_reallocvector(v,n,t) ((t *)luaM_realloc(v,(n)*sizeof(t))) #define luaM_reallocvector(v,n,t) ((v)=(t *)luaM_realloc(v,(n)*sizeof(t)))
#ifdef DEBUG #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 ** Some generic functions over Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
#include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include "lobject.h" #include "lobject.h"
@@ -34,14 +35,12 @@ int luaO_redimension (int oldsize)
if (dimensions[i] > oldsize) if (dimensions[i] > oldsize)
return dimensions[i]; return dimensions[i];
} }
lua_error("table overflow"); lua_error("tableEM");
return 0; /* to avoid warnings */ return 0; /* to avoid warnings */
} }
int luaO_equalObj (TObject *t1, TObject *t2) int luaO_equalval (TObject *t1, TObject *t2) {
{
if (ttype(t1) != ttype(t2)) return 0;
switch (ttype(t1)) { switch (ttype(t1)) {
case LUA_T_NIL: return 1; case LUA_T_NIL: return 1;
case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
@@ -64,20 +63,67 @@ void luaO_insertlist (GCnode *root, GCnode *node)
node->marked = 0; node->marked = 0;
} }
#ifdef OLD_ANSI #ifdef OLD_ANSI
void luaO_memup (void *dest, void *src, int size) void luaO_memup (void *dest, void *src, int size) {
{ while (size--)
char *d = dest; ((char *)dest)[size]=((char *)src)[size];
char *s = src;
while (size--) d[size]=s[size];
} }
void luaO_memdown (void *dest, void *src, int size) void luaO_memdown (void *dest, void *src, int size) {
{
char *d = dest;
char *s = src;
int i; 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 #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 ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -32,10 +32,6 @@
#define LUA_NUM_TYPE double #define LUA_NUM_TYPE double
#endif #endif
/*
** format to convert number to strings
*/
#define NUMBER_FMT "%g"
typedef LUA_NUM_TYPE real; 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) */ #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) */ typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */
@@ -75,7 +64,6 @@ typedef enum {
LUA_T_LINE = -11 LUA_T_LINE = -11
} lua_Type; } lua_Type;
#define NUM_TYPES 11
#define NUM_TAGS 7 #define NUM_TAGS 7
@@ -139,7 +127,7 @@ typedef struct TProtoFunc {
int nconsts; int nconsts;
Byte *code; /* ends with opcode ENDCODE */ Byte *code; /* ends with opcode ENDCODE */
int lineDefined; int lineDefined;
TaggedString *fileName; TaggedString *source;
struct LocVar *locvars; /* ends with line = -1 */ struct LocVar *locvars; /* ends with line = -1 */
} TProtoFunc; } TProtoFunc;
@@ -192,11 +180,17 @@ typedef struct Hash {
extern char *luaO_typenames[]; extern char *luaO_typenames[];
#define luaO_typename(o) luaO_typenames[-ttype(o)]
extern TObject luaO_nilobject; 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); int luaO_redimension (int oldsize);
void luaO_insertlist (GCnode *root, GCnode *node); void luaO_insertlist (GCnode *root, GCnode *node);
double luaO_str2d (char *s);
#ifdef OLD_ANSI #ifdef OLD_ANSI
void luaO_memup (void *dest, void *src, int size); 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.31 1999/03/05 21:16:07 roberto Exp roberto $
** Opcodes for Lua virtual machine ** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -10,172 +10,129 @@
/* /*
** NOTICE: variants of the same opcode must be consecutive: First, those ** NOTICE: variants of the same opcode must be consecutive: First, those
** with byte parameter, then with built-in parameters, and last with ** with word parameter, then with byte parameter.
** word parameter.
*/ */
typedef enum { typedef enum {
/* name parm before after side effect /* name parm before after side effect
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
ENDCODE,/* - - - */ ENDCODE,/* - - (return) */
RETCODE,/* b - (return) */
PUSHNIL,/* b - nil_0...nil_b */ CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
PUSHNIL0,/* - - nil */
PUSHNUMBER,/* b - (float)b */ TAILCALL,/* b c v_c...v_1 f (return) f(v1,...,v_c) */
PUSHNUMBER0,/* - - 0.0 */
PUSHNUMBER1,/* - - 1.0 */
PUSHNUMBER2,/* - - 2.0 */
PUSHNUMBERW,/* w - (float)w */
PUSHCONSTANT,/* b - CNST[b] */ PUSHNIL,/* b - nil_0...nil_b */
PUSHCONSTANT0,/*- - CNST[0] */ POP,/* b a_b...a_1 - */
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] */
PUSHUPVALUE,/* b - Closure[b] */ PUSHNUMBERW,/* w - (float)w */
PUSHUPVALUE0,/* - - Closure[0] */ PUSHNUMBER,/* b - (float)b */
PUSHUPVALUE1,/* - - Closure[1] */
PUSHLOCAL,/* b - LOC[b] */ PUSHNUMBERNEGW,/* w - (float)-w */
PUSHLOCAL0,/* - - LOC[0] */ PUSHNUMBERNEG,/* b - (float)-b */
PUSHLOCAL1,/* - - LOC[1] */
PUSHLOCAL2,/* - - LOC[2] */
PUSHLOCAL3,/* - - LOC[3] */
PUSHLOCAL4,/* - - LOC[4] */
PUSHLOCAL5,/* - - LOC[5] */
PUSHLOCAL6,/* - - LOC[6] */
PUSHLOCAL7,/* - - LOC[7] */
GETGLOBAL,/* b - VAR[CNST[b]] */ PUSHCONSTANTW,/*w - CNST[w] */
GETGLOBAL0,/* - - VAR[CNST[0]] */ PUSHCONSTANT,/* b - CNST[b] */
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]] */
GETTABLE,/* - i t t[i] */ PUSHUPVALUE,/* b - Closure[b] */
GETDOTTED,/* b t t[CNST[b]] */ PUSHLOCAL,/* b - LOC[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]] */
PUSHSELF,/* b t t t[CNST[b]] */ GETGLOBALW,/* w - VAR[CNST[w]] */
PUSHSELF0,/* - t t t[CNST[0]] */ GETGLOBAL,/* b - VAR[CNST[b]] */
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]] */
CREATEARRAY,/* b - newarray(size = b) */ GETTABLE,/* - i t t[i] */
CREATEARRAY0,/* - - newarray(size = 0) */
CREATEARRAY1,/* - - newarray(size = 1) */
CREATEARRAYW,/* w - newarray(size = w) */
SETLOCAL,/* b x - LOC[b]=x */ GETDOTTEDW,/* w t t[CNST[w]] */
SETLOCAL0,/* - x - LOC[0]=x */ GETDOTTED,/* b t t[CNST[b]] */
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 */
SETGLOBAL,/* b x - VAR[CNST[b]]=x */ PUSHSELFW,/* w t t t[CNST[w]] */
SETGLOBAL0,/* - x - VAR[CNST[0]]=x */ PUSHSELF,/* b t t t[CNST[b]] */
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 */
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 */ SETGLOBALW,/* w x - VAR[CNST[w]]=x */
SETLIST0,/* b v_b...v_1 t - t[i]=v_i */ SETGLOBAL,/* b x - VAR[CNST[b]]=x */
SETLISTW,/* w c v_c...v_1 t - t[i+w*FPF]=v_i */
SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */ SETTABLEPOP,/* - v i t - t[i]=v */
SETMAP0,/* - v_0 k_0 t t t[k_0]=v_0 */
EQOP,/* - y x (x==y)? 1 : nil */ SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
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 */
ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */ SETLISTW,/* w c v_c...v_1 t t t[i+w*FPF]=v_i */
ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */ SETLIST,/* b c v_c...v_1 t t t[i+b*FPF]=v_i */
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 */
CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */ SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */
CLOSUREW,/* w c v_b...v_1 closure(CNST[w], v_c...v_1) */
CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */ NEQOP,/* - y x (x~=y)? 1 : nil */
CALLFUNC0,/* b v_b...v_1 f - f(v1,...,v_b) */ EQOP,/* - y x (x==y)? 1 : nil */
CALLFUNC1,/* b v_b...v_1 f r_1 f(v1,...,v_b) */ 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 */ CLOSUREW,/* w c v_c...v_1 closure(CNST[w], v_c...v_1) */
SETLINEW,/* w - - LINE=w */ CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
POP,/* b - - TOP-=(b+1) */ SETLINEW,/* w - - LINE=w */
POP0,/* - - - TOP-=1 */ SETLINE,/* b - - LINE=b */
POP1/* - - - TOP-=2 */
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; } OpCode;
#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */ #define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */
#define LFIELDS_PER_FLUSH 64 /* lists (SETLIST) */ #define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) */
#define ZEROVARARG 64 #define ZEROVARARG 64
/* 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)
#endif #endif

520
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 $ ** $Id: lparser.h,v 1.2 1997/12/22 20:57:18 roberto Exp roberto $
** Syntax analizer and code generator ** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h ** 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.9 1999/02/25 15:17:01 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -24,11 +24,18 @@ void lua_open (void)
{ {
if (lua_state) return; if (lua_state) return;
lua_state = luaM_new(lua_State); lua_state = luaM_new(lua_State);
L->numCblocks = 0;
L->Cstack.base = 0; L->Cstack.base = 0;
L->Cstack.lua2C = 0; L->Cstack.lua2C = 0;
L->Cstack.num = 0; L->Cstack.num = 0;
L->errorJmp = NULL; L->errorJmp = NULL;
L->Mbuffer = NULL;
L->Mbuffbase = 0;
L->Mbuffsize = 0;
L->Mbuffnext = 0;
L->numCblocks = 0;
L->debug = 0;
L->callhook = NULL;
L->linehook = NULL;
L->rootproto.next = NULL; L->rootproto.next = NULL;
L->rootproto.marked = 0; L->rootproto.marked = 0;
L->rootcl.next = NULL; L->rootcl.next = NULL;
@@ -37,12 +44,9 @@ void lua_open (void)
L->rootglobal.marked = 0; L->rootglobal.marked = 0;
L->roottable.next = NULL; L->roottable.next = NULL;
L->roottable.marked = 0; L->roottable.marked = 0;
L->IMtable = NULL;
L->refArray = NULL; L->refArray = NULL;
L->refSize = 0; L->refSize = 0;
L->Mbuffsize = 0;
L->Mbuffnext = 0;
L->Mbuffbase = NULL;
L->Mbuffer = NULL;
L->GCthreshold = GARBAGE_BLOCK; L->GCthreshold = GARBAGE_BLOCK;
L->nblocks = 0; L->nblocks = 0;
luaD_init(); luaD_init();
@@ -78,9 +82,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.15 1999/02/25 15:17:01 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -11,6 +11,7 @@
#include "lobject.h" #include "lobject.h"
#include "lua.h" #include "lua.h"
#include "luadebug.h"
#define MAX_C_BLOCKS 10 #define MAX_C_BLOCKS 10
@@ -55,20 +56,21 @@ struct lua_State {
struct C_Lua_Stack Cstack; /* C2lua struct */ struct C_Lua_Stack Cstack; /* C2lua struct */
jmp_buf *errorJmp; /* current error recover point */ jmp_buf *errorJmp; /* current error recover point */
char *Mbuffer; /* global buffer */ char *Mbuffer; /* global buffer */
char *Mbuffbase; /* current first position of Mbuffer */ int Mbuffbase; /* current first position of Mbuffer */
int Mbuffsize; /* size of Mbuffer */ int Mbuffsize; /* size of Mbuffer */
int Mbuffnext; /* next position to fill in Mbuffer */ int Mbuffnext; /* next position to fill in Mbuffer */
struct C_Lua_Stack Cblocks[MAX_C_BLOCKS]; struct C_Lua_Stack Cblocks[MAX_C_BLOCKS];
int numCblocks; /* number of nested Cblocks */ int numCblocks; /* number of nested Cblocks */
int debug;
lua_CHFunction callhook;
lua_LHFunction linehook;
/* global state */ /* global state */
TObject errorim; /* error tag method */
GCnode rootproto; /* list of all prototypes */ GCnode rootproto; /* list of all prototypes */
GCnode rootcl; /* list of all closures */ GCnode rootcl; /* list of all closures */
GCnode roottable; /* list of all tables */ GCnode roottable; /* list of all tables */
GCnode rootglobal; /* list of strings with global values */ GCnode rootglobal; /* list of strings with global values */
stringtable *string_root; /* array of hash tables for strings and udata */ stringtable *string_root; /* array of hash tables for strings and udata */
struct IM *IMtable; /* table for tag methods */ struct IM *IMtable; /* table for tag methods */
int IMtable_size; /* size of IMtable */
int last_tag; /* last used tag in IMtable */ int last_tag; /* last used tag in IMtable */
struct ref *refArray; /* locked objects */ struct ref *refArray; /* locked objects */
int refSize; /* size of refArray */ int refSize; /* size of refArray */
@@ -77,10 +79,8 @@ struct lua_State {
}; };
extern lua_State *lua_state;
#define L lua_state #define L lua_state
#endif #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) ** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -14,7 +14,9 @@
#include "lua.h" #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' */ #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}}; {{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
void luaS_init (void) void luaS_init (void) {
{
int i; int i;
L->string_root = luaM_newvector(NUM_HASHS, stringtable); L->string_root = luaM_newvector(NUM_HASHS, stringtable);
for (i=0; i<NUM_HASHS; i++) { for (i=0; i<NUM_HASHS; i++) {
@@ -37,16 +38,14 @@ void luaS_init (void)
} }
static unsigned long hash_s (char *s, long l) static unsigned long hash_s (char *s, long l) {
{ unsigned long h = 0; /* seed */
unsigned long h = 0;
while (l--) while (l--)
h = ((h<<5)-h)^(unsigned char)*(s++); h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++));
return h; return h;
} }
static int newsize (stringtable *tb) static int newsize (stringtable *tb) {
{
int size = tb->size; int size = tb->size;
int realuse = 0; int realuse = 0;
int i; int i;
@@ -54,16 +53,11 @@ static int newsize (stringtable *tb)
for (i=0; i<size; i++) for (i=0; i<size; i++)
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
realuse++; realuse++;
if (2*(realuse+1) <= size) /* +1 is the new element */ return luaO_redimension((realuse+1)*2); /* +1 is the new element */
return size; /* don't need to grow, just rehash to clear EMPTYs */
else
return luaO_redimension(size);
} }
static void grow (stringtable *tb) static void grow (stringtable *tb) {
{
int ns = newsize(tb); int ns = newsize(tb);
TaggedString **newhash = luaM_newvector(ns, TaggedString *); TaggedString **newhash = luaM_newvector(ns, TaggedString *);
int i; int i;
@@ -73,10 +67,13 @@ static void grow (stringtable *tb)
tb->nuse = 0; tb->nuse = 0;
for (i=0; i<tb->size; i++) { for (i=0; i<tb->size; i++) {
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
int h = tb->hash[i]->hash%ns; unsigned long h = tb->hash[i]->hash;
while (newhash[h]) int h1 = h%ns;
h = (h+1)%ns; while (newhash[h1]) {
newhash[h] = tb->hash[i]; h1 += (h&(ns-2)) + 1; /* double hashing */
if (h1 >= ns) h1 -= ns;
}
newhash[h1] = tb->hash[i];
tb->nuse++; 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); TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
memcpy(ts->str, str, l); memcpy(ts->str, str, l);
ts->str[l] = 0; /* ending 0 */ ts->str[l] = 0; /* ending 0 */
@@ -101,8 +97,7 @@ static TaggedString *newone_s (char *str, long l, unsigned long h)
return ts; 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); TaggedString *ts = luaM_new(TaggedString);
ts->u.d.v = buff; ts->u.d.v = buff;
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; 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; return ts;
} }
static TaggedString *insert_s (char *str, long l, stringtable *tb) static TaggedString *insert_s (char *str, long l, stringtable *tb) {
{
TaggedString *ts; TaggedString *ts;
unsigned long h = hash_s(str, l); unsigned long h = hash_s(str, l);
int size = tb->size; int size = tb->size;
int i;
int j = -1; int j = -1;
int h1;
if ((long)tb->nuse*3 >= (long)size*2) { if ((long)tb->nuse*3 >= (long)size*2) {
grow(tb); grow(tb);
size = tb->size; size = tb->size;
} }
for (i = h%size; (ts = tb->hash[i]) != NULL; ) { h1 = h%size;
while ((ts = tb->hash[h1]) != NULL) {
if (ts == &EMPTY) if (ts == &EMPTY)
j = i; j = h1;
else if (ts->constindex >= 0 && else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
ts->u.s.len == l &&
(memcmp(str, ts->str, l) == 0))
return ts; return ts;
if (++i == size) i=0; h1 += (h&(size-2)) + 1; /* double hashing */
if (h1 >= size) h1 -= size;
} }
/* not found */ /* not found */
if (j != -1) /* is there an EMPTY space? */ if (j != -1) /* is there an EMPTY space? */
i = j; h1 = j;
else else
tb->nuse++; tb->nuse++;
ts = tb->hash[i] = newone_s(str, l, h); ts = tb->hash[h1] = newone_s(str, l, h);
return ts; return ts;
} }
static TaggedString *insert_u (void *buff, int tag, stringtable *tb)
{ static TaggedString *insert_u (void *buff, int tag, stringtable *tb) {
TaggedString *ts; TaggedString *ts;
unsigned long h = (unsigned long)buff; unsigned long h = (unsigned long)buff;
int size = tb->size; int size = tb->size;
int i;
int j = -1; int j = -1;
int h1;
if ((long)tb->nuse*3 >= (long)size*2) { if ((long)tb->nuse*3 >= (long)size*2) {
grow(tb); grow(tb);
size = tb->size; size = tb->size;
} }
for (i = h%size; (ts = tb->hash[i]) != NULL; ) { h1 = h%size;
while ((ts = tb->hash[h1]) != NULL) {
if (ts == &EMPTY) if (ts == &EMPTY)
j = i; j = h1;
else if (ts->constindex < 0 && /* is a udata? */ else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)
(tag == ts->u.d.tag || tag == LUA_ANYTAG) &&
buff == ts->u.d.v)
return ts; return ts;
if (++i == size) i=0; h1 += (h&(size-2)) + 1; /* double hashing */
if (h1 >= size) h1 -= size;
} }
/* not found */ /* not found */
if (j != -1) /* is there an EMPTY space? */ if (j != -1) /* is there an EMPTY space? */
i = j; h1 = j;
else else
tb->nuse++; tb->nuse++;
ts = tb->hash[i] = newone_u(buff, tag, h); ts = tb->hash[h1] = newone_u(buff, tag, h);
return ts; return ts;
} }
TaggedString *luaS_createudata (void *udata, int tag)
{ TaggedString *luaS_createudata (void *udata, int tag) {
return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]); int t = ((unsigned)udata%NUM_HASHUDATA)+NUM_HASHSTR;
return insert_u(udata, tag, &L->string_root[t]);
} }
TaggedString *luaS_newlstr (char *str, long l) TaggedString *luaS_newlstr (char *str, long l) {
{ int t = (l==0) ? 0 : ((int)((unsigned char)str[0]*l))%NUM_HASHSTR;
int i = (l==0)?0:(unsigned char)str[0]; return insert_s(str, l, &L->string_root[t]);
return insert_s(str, l, &L->string_root[i%NUM_HASHS]);
} }
TaggedString *luaS_new (char *str) TaggedString *luaS_new (char *str) {
{
return luaS_newlstr(str, strlen(str)); return luaS_newlstr(str, strlen(str));
} }
TaggedString *luaS_newfixedstring (char *str) TaggedString *luaS_newfixedstring (char *str) {
{
TaggedString *ts = luaS_new(str); TaggedString *ts = luaS_new(str);
if (ts->head.marked == 0) if (ts->head.marked == 0)
ts->head.marked = 2; /* avoid GC */ 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) { while (l) {
TaggedString *next = (TaggedString *)l->head.next; TaggedString *next = (TaggedString *)l->head.next;
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len); L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
@@ -212,8 +203,7 @@ void luaS_free (TaggedString *l)
** Garbage collection functions. ** Garbage collection functions.
*/ */
static void remove_from_list (GCnode *l) static void remove_from_list (GCnode *l) {
{
while (l) { while (l) {
GCnode *next = l->next; GCnode *next = l->next;
while (next && !next->marked) 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; TaggedString *frees = NULL;
int i; int i;
remove_from_list(&(L->rootglobal)); remove_from_list(&(L->rootglobal));
@@ -247,18 +236,18 @@ TaggedString *luaS_collector (void)
} }
TaggedString *luaS_collectudata (void) TaggedString *luaS_collectudata (void) {
{
TaggedString *frees = NULL; TaggedString *frees = NULL;
int i; int i;
L->rootglobal.next = NULL; /* empty list of globals */ 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]; stringtable *tb = &L->string_root[i];
int j; int j;
for (j=0; j<tb->size; j++) { for (j=0; j<tb->size; j++) {
TaggedString *t = tb->hash[j]; TaggedString *t = tb->hash[j];
if (t == NULL || t == &EMPTY || t->constindex != -1) if (t == NULL || t == &EMPTY)
continue; /* get only user data */ continue;
LUA_ASSERT(t->constindex == -1, "must be userdata");
t->head.next = (GCnode *)frees; t->head.next = (GCnode *)frees;
frees = t; frees = t;
tb->hash[j] = &EMPTY; tb->hash[j] = &EMPTY;
@@ -268,8 +257,7 @@ TaggedString *luaS_collectudata (void)
} }
void luaS_freeall (void) void luaS_freeall (void) {
{
int i; int i;
for (i=0; i<NUM_HASHS; i++) { for (i=0; i<NUM_HASHS; i++) {
stringtable *tb = &L->string_root[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; ts->u.s.globalval = *newval;
if (ts->head.next == (GCnode *)ts) { /* is not in list? */ if (ts->head.next == (GCnode *)ts) { /* is not in list? */
ts->head.next = L->rootglobal.next; 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; TaggedString *g;
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
if (fn(&g->u.s.globalval)) 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); TaggedString *ts = luaS_new(name);
return ts->u.s.globalval.ttype != LUA_T_NIL; return ts->u.s.globalval.ttype != LUA_T_NIL;
} }

172
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.27 1999/02/25 19:13:56 roberto Exp roberto $
** Standard library for strings and pattern-matching ** Standard library for strings and pattern-matching
** See Copyright Notice in lua.h ** 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()); 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 */ /* relative string position: negative means back from end */
return (pos>=0) ? pos : len+pos+1; return (pos>=0) ? pos : len+pos+1;
} }
static void str_sub (void) static void str_sub (void) {
{
long l; long l;
char *s = luaL_check_lstr(1, &l); char *s = luaL_check_lstr(1, &l);
long start = posrelat(luaL_check_number(2), l); long start = posrelat(luaL_check_long(2), l);
long end = posrelat(luaL_opt_number(3, -1), l); long end = posrelat(luaL_opt_long(3, -1), l);
if (1 <= start && start <= end && end <= l) if (start < 1) start = 1;
if (end > l) end = l;
if (start <= end)
lua_pushlstring(s+start-1, end-start+1); lua_pushlstring(s+start-1, end-start+1);
else lua_pushstring(""); else lua_pushstring("");
} }
static void str_lower (void) static void str_lower (void) {
{
long l; long l;
int i; int i;
char *s = luaL_check_lstr(1, &l); 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; long l;
int i; int i;
char *s = luaL_check_lstr(1, &l); char *s = luaL_check_lstr(1, &l);
@@ -84,7 +81,7 @@ static void str_rep (void)
{ {
long l; long l;
char *s = luaL_check_lstr(1, &l); char *s = luaL_check_lstr(1, &l);
int n = (int)luaL_check_number(2); int n = luaL_check_int(2);
luaL_resetbuffer(); luaL_resetbuffer();
while (n-- > 0) while (n-- > 0)
addnchar(s, l); addnchar(s, l);
@@ -92,29 +89,30 @@ static void str_rep (void)
} }
static void str_byte (void) static void str_byte (void) {
{
long l; long l;
char *s = luaL_check_lstr(1, &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"); luaL_arg_check(0<pos && pos<=l, 2, "out of range");
lua_pushnumber((unsigned char)s[pos-1]); lua_pushnumber((unsigned char)s[pos-1]);
} }
static void str_char (void) { static void str_char (void) {
int i = 0; int i = 0;
luaL_resetbuffer(); luaL_resetbuffer();
while (lua_getparam(++i) != LUA_NOOBJECT) { while (lua_getparam(++i) != LUA_NOOBJECT) {
double c = luaL_check_number(i); double c = luaL_check_number(i);
luaL_arg_check((unsigned char)c == c, i, "invalid value"); luaL_arg_check((unsigned char)c == c, i, "invalid value");
luaL_addchar((int)c); luaL_addchar((unsigned char)c);
} }
closeandpush(); closeandpush();
} }
/* /*
** ======================================================= ** {======================================================
** PATTERN MATCHING ** PATTERN MATCHING
** ======================================================= ** =======================================================
*/ */
@@ -122,8 +120,8 @@ static void str_char (void) {
#define MAX_CAPT 9 #define MAX_CAPT 9
struct Capture { struct Capture {
int level; /* total number of captures (finished or unfinished) */
char *src_end; /* end ('\0') of source string */ char *src_end; /* end ('\0') of source string */
int level; /* total number of captures (finished or unfinished) */
struct { struct {
char *init; char *init;
int len; /* -1 signals unfinished capture */ int len; /* -1 signals unfinished capture */
@@ -135,16 +133,17 @@ struct Capture {
#define SPECIALS "^$*?.([%-" #define SPECIALS "^$*?.([%-"
static void push_captures (struct Capture *cap) static void push_captures (struct Capture *cap) {
{
int i; int i;
for (i=0; i<cap->level; i++) for (i=0; i<cap->level; i++) {
lua_pushlstring(cap->capture[i].init, cap->capture[i].len); 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'; l -= '1';
if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
lua_error("invalid capture index"); lua_error("invalid capture index");
@@ -152,8 +151,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; int level = cap->level;
for (level--; level>=0; level--) for (level--; level>=0; level--)
if (cap->capture[level].len == -1) return level; if (cap->capture[level].len == -1) return level;
@@ -162,14 +160,12 @@ static int capture_to_close (struct Capture *cap)
} }
static char *bracket_end (char *p) static char *bracket_end (char *p) {
{
return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']'); return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']');
} }
static int matchclass (int c, int cl) static int matchclass (int c, int cl) {
{
int res; int res;
switch (tolower(cl)) { switch (tolower(cl)) {
case 'a' : res = isalpha(c); break; case 'a' : res = isalpha(c); break;
@@ -180,15 +176,15 @@ static int matchclass (int c, int cl)
case 's' : res = isspace(c); break; case 's' : res = isspace(c); break;
case 'u' : res = isupper(c); break; case 'u' : res = isupper(c); break;
case 'w' : res = isalnum(c); break; case 'w' : res = isalnum(c); break;
case 'x' : res = isxdigit(c); break;
case 'z' : res = (c == '\0'); break; case 'z' : res = (c == '\0'); break;
default: return (cl == c); 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) int luaI_singlematch (int c, char *p, char **ep) {
{
switch (*p) { switch (*p) {
case '.': /* matches any char */ case '.': /* matches any char */
*ep = p+1; *ep = p+1;
@@ -213,7 +209,7 @@ int luaI_singlematch (int c, char *p, char **ep)
} }
else if ((*(p+1) == '-') && (p+2 < end)) { else if ((*(p+1) == '-') && (p+2 < end)) {
p+=2; p+=2;
if ((unsigned char)*(p-2) <= c && c <= (unsigned char)*p) if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p)
return sig; return sig;
} }
else if ((unsigned char)*p == c) return sig; else if ((unsigned char)*p == c) return sig;
@@ -227,8 +223,7 @@ int luaI_singlematch (int c, char *p, char **ep)
} }
static char *matchbalance (char *s, int b, int e, struct Capture *cap) static char *matchbalance (char *s, int b, int e, struct Capture *cap) {
{
if (*s != b) return NULL; if (*s != b) return NULL;
else { else {
int cont = 1; int cont = 1;
@@ -243,8 +238,7 @@ static char *matchbalance (char *s, int b, int e, struct Capture *cap)
} }
static char *matchitem (char *s, char *p, struct Capture *cap, char **ep) static char *matchitem (char *s, char *p, struct Capture *cap, char **ep) {
{
if (*p == ESC) { if (*p == ESC) {
p++; p++;
if (isdigit((unsigned char)*p)) { /* capture */ if (isdigit((unsigned char)*p)) { /* capture */
@@ -264,14 +258,13 @@ static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
} }
else p--; /* and go through */ else p--; /* and go through */
} }
/* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */ /* "luaI_singlematch" sets "ep" (so must be called even at the end of "s" */
return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ? return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ?
s+1 : NULL; s+1 : NULL;
} }
static char *match (char *s, char *p, struct Capture *cap) static char *match (char *s, char *p, struct Capture *cap) {
{
init: /* using goto's to optimize tail recursion */ init: /* using goto's to optimize tail recursion */
switch (*p) { switch (*p) {
case '(': { /* start capture */ case '(': { /* start capture */
@@ -297,7 +290,7 @@ static char *match (char *s, char *p, struct Capture *cap)
return s; return s;
/* else go through */ /* else go through */
default: { /* it is a pattern item */ default: { /* it is a pattern item */
char *ep; /* get what is next */ char *ep; /* will point to what is next */
char *s1 = matchitem(s, p, cap, &ep); char *s1 = matchitem(s, p, cap, &ep);
switch (*ep) { switch (*ep) {
case '*': { /* repetition */ case '*': { /* repetition */
@@ -332,12 +325,11 @@ static char *match (char *s, char *p, struct Capture *cap)
} }
static void str_find (void) static void str_find (void) {
{
long l; long l;
char *s = luaL_check_lstr(1, &l); char *s = luaL_check_lstr(1, &l);
char *p = luaL_check_string(2); 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; struct Capture cap;
luaL_arg_check(0 <= init && init <= l, 3, "out of range"); luaL_arg_check(0 <= init && init <= l, 3, "out of range");
if (lua_getparam(4) != LUA_NOOBJECT || if (lua_getparam(4) != LUA_NOOBJECT ||
@@ -368,8 +360,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)) { if (lua_isstring(newp)) {
char *news = lua_getstring(newp); char *news = lua_getstring(newp);
int l = lua_strlen(newp); int l = lua_strlen(newp);
@@ -411,13 +402,12 @@ static void add_s (lua_Object newp, struct Capture *cap)
} }
static void str_gsub (void) static void str_gsub (void) {
{
long srcl; long srcl;
char *src = luaL_check_lstr(1, &srcl); char *src = luaL_check_lstr(1, &srcl);
char *p = luaL_check_string(2); char *p = luaL_check_string(2);
lua_Object newp = lua_getparam(3); 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 anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0; int n = 0;
struct Capture cap; struct Capture cap;
@@ -445,26 +435,33 @@ static void str_gsub (void)
lua_pushnumber(n); /* number of substitutions */ 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('"'); luaL_addchar('"');
for (; *s; s++) { while (l--) {
if (strchr("\"\\\n", *s)) switch (*s) {
luaL_addchar('\\'); case '"': case '\\': case '\n':
luaL_addchar(*s); luaL_addchar('\\');
luaL_addchar(*s);
break;
case '\0': addnchar("\\000", 4); break;
default: luaL_addchar(*s);
}
s++;
} }
luaL_addchar('"'); luaL_addchar('"');
} }
#define MAX_FORMAT 200 /* maximum size of each format specification (such as '%-099.99d') */
#define MAX_FORMAT 20
static void str_format (void) static void str_format (void) {
{
int arg = 1; int arg = 1;
char *strfrmt = luaL_check_string(arg); char *strfrmt = luaL_check_string(arg);
struct Capture cap;
cap.src_end = strfrmt+strlen(strfrmt)+1;
luaL_resetbuffer(); luaL_resetbuffer();
while (*strfrmt) { while (*strfrmt) {
if (*strfrmt != '%') if (*strfrmt != '%')
@@ -472,34 +469,28 @@ static void str_format (void)
else if (*++strfrmt == '%') else if (*++strfrmt == '%')
luaL_addchar(*strfrmt++); /* %% */ luaL_addchar(*strfrmt++); /* %% */
else { /* format item */ else { /* format item */
char form[MAX_FORMAT]; /* store the format ('%...') */ struct Capture cap;
char *buff; char form[MAX_FORMAT]; /* to store the format ('%...') */
char *buff; /* to store the formatted item */
char *initf = strfrmt; char *initf = strfrmt;
form[0] = '%'; form[0] = '%';
cap.level = 0; if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
if (isdigit((unsigned char)initf[0]) && initf[1] == '$') { arg = *initf - '0';
arg = initf[0] - '0';
initf += 2; /* skip the 'n$' */ initf += 2; /* skip the 'n$' */
} }
arg++; arg++;
cap.src_end = strfrmt+strlen(strfrmt)+1;
cap.level = 0;
strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); 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)"); lua_error("invalid format (width or precision too long)");
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
form[strfrmt-initf+2] = 0; 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++) { 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': case 'c': case 'd': case 'i':
sprintf(buff, form, (int)luaL_check_number(arg)); sprintf(buff, form, luaL_check_int(arg));
break; break;
case 'o': case 'u': case 'x': case 'X': case 'o': case 'u': case 'x': case 'X':
sprintf(buff, form, (unsigned int)luaL_check_number(arg)); sprintf(buff, form, (unsigned int)luaL_check_number(arg));
@@ -507,6 +498,23 @@ static void str_format (void)
case 'e': case 'E': case 'f': case 'g': case 'G': case 'e': case 'E': case 'f': case 'g': case 'G':
sprintf(buff, form, luaL_check_number(arg)); sprintf(buff, form, luaL_check_number(arg));
break; 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' */ default: /* also treat cases 'pnLlh' */
lua_error("invalid option in `format'"); lua_error("invalid option in `format'");
} }
@@ -524,7 +532,7 @@ static struct luaL_reg strlib[] = {
{"strupper", str_upper}, {"strupper", str_upper},
{"strchar", str_char}, {"strchar", str_char},
{"strrep", str_rep}, {"strrep", str_rep},
{"ascii", str_byte}, /* for compatibility */ {"ascii", str_byte}, /* for compatibility with 3.0 and earlier */
{"strbyte", str_byte}, {"strbyte", str_byte},
{"format", str_format}, {"format", str_format},
{"strfind", str_find}, {"strfind", str_find},

182
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.20 1999/01/25 17:41:19 roberto Exp roberto $
** Lua tables (hash) ** Lua tables (hash)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -20,14 +20,11 @@
#define nodevector(t) ((t)->node) #define nodevector(t) ((t)->node)
#define REHASH_LIMIT 0.70 /* avoid more than this % full */
#define TagDefault LUA_T_ARRAY; #define TagDefault LUA_T_ARRAY;
static long int hashindex (TObject *ref) static long int hashindex (TObject *ref) {
{
long int h; long int h;
switch (ttype(ref)) { switch (ttype(ref)) {
case LUA_T_NUMBER: 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); int tsize = nhash(t);
long int h = hashindex(key); long int h = hashindex(key);
int h1 = h%tsize; int h1 = h%tsize;
TObject *rf = ref(node(t, h1)); Node *n = node(t, h1);
if (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf)) { /* keep looking until an entry with "ref" equal to key or nil */
int h2 = h%(tsize-2) + 1; while ((ttype(ref(n)) == ttype(key)) ? !luaO_equalval(key, ref(n))
do { : ttype(ref(n)) != LUA_T_NIL) {
h1 += h2; h1 += (h&(tsize-2)) + 1; /* double hashing */
if (h1 >= tsize) h1 -= tsize; if (h1 >= tsize) h1 -= tsize;
rf = ref(node(t, h1)); n = node(t, h1);
} while (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf));
} }
return h1; return n;
} }
/* void luaH_free (Hash *frees) {
** 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)
{
while (frees) { while (frees) {
Hash *next = (Hash *)frees->head.next; Hash *next = (Hash *)frees->head.next;
L->nblocks -= gcsize(frees->nhash); L->nblocks -= gcsize(frees->nhash);
hashdelete(frees); luaM_free(nodevector(frees));
luaM_free(frees);
frees = next; 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); Hash *t = luaM_new(Hash);
nhash = luaO_redimension((int)((float)nhash/REHASH_LIMIT)); nhash = luaO_redimension(nhash*3/2);
nodevector(t) = hashnodecreate(nhash); nodevector(t) = hashnodecreate(nhash);
nhash(t) = nhash; nhash(t) = nhash;
nuse(t) = 0; nuse(t) = 0;
@@ -121,96 +102,75 @@ Hash *luaH_new (int nhash)
} }
static int newsize (Hash *t) static int newsize (Hash *t) {
{
Node *v = t->node; Node *v = t->node;
int size = nhash(t); int size = nhash(t);
int realuse = 0; int realuse = 0;
int i; int i;
for (i=0; i<size; 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++; realuse++;
} }
if (2*(realuse+1) <= size) /* +1 is the new element */ return luaO_redimension((realuse+1)*2); /* +1 is the new element */
return size; /* don't need to grow, just rehash */
else
return luaO_redimension(size);
} }
static void rehash (Hash *t)
{ static void rehash (Hash *t) {
int nold = nhash(t); int nold = nhash(t);
Node *vold = nodevector(t); Node *vold = nodevector(t);
int nnew = newsize(t); int nnew = newsize(t);
int i; int i;
nodevector(t) = hashnodecreate(nnew); nodevector(t) = hashnodecreate(nnew);
nhash(t) = nnew; nhash(t) = nnew;
nuse(t) = 0;
for (i=0; i<nold; i++) { for (i=0; i<nold; i++) {
Node *n = vold+i; Node *n = vold+i;
if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL) if (ttype(val(n)) != LUA_T_NIL) {
*node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */ *luaH_present(t, ref(n)) = *n; /* copy old node to new hash */
nuse(t)++;
}
} }
L->nblocks += gcsize(nnew)-gcsize(nold); L->nblocks += gcsize(nnew)-gcsize(nold);
luaM_free(vold); 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;
}
void luaH_set (Hash *t, TObject *ref, TObject *val) {
/* Node *n = luaH_present(t, ref);
** If the hash node is present, return its pointer, otherwise create a luaM_new if (ttype(ref(n)) != LUA_T_NIL)
** node for the given reference and also return its pointer. *val(n) = *val;
*/
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);
else { else {
int i = present(t, r); TObject buff = *val; /* rehash may invalidate this address */
Node *n = node(t, i); if ((long)nuse(t)*3L > (long)nhash(t)*2L) {
luaL_arg_check(ttype(ref(n))!=LUA_T_NIL && ttype(val(n))!=LUA_T_NIL, rehash(t);
2, "key not found"); n = luaH_present(t, ref);
return hashnext(t, i+1); }
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) ** Lua tables (hash)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -15,10 +15,16 @@
#define val(n) (&(n)->val) #define val(n) (&(n)->val)
#define nhash(t) ((t)->nhash) #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); Hash *luaH_new (int nhash);
void luaH_free (Hash *frees); void luaH_free (Hash *frees);
TObject *luaH_get (Hash *t, TObject *ref); Node *luaH_present (Hash *t, TObject *key);
TObject *luaH_set (Hash *t, TObject *ref); void luaH_set (Hash *t, TObject *ref, TObject *val);
Node *luaH_next (TObject *o, TObject *r); int luaH_pos (Hash *t, TObject *r);
void luaH_setint (Hash *t, int ref, TObject *val);
TObject *luaH_getint (Hash *t, int ref);
#endif #endif

88
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.23 1999/02/25 19:13:56 roberto Exp roberto $
** Tag methods ** Tag methods
** See Copyright Notice in lua.h ** 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); int e = luaL_findstring(name, list);
if (e < 0) if (e < 0)
luaL_verror("`%.50s' is not a valid event name", name); 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 /* events in LUA_T_NIL are all allowed, since this is used as a
* 'placeholder' for "default" fallbacks * '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, 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, 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 */ {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 */ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
}; };
static int luaT_validevent (int t, int e) { /* ORDER LUA_T */
static int validevent (int t, int e) return (t < LUA_T_NIL) ? 1 : luaT_validevents[-t][e];
{ /* ORDER LUA_T */
return (t < LUA_T_NIL) ? 1 : validevents[-t][e];
} }
static void init_entry (int tag) static void init_entry (int tag) {
{
int i; int i;
for (i=0; i<IM_N; i++) for (i=0; i<IM_N; i++)
ttype(luaT_getim(tag, i)) = LUA_T_NIL; ttype(luaT_getim(tag, i)) = LUA_T_NIL;
} }
void luaT_init (void) void luaT_init (void) {
{
int t; int t;
L->IMtable_size = NUM_TAGS*2;
L->last_tag = -(NUM_TAGS-1); 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++) for (t=L->last_tag; t<=0; t++)
init_entry(t); init_entry(t);
} }
int lua_newtag (void) int lua_newtag (void) {
{
--L->last_tag; --L->last_tag;
if ((-L->last_tag) >= L->IMtable_size) luaM_growvector(L->IMtable, -(L->last_tag), 1, struct IM, arrEM, MAX_INT);
L->IMtable_size = luaM_growvector(&L->IMtable, L->IMtable_size,
struct IM, memEM, MAX_INT);
init_entry(L->last_tag); init_entry(L->last_tag);
return L->last_tag; return L->last_tag;
} }
static void checktag (int tag) static void checktag (int tag) {
{
if (!(L->last_tag <= tag && tag <= 0)) if (!(L->last_tag <= tag && tag <= 0))
luaL_verror("%d is not a valid tag", tag); 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)) 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; int e;
checktag(tagto); checktag(tagto);
checktag(tagfrom); checktag(tagfrom);
for (e=0; e<IM_N; e++) { for (e=0; e<IM_N; e++) {
if (validevent(tagto, e)) if (luaT_validevent(tagto, e))
*luaT_getim(tagto, e) = *luaT_getim(tagfrom, e); *luaT_getim(tagto, e) = *luaT_getim(tagfrom, e);
} }
return tagto; return tagto;
} }
int luaT_efectivetag (TObject *o) int luaT_effectivetag (TObject *o) {
{
int t; int t;
switch (t = ttype(o)) { switch (t = ttype(o)) {
case LUA_T_ARRAY: case LUA_T_ARRAY:
@@ -131,36 +118,33 @@ 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); int e = luaI_checkevent(event, luaT_eventname);
checktag(t); checktag(t);
if (validevent(t, e)) if (luaT_validevent(t, e))
return luaT_getim(t,e); return luaT_getim(t,e);
else else
return &luaO_nilobject; return &luaO_nilobject;
} }
void luaT_settagmethod (int t, char *event, TObject *func) void luaT_settagmethod (int t, char *event, TObject *func) {
{
TObject temp = *func; TObject temp = *func;
int e = luaI_checkevent(event, luaT_eventname); int e = luaI_checkevent(event, luaT_eventname);
checktag(t); checktag(t);
if (!validevent(t, e)) if (!luaT_validevent(t, e))
luaL_verror("settagmethod: cannot change tag method `%.20s' for tag %d", luaL_verror("cannot change tag method `%.20s' for type `%.20s'%.20s",
luaT_eventname[e], t); luaT_eventname[e], luaO_typenames[-t],
(t == LUA_T_ARRAY || t == LUA_T_USERDATA) ? " with default tag"
: "");
*func = *luaT_getim(t,e); *func = *luaT_getim(t,e);
*luaT_getim(t, e) = temp; *luaT_getim(t, e) = temp;
} }
char *luaT_travtagmethods (int (*fn)(TObject *)) char *luaT_travtagmethods (int (*fn)(TObject *)) { /* ORDER IM */
{
int e; int e;
if (fn(&L->errorim)) for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) {
return "error";
for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { /* ORDER IM */
int t; int t;
for (t=0; t>=L->last_tag; t--) for (t=0; t>=L->last_tag; t--)
if (fn(luaT_getim(t,e))) if (fn(luaT_getim(t,e)))
@@ -177,6 +161,7 @@ char *luaT_travtagmethods (int (*fn)(TObject *))
#ifdef LUA_COMPAT2_5 #ifdef LUA_COMPAT2_5
#include "lapi.h" #include "lapi.h"
#include "lstring.h"
static void errorFB (void) static void errorFB (void)
{ {
@@ -191,23 +176,20 @@ static void errorFB (void)
static void nilFB (void) { } static void nilFB (void) { }
static void typeFB (void) static void typeFB (void) {
{
lua_error("unexpected type"); lua_error("unexpected type");
} }
static void fillvalids (IMS e, TObject *func) static void fillvalids (IMS e, TObject *func) {
{
int t; int t;
for (t=LUA_T_NIL; t<=LUA_T_USERDATA; 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; *luaT_getim(t, e) = *func;
} }
void luaT_setfallback (void) void luaT_setfallback (void) {
{
static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL}; static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL};
TObject oldfunc; TObject oldfunc;
lua_CFunction replace; lua_CFunction replace;
@@ -215,11 +197,13 @@ void luaT_setfallback (void)
lua_Object func = lua_getparam(2); lua_Object func = lua_getparam(2);
luaL_arg_check(lua_isfunction(func), 2, "function expected"); luaL_arg_check(lua_isfunction(func), 2, "function expected");
switch (luaL_findstring(name, oldnames)) { switch (luaL_findstring(name, oldnames)) {
case 0: /* old error fallback */ case 0: { /* old error fallback */
oldfunc = L->errorim; TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
L->errorim = *luaA_Address(func); oldfunc = *em;
*em = *luaA_Address(func);
replace = errorFB; replace = errorFB;
break; break;
}
case 1: /* old getglobal fallback */ case 1: /* old getglobal fallback */
oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL); oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL);
*luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func); *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 ** Tag methods
** See Copyright Notice in lua.h ** 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_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[]; extern char *luaT_eventname[];
void luaT_init (void); void luaT_init (void);
void luaT_realtag (int tag); void luaT_realtag (int tag);
int luaT_efectivetag (TObject *o); int luaT_effectivetag (TObject *o);
void luaT_settagmethod (int t, char *event, TObject *func); void luaT_settagmethod (int t, char *event, TObject *func);
TObject *luaT_gettagmethod (int t, char *event); TObject *luaT_gettagmethod (int t, char *event);
char *luaT_travtagmethods (int (*fn)(TObject *)); char *luaT_travtagmethods (int (*fn)(TObject *));

57
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.18 1999/01/26 11:50:58 roberto Exp roberto $
** Lua stand-alone interpreter ** Lua stand-alone interpreter
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -32,27 +32,31 @@ typedef void (*handler)(int); /* type for signal actions */
static void laction (int i); static void laction (int i);
static handler lreset (void)
{ static lua_LHFunction old_linehook = NULL;
lua_linehook = NULL; static lua_CHFunction old_callhook = NULL;
lua_callhook = NULL;
static handler lreset (void) {
return signal(SIGINT, laction); return signal(SIGINT, laction);
} }
static void lstop (void)
{ static void lstop (void) {
lua_setlinehook(old_linehook);
lua_setcallhook(old_callhook);
lreset(); lreset();
lua_error("interrupted!"); lua_error("interrupted!");
} }
static void laction (int i)
{ static void laction (int i) {
lua_linehook = (lua_LHFunction)lstop; old_linehook = lua_setlinehook((lua_LHFunction)lstop);
lua_callhook = (lua_CHFunction)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; int res;
handler h = lreset(); handler h = lreset();
res = f(name); /* dostring | dofile */ res = f(name); /* dostring | dofile */
@@ -61,8 +65,7 @@ static int ldo (int (*f)(char *), char *name)
} }
static void print_message (void) static void print_message (void) {
{
fprintf(stderr, fprintf(stderr,
"Lua: command line options:\n" "Lua: command line options:\n"
" -v print version information\n" " -v print version information\n"
@@ -76,8 +79,7 @@ static void print_message (void)
} }
static void assign (char *arg) static void assign (char *arg) {
{
if (strlen(arg) >= 500) if (strlen(arg) >= 500)
fprintf(stderr, "lua: shell argument too long"); fprintf(stderr, "lua: shell argument too long");
else { else {
@@ -90,13 +92,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; int cont = 1;
while (cont) { while (cont) {
char buffer[BUF_SIZE]; char buffer[BUFSIZ];
int i = 0; int i = 0;
lua_beginblock(); lua_beginblock();
if (prompt) if (prompt)
@@ -112,13 +112,13 @@ static void manual_input (int prompt)
buffer[i-1] = '\n'; buffer[i-1] = '\n';
else break; else break;
} }
else if (i >= BUF_SIZE-1) { else if (i >= BUFSIZ-1) {
fprintf(stderr, "lua: argument line too long\n"); fprintf(stderr, "lua: argument line too long\n");
break; break;
} }
else buffer[i++] = c; else buffer[i++] = (char)c;
} }
buffer[i] = 0; buffer[i] = '\0';
ldo(lua_dostring, buffer); ldo(lua_dostring, buffer);
lua_endblock(); lua_endblock();
} }
@@ -129,11 +129,10 @@ static void manual_input (int prompt)
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
int i; int i;
setlocale(LC_ALL, ""); lua_open();
lua_iolibopen();
lua_strlibopen();
lua_mathlibopen();
lua_pushstring("> "); lua_setglobal("_PROMPT"); lua_pushstring("> "); lua_setglobal("_PROMPT");
setlocale(LC_ALL, "");
lua_userinit();
if (argc < 2) { /* no arguments? */ if (argc < 2) { /* no arguments? */
if (isatty(0)) { if (isatty(0)) {
printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT); printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT);
@@ -155,7 +154,7 @@ int main (int argc, char *argv[])
manual_input(0); manual_input(0);
break; break;
case 'd': case 'd':
lua_debug = 1; lua_setdebug(1);
break; break;
case 'v': case 'v':
printf("%s %s\n(written by %s)\n\n", 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.30 1999/02/25 19:13:56 roberto Exp roberto $
** Lua - An Extensible Extension Language ** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: lua@tecgraf.puc-rio.br ** e-mail: lua@tecgraf.puc-rio.br
@@ -11,8 +11,8 @@
#ifndef lua_h #ifndef lua_h
#define lua_h #define lua_h
#define LUA_VERSION "Lua 3.1" #define LUA_VERSION "Lua 3.2 (beta)"
#define LUA_COPYRIGHT "Copyright (C) 1994-1998 TeCGraf, PUC-Rio" #define LUA_COPYRIGHT "Copyright (C) 1994-1999 TeCGraf, PUC-Rio"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo" #define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
@@ -20,19 +20,18 @@
#define LUA_ANYTAG (-1) #define LUA_ANYTAG (-1)
typedef void (*lua_CFunction) (void);
typedef unsigned int lua_Object;
typedef struct lua_State lua_State; typedef struct lua_State lua_State;
extern 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_open (void);
void lua_close (void); void lua_close (void);
lua_State *lua_setstate (lua_State *st); lua_State *lua_setstate (lua_State *st);
lua_Object lua_settagmethod (int tag, char *event); /* In: new method */ lua_Object lua_settagmethod (int tag, char *event); /* In: new method */
lua_Object lua_gettagmethod (int tag, char *event); lua_Object lua_gettagmethod (int tag, char *event);
lua_Object lua_seterrormethod (void); /* In: new method */
int lua_newtag (void); int lua_newtag (void);
int lua_copytagmethods (int tagto, int tagfrom); 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); 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 */ int lua_ref (int lock); /* In: value */
lua_Object lua_getref (int ref); 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)) #define lua_call(name) lua_callfunction(lua_getglobal(name))
void (lua_pushref) (int ref);
#define lua_pushref(ref) lua_pushobject(lua_getref(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)) #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)) #define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n))
void (lua_pushuserdata) (void *u);
#define lua_pushuserdata(u) lua_pushusertag(u, 0) #define lua_pushuserdata(u) lua_pushusertag(u, 0)
void (lua_pushcfunction) (lua_CFunction f);
#define lua_pushcfunction(f) lua_pushcclosure(f, 0) #define lua_pushcfunction(f) lua_pushcclosure(f, 0)
int (lua_clonetag) (int t);
#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (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 ** 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 * Permission is hereby granted, without written agreement and without license
* or royalty fees, to use, copy, modify, and distribute this software and its * 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 * The Lua language and this implementation have been entirely designed and
* written by Waldemar Celes Filho, Roberto Ierusalimschy and * written by Waldemar Celes Filho, Roberto Ierusalimschy and
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio. * Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
*
* This implementation contains no third-party code. * 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 ** Debugging API
** See Copyright Notice in lua.h ** 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); typedef void (*lua_CHFunction) (lua_Function func, char *file, int line);
lua_Function lua_stackedfunction (int level); 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); int lua_currentline (lua_Function func);
char *lua_getobjname (lua_Object o, char **name); char *lua_getobjname (lua_Object o, char **name);
lua_Object lua_getlocal (lua_Function func, int local_number, 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_setlocal (lua_Function func, int local_number);
int lua_nups (lua_Function func);
extern lua_LHFunction lua_linehook; lua_LHFunction lua_setlinehook (lua_LHFunction func);
extern lua_CHFunction lua_callhook; lua_CHFunction lua_setcallhook (lua_CHFunction func);
extern int lua_debug; int lua_setdebug (int debug);
#endif #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.4 1998/06/19 16:14:09 roberto Exp roberto $
** Lua standard libraries ** Lua standard libraries
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -10,12 +10,13 @@
#include "lua.h" #include "lua.h"
void lua_iolibopen (void); void lua_iolibopen (void);
void lua_strlibopen (void); void lua_strlibopen (void);
void lua_mathlibopen (void); void lua_mathlibopen (void);
void lua_dblibopen (void);
void lua_userinit (void);
/* To keep compatibility with old versions */ /* To keep compatibility with old versions */

170
lundump.c
View File

@@ -1,105 +1,93 @@
/* /*
** $Id: lundump.c,v 1.10 1998/06/25 15:50:09 lhf Exp $ ** $Id: lundump.c,v 1.18 1999/04/09 03:10:40 lhf Exp lhf $
** load bytecodes from files ** load bytecodes from files
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "lauxlib.h" #include "lauxlib.h"
#include "lfunc.h" #include "lfunc.h"
#include "lmem.h" #include "lmem.h"
#include "lopcodes.h"
#include "lstring.h" #include "lstring.h"
#include "lundump.h" #include "lundump.h"
#define LoadBlock(b,size,Z) ezread(Z,b,size) #define LoadBlock(b,size,Z) ezread(Z,b,size)
#define LoadNative(t,Z) LoadBlock(&t,sizeof(t),Z)
#if ID_NUMBER==ID_NATIVE #if LUAC_NATIVE
#define doLoadNumber(f,Z) LoadNative(f,Z) #define doLoadNumber(x,Z) LoadBlock(&x,sizeof(x),Z)
#else #else
#define doLoadNumber(f,Z) f=LoadNumber(Z) #define doLoadNumber(x,Z) x=LoadNumber(Z)
#endif #endif
static void unexpectedEOZ(ZIO* Z) static void unexpectedEOZ (ZIO* Z)
{ {
luaL_verror("unexpected end of file in %s",zname(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); int c=zgetc(Z);
if (c==EOZ) unexpectedEOZ(Z); if (c==EOZ) unexpectedEOZ(Z);
return c; 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); int r=zread(Z,b,n);
if (r!=0) unexpectedEOZ(Z); if (r!=0) unexpectedEOZ(Z);
} }
static unsigned int LoadWord(ZIO* Z) static unsigned int LoadWord (ZIO* Z)
{ {
unsigned int hi=ezgetc(Z); unsigned int hi=ezgetc(Z);
unsigned int lo=ezgetc(Z); unsigned int lo=ezgetc(Z);
return (hi<<8)|lo; return (hi<<8)|lo;
} }
static unsigned long LoadLong(ZIO* Z) static unsigned long LoadLong (ZIO* Z)
{ {
unsigned long hi=LoadWord(Z); unsigned long hi=LoadWord(Z);
unsigned long lo=LoadWord(Z); unsigned long lo=LoadWord(Z);
return (hi<<16)|lo; return (hi<<16)|lo;
} }
#if ID_NUMBER==ID_REAL4 static real LoadNumber (ZIO* Z)
/* LUA_NUMBER */ {
/* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */ char b[256];
static float LoadFloat(ZIO* Z) int size=ezgetc(Z);
LoadBlock(b,size,Z);
b[size]=0;
if (b[0]=='-')
return -luaO_str2d(b+1);
else
return luaO_str2d(b);
}
static int LoadInt (ZIO* Z, char* message)
{ {
unsigned long l=LoadLong(Z); unsigned long l=LoadLong(Z);
float f=*(float*)&l; unsigned int i=l;
return f; if (i!=l) luaL_verror(message,l,zname(Z));
return i;
} }
#endif
#if ID_NUMBER==ID_REAL8 #define PAD 5 /* two word operands plus opcode */
/* 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
static Byte* LoadCode(ZIO* Z) static Byte* LoadCode (ZIO* Z)
{ {
unsigned long size=LoadLong(Z); int size=LoadInt(Z,"code too long (%ld bytes) in %s");
unsigned int s=size; Byte* b=luaM_malloc(size+PAD);
void* b;
if (s!=size) luaL_verror("code too long (%ld bytes) in %s",size,zname(Z));
b=luaM_malloc(size);
LoadBlock(b,size,Z); 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; return b;
} }
static TaggedString* LoadTString(ZIO* Z) static TaggedString* LoadTString (ZIO* Z)
{ {
int size=LoadWord(Z); long size=LoadLong(Z);
if (size==0) if (size==0)
return NULL; return NULL;
else else
@@ -110,65 +98,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; if (n==0) return;
tf->locvars=luaM_newvector(n+1,LocVar); tf->locvars=luaM_newvector(n+1,LocVar);
for (i=0; i<n; i++) 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].varname=LoadTString(Z);
} }
tf->locvars[i].line=-1; /* flag end of vector */ tf->locvars[i].line=-1; /* flag end of vector */
tf->locvars[i].varname=NULL; tf->locvars[i].varname=NULL;
} }
static TProtoFunc* LoadFunction(ZIO* Z); static TProtoFunc* LoadFunction (ZIO* Z);
static void LoadConstants(TProtoFunc* tf, ZIO* Z) static void LoadConstants (TProtoFunc* tf, ZIO* Z)
{ {
int i,n=LoadWord(Z); int i,n=LoadInt(Z,"too many constants (%ld) in %s");
tf->nconsts=n; tf->nconsts=n;
if (n==0) return; if (n==0) return;
tf->consts=luaM_newvector(n,TObject); tf->consts=luaM_newvector(n,TObject);
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
TObject* o=tf->consts+i; TObject* o=tf->consts+i;
int c=ezgetc(Z); ttype(o)=-ezgetc(Z); /* ttype(o) is negative - ORDER LUA_T */
switch (c) switch (ttype(o))
{ {
case ID_NUM: case LUA_T_NUMBER:
ttype(o)=LUA_T_NUMBER;
doLoadNumber(nvalue(o),Z); doLoadNumber(nvalue(o),Z);
break; break;
case ID_STR: case LUA_T_STRING:
ttype(o)=LUA_T_STRING;
tsvalue(o)=LoadTString(Z); tsvalue(o)=LoadTString(Z);
break; break;
case ID_FUN: case LUA_T_PROTO:
ttype(o)=LUA_T_PROTO;
tfvalue(o)=LoadFunction(Z); tfvalue(o)=LoadFunction(Z);
break; break;
default: case LUA_T_NIL:
luaL_verror("bad constant #%d in %s: type=%d ('%c')",i,zname(Z),c,c); break;
default: /* cannot happen */
luaU_badconstant("load",i,o,tf);
break; break;
} }
} }
} }
static TProtoFunc* LoadFunction(ZIO* Z) static TProtoFunc* LoadFunction (ZIO* Z)
{ {
TProtoFunc* tf=luaF_newproto(); TProtoFunc* tf=luaF_newproto();
tf->lineDefined=LoadWord(Z); tf->lineDefined=LoadInt(Z,"lineDefined too large (%ld) in %s");
tf->fileName=LoadTString(Z); tf->source=LoadTString(Z);
if (tf->source==NULL) tf->source=luaS_new(zname(Z));
tf->code=LoadCode(Z); tf->code=LoadCode(Z);
LoadLocals(tf,Z); LoadLocals(tf,Z);
LoadConstants(tf,Z); LoadConstants(tf,Z);
return tf; return tf;
} }
static void LoadSignature(ZIO* Z) static void LoadSignature (ZIO* Z)
{ {
char* s=SIGNATURE; char* s=SIGNATURE;
while (*s!=0 && ezgetc(Z)==*s) while (*s!=0 && ezgetc(Z)==*s)
@@ -176,10 +164,9 @@ static void LoadSignature(ZIO* Z)
if (*s!=0) luaL_verror("bad signature in %s",zname(Z)); if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
} }
static void LoadHeader(ZIO* Z) static void LoadHeader (ZIO* Z)
{ {
int version,id,sizeofR; int version,sizeofR;
real f=-TEST_NUMBER,tf=TEST_NUMBER;
LoadSignature(Z); LoadSignature(Z);
version=ezgetc(Z); version=ezgetc(Z);
if (version>VERSION) if (version>VERSION)
@@ -190,22 +177,33 @@ static void LoadHeader(ZIO* Z)
luaL_verror( luaL_verror(
"%s too old: version=0x%02x; expected at least 0x%02x", "%s too old: version=0x%02x; expected at least 0x%02x",
zname(Z),version,VERSION0); zname(Z),version,VERSION0);
id=ezgetc(Z); /* test number representation */ sizeofR=ezgetc(Z); /* test number representation */
sizeofR=ezgetc(Z); #if LUAC_NATIVE
if (id!=ID_NUMBER || sizeofR!=sizeof(real)) if (sizeofR==0)
luaL_verror("cannot read numbers in %s: "
"support for decimal format not enabled",
zname(Z));
if (sizeofR!=sizeof(real))
luaL_verror("unknown number size in %s: read %d; expected %d",
zname(Z),sizeofR,sizeof(real));
else
{ {
luaL_verror("unknown number signature in %s: " real f=-TEST_NUMBER,tf=TEST_NUMBER;
"read 0x%02x%02x; expected 0x%02x%02x",
zname(Z),id,sizeofR,ID_NUMBER,sizeof(real));
}
doLoadNumber(f,Z); doLoadNumber(f,Z);
if (f!=tf) if (f!=tf)
luaL_verror("unknown number representation in %s: " luaL_verror("unknown number representation in %s: "
"read " NUMBER_FMT "; expected " NUMBER_FMT "", /* LUA_NUMBER */ "read " NUMBER_FMT "; expected " NUMBER_FMT,
zname(Z),(double)f,(double)tf); zname(Z),f,tf);
}
#else
if (sizeofR!=0)
luaL_verror("cannot read numbers in %s: "
"support for native format not enabled",
zname(Z));
#endif
} }
static TProtoFunc* LoadChunk(ZIO* Z) static TProtoFunc* LoadChunk (ZIO* Z)
{ {
LoadHeader(Z); LoadHeader(Z);
return LoadFunction(Z); return LoadFunction(Z);
@@ -215,7 +213,7 @@ static TProtoFunc* LoadChunk(ZIO* Z)
** load one chunk from a file or buffer ** load one chunk from a file or buffer
** return main if ok and NULL at EOF ** return main if ok and NULL at EOF
*/ */
TProtoFunc* luaU_undump1(ZIO* Z) TProtoFunc* luaU_undump1 (ZIO* Z)
{ {
int c=zgetc(Z); int c=zgetc(Z);
if (c==ID_CHUNK) if (c==ID_CHUNK)
@@ -224,3 +222,13 @@ TProtoFunc* luaU_undump1(ZIO* Z)
luaL_verror("%s is not a Lua binary file",zname(Z)); luaL_verror("%s is not a Lua binary file",zname(Z));
return NULL; 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.13 1999/03/29 16:16:18 lhf Exp lhf $
** load pre-compiled Lua chunks ** load pre-compiled Lua chunks
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -10,72 +10,39 @@
#include "lobject.h" #include "lobject.h"
#include "lzio.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 */
#define SIGNATURE "Lua" /* definitions for headers of binary files */
#define VERSION 0x31 /* last format change was in 3.1 */ #define VERSION 0x32 /* last format change was in 3.2 */
#define VERSION0 0x31 /* last major change was in 3.1 */ #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 */ /* format for numbers in listings and error messages */
#define ID_NUM 'N' #ifndef NUMBER_FMT
#define ID_STR 'S' #define NUMBER_FMT "%.16g" /* LUA_NUMBER */
#define ID_FUN 'F' #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.
*/
#define TEST_NUMBER 3.14159265358979323846E8
/* LUA_NUMBER /* LUA_NUMBER
* choose one below for the number representation in precompiled chunks. * by default, numbers are stored in precompiled chunks as decimal strings.
* the default is ID_REAL8 because the default for LUA_NUM_TYPE is double. * this is completely portable and fast enough for most applications.
* if your machine does not use IEEE 754, use ID_NATIVE. * if you want to use this default, do nothing.
* the next version will support conversion to/from IEEE 754. * if you want additional speed at the expense of portability, move the line
* * below out of this comment.
* if you change LUA_NUM_TYPE, make sure you set ID_NUMBER accordingly, #define LUAC_NATIVE
* 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 #ifdef LUAC_NATIVE
#define ID_NUMBER ID_NATIVE /* a multiple of PI for testing number representation */
#endif /* multiplying by 1E8 gives non-trivial integer values */
#define TEST_NUMBER 3.14159265358979323846E8
#if 0
#define ID_NUMBER ID_INT4
#define ID_NUMBER ID_REAL4
#define ID_NUMBER ID_REAL8
#define ID_NUMBER ID_NATIVE
#endif #endif
#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

599
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.54 1999/03/10 14:09:45 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
#include <ctype.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "lauxlib.h" #include "lauxlib.h"
@@ -13,6 +16,7 @@
#include "lfunc.h" #include "lfunc.h"
#include "lgc.h" #include "lgc.h"
#include "lmem.h" #include "lmem.h"
#include "lobject.h"
#include "lopcodes.h" #include "lopcodes.h"
#include "lstate.h" #include "lstate.h"
#include "lstring.h" #include "lstring.h"
@@ -27,9 +31,7 @@
#endif #endif
#define skip_word(pc) (pc+=2) #define highbyte(x) ((x)<<8)
#define get_word(pc) ((*(pc)<<8)+(*((pc)+1)))
#define next_word(pc) (pc+=2, get_word(pc-2))
/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */ /* 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) static TaggedString *strconc (TaggedString *l, TaggedString *r) {
{ long nl = l->u.s.len;
size_t nl = l->u.s.len; long nr = r->u.s.len;
size_t nr = r->u.s.len; char *buffer = luaL_openspace(nl+nr);
char *buffer = luaL_openspace(nl+nr+1);
memcpy(buffer, l->str, nl); memcpy(buffer, l->str, nl);
memcpy(buffer+nl, r->str, nr); memcpy(buffer+nl, r->str, nr);
return luaS_newlstr(buffer, nl+nr); return luaS_newlstr(buffer, nl+nr);
} }
int luaV_tonumber (TObject *obj) int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */
{ /* LUA_NUMBER */
double t;
char c;
if (ttype(obj) != LUA_T_STRING) if (ttype(obj) != LUA_T_STRING)
return 1; return 1;
else if (sscanf(svalue(obj), "%lf %c",&t, &c) == 1) { else {
nvalue(obj) = (real)t; 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; ttype(obj) = LUA_T_NUMBER;
return 0; return 0;
} }
else
return 2;
} }
int luaV_tostring (TObject *obj) int luaV_tostring (TObject *obj) { /* LUA_NUMBER */
{ /* LUA_NUMBER */
if (ttype(obj) != LUA_T_NUMBER) if (ttype(obj) != LUA_T_NUMBER)
return 1; return 1;
else { else {
char s[60]; char s[32]; /* 16 digits, signal, point and \0 (+ some extra...) */
real f = nvalue(obj); sprintf(s, "%.16g", (double)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));
tsvalue(obj) = luaS_new(s); tsvalue(obj) = luaS_new(s);
ttype(obj) = LUA_T_STRING; ttype(obj) = LUA_T_STRING;
return 0; 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) { if (nelems > 0) {
struct Stack *S = &L->stack; struct Stack *S = &L->stack;
Closure *c = luaF_newclosure(nelems); Closure *c = luaF_newclosure(nelems);
@@ -101,94 +112,104 @@ void luaV_closure (int nelems)
** Function to index a table. ** Function to index a table.
** Receives the table at top-2 and the index at top-1. ** Receives the table at top-2 and the index at top-1.
*/ */
void luaV_gettable (void) void luaV_gettable (void) {
{ TObject *table = L->stack.top-2;
struct Stack *S = &L->stack;
TObject *im; TObject *im;
if (ttype(S->top-2) != LUA_T_ARRAY) /* not a table, get "gettable" method */ if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
im = luaT_getimbyObj(S->top-2, IM_GETTABLE); im = luaT_getimbyObj(table, IM_GETTABLE);
if (ttype(im) == LUA_T_NIL)
lua_error("indexed expression not a table");
}
else { /* object is 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); im = luaT_getim(tg, IM_GETTABLE);
if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */ if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */
TObject *h = luaH_get(avalue(S->top-2), S->top-1); TObject *h = luaH_get(avalue(table), table+1);
if (h != NULL && ttype(h) != LUA_T_NIL) { if (ttype(h) == LUA_T_NIL &&
--S->top; (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)) {
*(S->top-1) = *h; /* 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 { else {
--S->top; L->stack.top--;
ttype(S->top-1) = LUA_T_NIL; *table = *h; /* "push" result into table position */
} }
return; return;
} }
/* else it has a "gettable" method, go through to next command */ /* else it has a "gettable" method, go through to next command */
} }
/* object is not a table, or it has a "gettable" method */ /* object is not a table, or it has a "gettable" method */
if (ttype(im) != LUA_T_NIL) luaD_callTM(im, 2, 1);
luaD_callTM(im, 2, 1);
else
lua_error("indexed expression not a table");
} }
/* /*
** Function to store indexed based on values at the stack.top ** Receives table at *t, index at *(t+1) and value at 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)
*/ */
void luaV_settable (TObject *t, int mode) void luaV_settable (TObject *t) {
{
struct Stack *S = &L->stack; struct Stack *S = &L->stack;
TObject *im = (mode == 0) ? NULL : luaT_getimbyObj(t, IM_SETTABLE); TObject *im;
if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) { if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
TObject *h = luaH_set(avalue(t), t+1); im = luaT_getimbyObj(t, IM_SETTABLE);
*h = *(S->top-1); if (ttype(im) == LUA_T_NIL)
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
lua_error("indexed expression not a table"); 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) void luaV_rawsettable (TObject *t) {
{ if (ttype(t) != LUA_T_ARRAY)
/* WARNING: caller must assure stack space */ lua_error("indexed expression not a table");
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;
}
else { else {
struct Stack *S = &L->stack; struct Stack *S = &L->stack;
ttype(S->top) = LUA_T_STRING; luaH_set(avalue(t), t+1, S->top-1);
tsvalue(S->top) = ts; S->top -= 3;
S->top++;
*S->top++ = *value;
luaD_callTM(im, 2, 1);
} }
} }
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 *oldvalue = &ts->u.s.globalval;
TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL); 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); luaS_rawsetglobal(ts, --L->stack.top);
else { else {
/* WARNING: caller must assure stack space */ /* WARNING: caller must assure stack space */
@@ -225,7 +246,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 (;;) { for (;;) {
long temp = strcoll(l, r); long temp = strcoll(l, r);
@@ -242,18 +263,17 @@ static int strcomp (char *l, long ll, char *r, long lr)
} }
} }
static void comparison (lua_Type ttype_less, lua_Type ttype_equal, void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
lua_Type ttype_great, IMS op) lua_Type ttype_great, IMS op) {
{
struct Stack *S = &L->stack; struct Stack *S = &L->stack;
TObject *l = S->top-2; TObject *l = S->top-2;
TObject *r = S->top-1; TObject *r = S->top-1;
int result; real result;
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) 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) else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
result = strcomp(svalue(l), tsvalue(l)->u.s.len, result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
svalue(r), tsvalue(r)->u.s.len); svalue(r), tsvalue(r)->u.s.len);
else { else {
call_binTM(op, "unexpected type in comparison"); call_binTM(op, "unexpected type in comparison");
return; return;
@@ -265,27 +285,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; TObject *firstelem = L->stack.stack+firstel;
int i; int i;
Hash *htab;
if (nvararg < 0) nvararg = 0; 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; ttype(tab) = LUA_T_ARRAY;
for (i=0; i<nvararg; i++) { for (i=0; i<nvararg; i++)
TObject index; luaH_setint(htab, i+1, firstelem+i);
ttype(&index) = LUA_T_NUMBER; luaV_setn(htab, nvararg); /* store counter in field "n" */
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;
}
} }
@@ -305,12 +314,11 @@ static void adjust_varargs (StkId first_extra_arg)
** [stack+base,top). Returns n such that the the results are between ** [stack+base,top). Returns n such that the the results are between
** [stack+n,top). ** [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 */ struct Stack *S = &L->stack; /* to optimize */
Byte *pc = tf->code; register Byte *pc = tf->code;
TObject *consts = tf->consts; TObject *consts = tf->consts;
if (lua_callhook) if (L->callhook)
luaD_callHook(base, tf, 0); luaD_callHook(base, tf, 0);
luaD_checkstack((*pc++)+EXTRA_STACK); luaD_checkstack((*pc++)+EXTRA_STACK);
if (*pc < ZEROVARARG) if (*pc < ZEROVARARG)
@@ -319,86 +327,82 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
luaC_checkGC(); luaC_checkGC();
adjust_varargs(base+(*pc++)-ZEROVARARG); adjust_varargs(base+(*pc++)-ZEROVARARG);
} }
while (1) { for (;;) {
int aux; register int aux = 0;
switch ((OpCode)(aux = *pc++)) { switchentry:
switch ((OpCode)*pc++) {
case PUSHNIL0: case ENDCODE:
ttype(S->top++) = LUA_T_NIL; S->top = S->stack + base;
goto ret;
case RETCODE:
base += *pc++;
goto ret;
case CALL: aux = *pc++;
luaD_call((S->top-S->stack)-(*pc++), aux);
break; break;
case PUSHNIL: case TAILCALL: aux = *pc++;
aux = *pc++; luaD_call((S->top-S->stack)-(*pc++), MULT_RET);
base += aux;
goto ret;
case PUSHNIL: aux = *pc++;
do { do {
ttype(S->top++) = LUA_T_NIL; ttype(S->top++) = LUA_T_NIL;
} while (aux--); } while (aux--);
break; break;
case PUSHNUMBER: case POP: aux = *pc++;
aux = *pc++; goto pushnumber; S->top -= aux;
break;
case PUSHNUMBERW: case PUSHNUMBERW: aux += highbyte(*pc++);
aux = next_word(pc); goto pushnumber; case PUSHNUMBER: aux += *pc++;
case PUSHNUMBER0: case PUSHNUMBER1: case PUSHNUMBER2:
aux -= PUSHNUMBER0;
pushnumber:
ttype(S->top) = LUA_T_NUMBER; ttype(S->top) = LUA_T_NUMBER;
nvalue(S->top) = aux; nvalue(S->top) = aux;
S->top++; S->top++;
break; break;
case PUSHLOCAL: case PUSHNUMBERNEGW: aux += highbyte(*pc++);
aux = *pc++; goto pushlocal; 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 PUSHCONSTANTW: aux += highbyte(*pc++);
case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: case PUSHCONSTANT: aux += *pc++;
aux -= PUSHLOCAL0; *S->top++ = consts[aux];
pushlocal: break;
case PUSHUPVALUE: aux = *pc++;
*S->top++ = cl->consts[aux+1];
break;
case PUSHLOCAL: aux = *pc++;
*S->top++ = *((S->stack+base) + aux); *S->top++ = *((S->stack+base) + aux);
break; break;
case GETGLOBALW: case GETGLOBALW: aux += highbyte(*pc++);
aux = next_word(pc); goto getglobal; case GETGLOBAL: aux += *pc++;
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:
luaV_getglobal(tsvalue(&consts[aux])); luaV_getglobal(tsvalue(&consts[aux]));
break; break;
case GETTABLE: case GETTABLE:
luaV_gettable(); luaV_gettable();
break; break;
case GETDOTTEDW: case GETDOTTEDW: aux += highbyte(*pc++);
aux = next_word(pc); goto getdotted; case GETDOTTED: aux += *pc++;
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:
*S->top++ = consts[aux]; *S->top++ = consts[aux];
luaV_gettable(); luaV_gettable();
break; break;
case PUSHSELFW: case PUSHSELFW: aux += highbyte(*pc++);
aux = next_word(pc); goto pushself; case PUSHSELF: aux += *pc++; {
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); TObject receiver = *(S->top-1);
*S->top++ = consts[aux]; *S->top++ = consts[aux];
luaV_gettable(); luaV_gettable();
@@ -406,141 +410,75 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
break; break;
} }
case PUSHCONSTANTW: case CREATEARRAYW: aux += highbyte(*pc++);
aux = next_word(pc); goto pushconstant; case CREATEARRAY: aux += *pc++;
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:
luaC_checkGC(); luaC_checkGC();
avalue(S->top) = luaH_new(aux); avalue(S->top) = luaH_new(aux);
ttype(S->top) = LUA_T_ARRAY; ttype(S->top) = LUA_T_ARRAY;
S->top++; S->top++;
break; 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++);
TObject *arr = S->top-n-1;
aux *= LFIELDS_PER_FLUSH;
for (; n; n--)
luaH_setint(avalue(arr), n+aux, --S->top);
break;
}
case SETMAP: aux = *pc++; {
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 NEQOP: aux = 1;
case EQOP: {
int res = luaO_equalObj(S->top-2, S->top-1); int res = luaO_equalObj(S->top-2, S->top-1);
if (aux) res = !res;
S->top--; S->top--;
if (aux == NEQOP) res = !res;
ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
nvalue(S->top-1) = 1; nvalue(S->top-1) = 1;
break; break;
} }
case LTOP: 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; break;
case LEOP: 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; break;
case GTOP: 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; break;
case GEOP: 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; break;
case ADDOP: { case ADDOP: {
@@ -624,98 +562,47 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
nvalue(S->top-1) = 1; nvalue(S->top-1) = 1;
break; break;
case ONTJMPW: case ONTJMPW: aux += highbyte(*pc++);
aux = next_word(pc); goto ontjmp; case ONTJMP: aux += *pc++;
case ONTJMP:
aux = *pc++;
ontjmp:
if (ttype(S->top-1) != LUA_T_NIL) pc += aux; if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
else S->top--; else S->top--;
break; break;
case ONFJMPW: case ONFJMPW: aux += highbyte(*pc++);
aux = next_word(pc); goto onfjmp; case ONFJMP: aux += *pc++;
case ONFJMP:
aux = *pc++;
onfjmp:
if (ttype(S->top-1) == LUA_T_NIL) pc += aux; if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
else S->top--; else S->top--;
break; break;
case JMPW: case JMPW: aux += highbyte(*pc++);
aux = next_word(pc); goto jmp; case JMP: aux += *pc++;
case JMP:
aux = *pc++;
jmp:
pc += aux; pc += aux;
break; break;
case IFFJMPW: case IFFJMPW: aux += highbyte(*pc++);
aux = next_word(pc); goto iffjmp; case IFFJMP: aux += *pc++;
case IFFJMP:
aux = *pc++;
iffjmp:
if (ttype(--S->top) == LUA_T_NIL) pc += aux; if (ttype(--S->top) == LUA_T_NIL) pc += aux;
break; break;
case IFTUPJMPW: case IFTUPJMPW: aux += highbyte(*pc++);
aux = next_word(pc); goto iftupjmp; case IFTUPJMP: aux += *pc++;
case IFTUPJMP:
aux = *pc++;
iftupjmp:
if (ttype(--S->top) != LUA_T_NIL) pc -= aux; if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
break; break;
case IFFUPJMPW: case IFFUPJMPW: aux += highbyte(*pc++);
aux = next_word(pc); goto iffupjmp; case IFFUPJMP: aux += *pc++;
case IFFUPJMP:
aux = *pc++;
iffupjmp:
if (ttype(--S->top) == LUA_T_NIL) pc -= aux; if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
break; break;
case CLOSUREW: case CLOSUREW: aux += highbyte(*pc++);
aux = next_word(pc); goto closure; case CLOSURE: aux += *pc++;
case CLOSURE:
aux = *pc++;
closure:
*S->top++ = consts[aux]; *S->top++ = consts[aux];
luaV_closure(*pc++); luaV_closure(*pc++);
luaC_checkGC(); luaC_checkGC();
break; break;
case CALLFUNC: case SETLINEW: aux += highbyte(*pc++);
aux = *pc++; goto callfunc; case SETLINE: aux += *pc++;
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:
if ((S->stack+base-1)->ttype != LUA_T_LINE) { if ((S->stack+base-1)->ttype != LUA_T_LINE) {
/* open space for LINE value */ /* open space for LINE value */
luaD_openstack((S->top-S->stack)-base); luaD_openstack((S->top-S->stack)-base);
@@ -723,15 +610,23 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
(S->stack+base-1)->ttype = LUA_T_LINE; (S->stack+base-1)->ttype = LUA_T_LINE;
} }
(S->stack+base-1)->value.i = aux; (S->stack+base-1)->value.i = aux;
if (lua_linehook) if (L->linehook)
luaD_lineHook(aux); luaD_lineHook(aux);
break; break;
#ifdef DEBUG case LONGARGW: aux += highbyte(*pc++);
default: case LONGARG: aux += *pc++;
LUA_INTERNALERROR("opcode doesn't match"); aux = highbyte(highbyte(aux));
#endif goto switchentry; /* do not reset "aux" */
case CHECKSTACK: aux = *pc++;
LUA_ASSERT((S->top-S->stack)-base == aux, "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 ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -10,6 +10,7 @@
#include "ldo.h" #include "ldo.h"
#include "lobject.h" #include "lobject.h"
#include "ltm.h"
#define tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (luaV_tonumber(o) != 0)) #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); void luaV_pack (StkId firstel, int nvararg, TObject *tab);
int luaV_tonumber (TObject *obj); int luaV_tonumber (TObject *obj);
int luaV_tostring (TObject *obj); int luaV_tostring (TObject *obj);
void luaV_setn (Hash *t, int val);
void luaV_gettable (void); 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_getglobal (TaggedString *ts);
void luaV_setglobal (TaggedString *ts); void luaV_setglobal (TaggedString *ts);
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base); StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base);
void luaV_closure (int nelems); void luaV_closure (int nelems);
void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
lua_Type ttype_great, IMS op);
#endif #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 ** a generic input stream interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -15,11 +15,11 @@
/* ----------------------------------------------------- memory buffers --- */ /* ----------------------------------------------------- memory buffers --- */
static int zmfilbuf (ZIO* z) static int zmfilbuf (ZIO* z) {
{
return EOZ; return EOZ;
} }
ZIO* zmopen (ZIO* z, char* b, int size, char *name) ZIO* zmopen (ZIO* z, char* b, int size, char *name)
{ {
if (b==NULL) return NULL; if (b==NULL) return NULL;
@@ -41,9 +41,10 @@ ZIO* zsopen (ZIO* z, char* s, char *name)
/* -------------------------------------------------------------- FILEs --- */ /* -------------------------------------------------------------- FILEs --- */
static int zffilbuf (ZIO* z) static int zffilbuf (ZIO* z) {
{ int n;
int n=fread(z->buffer,1,ZBSIZE,z->u); if (feof((FILE *)z->u)) return EOZ;
n=fread(z->buffer,1,ZBSIZE,z->u);
if (n==0) return EOZ; if (n==0) return EOZ;
z->n=n-1; z->n=n-1;
z->p=z->buffer; z->p=z->buffer;
@@ -64,16 +65,15 @@ ZIO* zFopen (ZIO* z, FILE* f, char *name)
/* --------------------------------------------------------------- read --- */ /* --------------------------------------------------------------- read --- */
int zread (ZIO *z, void *b, int n) int zread (ZIO *z, void *b, int n) {
{
while (n) { while (n) {
int m; int m;
if (z->n == 0) { if (z->n == 0) {
if (z->filbuf(z) == EOZ) if (z->filbuf(z) == EOZ)
return n; /* retorna quantos faltaram ler */ return n; /* return number of missing bytes */
zungetc(z); /* poe o resultado de filbuf no buffer */ 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); memcpy(b, z->p, m);
z->n -= m; z->n -= m;
z->p += 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 ## Makefile
## See Copyright Notice in lua.h ## See Copyright Notice in lua.h
# #
@@ -12,13 +12,15 @@
# define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant # define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant
# #
# define (undefine) OLD_ANSI if your system does NOT have some new ANSI # define (undefine) OLD_ANSI if your system does NOT have some new ANSI
# facilities (e.g. strerror, locale.h, memmove). Although they are ANSI, # facilities (e.g. strerror, locale.h, memmove). SunOS does not comply;
# SunOS does not comply; so, add "-DOLD_ANSI" on SunOS # so, add "-DOLD_ANSI" on SunOS
# #
# define LUA_COMPAT2_5 if yous system does need to be compatible with # define LUA_COMPAT2_5 if yous system does need to be compatible with
# version 2.5 (or older) # version 2.5 (or older)
# #
# define LUA_NUM_TYPE if you need numbers to be different from double # 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 = -DPOPEN -D_POSIX_SOURCE
#CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG #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 CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2
# To make early versions
CO_OPTIONS =
AR = ar AR = ar
ARFLAGS = rvl ARFLAGS = rvl
@@ -58,7 +64,9 @@ LUAOBJS = \
LIBOBJS = \ LIBOBJS = \
liolib.o \ liolib.o \
lmathlib.o \ lmathlib.o \
lstrlib.o lstrlib.o \
ldblib.o \
linit.o
lua : lua.o liblua.a liblualib.a lua : lua.o liblua.a liblualib.a
@@ -80,45 +88,53 @@ clear :
rcsclean rcsclean
rm -f *.o rm -f *.o
rm -f rm -f
co lua.h lualib.h luadebug.h co $(CO_OPTIONS) lua.h lualib.h luadebug.h
%.h : RCS/%.h,v %.h : RCS/%.h,v
co $@ co $(CO_OPTIONS) $@
%.c : RCS/%.c,v %.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 \ lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h \
lgc.h lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.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 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 \ 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 \ ldo.h lstate.h luadebug.h lfunc.h lmem.h lstring.h ltable.h ltm.h \
lzio.h lundump.h lzio.h lvm.h
ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \ ldblib.o: ldblib.c lauxlib.h lua.h luadebug.h lualib.h
lparser.h lzio.h ltm.h luadebug.h lundump.h lvm.h ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h lmem.h lparser.h lzio.h lstring.h ltm.h lundump.h lvm.h
lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \ lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h luadebug.h
lstring.h ltable.h ltm.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 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 \ 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 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 lobject.o: lobject.c lobject.h lua.h
lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h lfunc.h \ lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h \
llex.h lzio.h lmem.h lopcodes.h lparser.h lstring.h luadebug.h luadebug.h lfunc.h llex.h lzio.h lmem.h lopcodes.h lparser.h \
lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h lfunc.h \ lstring.h
lgc.h llex.h lzio.h lmem.h lstring.h ltable.h ltm.h lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h \
lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h lstring.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 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 ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h lstate.h \
ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltm.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 lua.o: lua.c lua.h luadebug.h lualib.h
lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \ lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \
lstring.h lundump.h lzio.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 \ lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h \
lmem.h lopcodes.h lstring.h ltable.h ltm.h luadebug.h lvm.h lfunc.h lgc.h lmem.h lopcodes.h lstring.h ltable.h ltm.h lvm.h
lzio.o: lzio.c lzio.h lzio.o: lzio.c lzio.h

File diff suppressed because it is too large Load Diff