Compare commits

...

410 Commits
v1.2 ... v2.5.1

Author SHA1 Message Date
Roberto Ierusalimschy
42359b8b13 new version 1996-11-20 11:49:32 -02:00
Roberto Ierusalimschy
169870e37d BUG: ISO chars are negative, ISO ints are not. 1996-11-20 11:47:59 -02:00
Roberto Ierusalimschy
78e454d864 BUG: ISO chars are negative, ISO ints are not.
new "balanced" pattern.
1996-11-20 11:47:59 -02:00
Roberto Ierusalimschy
dbfe28e199 correction in inheritance code in C 1996-11-18 12:27:42 -02:00
Roberto Ierusalimschy
d59c52753f undump needs file in binary mode 1996-11-18 11:48:44 -02:00
Roberto Ierusalimschy
62e1a4c84d BUG: problems with negative indexes 1996-11-18 11:48:44 -02:00
Luiz Henrique de Figueiredo
81411e8913 headers includes sizeof(Word) not sizeof(int) 1996-11-18 09:18:29 -02:00
Luiz Henrique de Figueiredo
62aa717f7e stdlib.h for exit
blocks are void*
1996-11-16 18:14:23 -02:00
Roberto Ierusalimschy
a5614eae3c spelling corrections. 1996-11-14 15:45:37 -02:00
Luiz Henrique de Figueiredo
536bae5871 corrected version test (0x23 not 23) 1996-11-14 13:00:32 -02:00
Luiz Henrique de Figueiredo
679eddf296 1996-11-14 11:33:15 -02:00
Luiz Henrique de Figueiredo
d991def36c added 3 new bytes to header (sizeof's) 1996-11-14 09:44:34 -02:00
Luiz Henrique de Figueiredo
8b195533d2 new header version 1996-11-14 09:44:34 -02:00
Roberto Ierusalimschy
3ccdd57c26 new version 1996-11-12 14:00:16 -02:00
Roberto Ierusalimschy
a103455dda better format for error messages. 1996-11-08 17:08:30 -02:00
Roberto Ierusalimschy
60242e1930 error message for syntax "1..2";
syntax error function is in "lex.c" (it has the token)
1996-11-08 10:49:35 -02:00
Roberto Ierusalimschy
a0e9bfbb48 syntax error function is in "lex.c" (it has the token) 1996-11-08 10:49:35 -02:00
Roberto Ierusalimschy
2f19e0ba16 SunOS is not ANSI about the return value of "sprintf". 1996-11-07 18:26:19 -02:00
Roberto Ierusalimschy
ab7fdcbbed corrected copyright notice 1996-11-07 18:26:08 -02:00
Luiz Henrique de Figueiredo
48cf1de356 replaced unions by memcpy 1996-11-07 12:13:28 -02:00
Luiz Henrique de Figueiredo
8d50122af0 replaced unions by memcpy 1996-11-07 11:59:51 -02:00
Roberto Ierusalimschy
fd379b38f7 new flag for STRERROR; libs now are called lib... 1996-11-06 18:48:03 -02:00
Roberto Ierusalimschy
aa4d865077 anna's comments 1996-11-06 18:26:56 -02:00
Roberto Ierusalimschy
3e94febfc1 pragmas should not be recognized inside literal strings. 1996-11-06 18:24:29 -02:00
Roberto Ierusalimschy
243b3a1a47 i/o functions return an error message 1996-11-01 16:02:53 -02:00
Roberto Ierusalimschy
389e808c60 although an ANSI function, some systems do not offer "strerror" 1996-11-01 15:54:41 -02:00
Roberto Ierusalimschy
450465c4d4 new parameters for "read" and "write". BIG CHANGE. 1996-11-01 15:03:36 -02:00
Roberto Ierusalimschy
2f44cc9f4d new pattern matching facilities; new version of i/o lib;
other small corrections.
1996-11-01 15:02:10 -02:00
Roberto Ierusalimschy
d106f3f43c pre-defined variable _VERSION_ 1996-11-01 10:47:45 -02:00
Roberto Ierusalimschy
bf3091d94f new version number 1996-11-01 10:46:59 -02:00
Roberto Ierusalimschy
4dbf7285a8 small omission corrected ("s_tsvalue") 1996-11-01 10:46:59 -02:00
Roberto Ierusalimschy
a1e41e3a12 small corrections in error messages 1996-10-31 18:18:05 -02:00
Roberto Ierusalimschy
9d0044ce53 "strfind" has an extra parameter to turn off all special characteres. 1996-10-31 15:26:04 -02:00
Roberto Ierusalimschy
37bf74efb7 some compilers do not accept "stdin"/"stdout" as constants. 1996-10-16 18:22:34 -02:00
Roberto Ierusalimschy
8c37d3b9d6 documentation of opcode meanings (thanks to lhf) 1996-09-26 18:08:41 -03:00
Roberto Ierusalimschy
0af581f0bf new way to handle pragmas (at the lexical level, instead of parsing). 1996-09-25 18:52:00 -03:00
Roberto Ierusalimschy
2a506ea9d2 lua_linenumber is initialized in lex.c 1996-09-25 09:57:22 -03:00
Roberto Ierusalimschy
e5ec547eb3 "call" returns separate results, instead of a table. 1996-09-24 18:46:44 -03:00
Roberto Ierusalimschy
6d383202dc "dofile" and "dostring" may return values. 1996-09-24 14:30:28 -03:00
Roberto Ierusalimschy
7b8166d7b3 a chunk may end with a return. 1996-09-24 14:29:50 -03:00
Roberto Ierusalimschy
3636bbad3a new function "strrep" 1996-09-20 15:20:44 -03:00
Roberto Ierusalimschy
82f9f3e552 better structure to control stack interface lua-C.
beginblock-endblock keeps better control over stack
1996-09-20 09:51:16 -03:00
Roberto Ierusalimschy
c96ad1c945 "strmap" replaced by "strupper" and "strlower" (that's what people will
use, anyway).
"gsub" aceppts a function to give the replacement string.
1996-09-16 15:02:40 -03:00
Roberto Ierusalimschy
5b9fbfa006 "dostring" now stores the prefix of its string, to improve error messages. 1996-09-11 18:53:02 -03:00
Roberto Ierusalimschy
f0cc2d5506 BUG: a program ending in a comment without EOL made lex loops forever. 1996-09-09 11:11:11 -03:00
Roberto Ierusalimschy
d289ac81d3 functions may have tags CMARK and MARK, too. 1996-09-02 18:57:51 -03:00
Roberto Ierusalimschy
15791f93fe lhf's corrections. 1996-08-28 17:46:26 -03:00
Roberto Ierusalimschy
d763b69740 skip first line of a lua file if it starts with a '#' (to allow shell
scripts).
1996-08-15 15:40:55 -03:00
Roberto Ierusalimschy
36dd1af92d "[^]]" must mean "not ]". 1996-08-09 10:14:11 -03:00
Roberto Ierusalimschy
25b6dae7c0 singlematch and item_end are used by "read", in iolib. 1996-08-05 17:55:24 -03:00
Roberto Ierusalimschy
1630c2533a Pattern-Matching!
plus several other changes...
1996-08-01 11:55:33 -03:00
Roberto Ierusalimschy
1d373d77de more functions exported. 1996-08-01 11:55:33 -03:00
Roberto Ierusalimschy
f025b0d160 "pushnil" is not needed (default return is nil). 1996-08-01 11:55:33 -03:00
Roberto Ierusalimschy
cc02b4729b new mod implementation (more portable). 1996-08-01 11:55:33 -03:00
Roberto Ierusalimschy
2bb3830fc1 "memcpy" is defined in "string.h". 1996-07-24 15:01:52 -03:00
Roberto Ierusalimschy
7a38bdd4b3 "exit" is defined in "stdlib". 1996-07-24 14:55:57 -03:00
Roberto Ierusalimschy
7614b17e85 very small corrections 1996-07-24 11:38:12 -03:00
Roberto Ierusalimschy
6dfdb76538 C functions don't need to "pushnil" to return nil value (this is
the default value).
1996-07-12 17:00:26 -03:00
Roberto Ierusalimschy
9a3c51cff1 new name for POSIX flag (this one turns on some posix stuff in standard
header files).
1996-07-06 17:20:35 -03:00
Roberto Ierusalimschy
6336d2f9e1 flag for direct execution is "-e"; argument with an "=" goes to
direct execution, independently of flags.
1996-07-05 17:55:43 -03:00
Roberto Ierusalimschy
ec6677e551 when "block" is computed, "nentity" == "block". So the change is only
a simpler way to write the same expression.
1996-06-18 18:12:23 -03:00
Roberto Ierusalimschy
20cbca699a "lua_dofile" has a more informative return code. 1996-06-18 17:08:40 -03:00
Roberto Ierusalimschy
3211a9648a "lua_dofile" returns different error codes if it could not open the file 1996-06-10 16:36:24 -03:00
Roberto Ierusalimschy
0baa915343 new option "-x" to execute a string given as argument. 1996-06-10 16:35:46 -03:00
Roberto Ierusalimschy
5cddb264d4 lexical analiser may use luaI_buffer, instead of waste space with
a separate buffer.
1996-05-30 11:04:07 -03:00
Roberto Ierusalimschy
9863223fbf first version of vararg facility (plus new function "call"). 1996-05-28 18:07:32 -03:00
Roberto Ierusalimschy
9a1948e67d small correction. 1996-05-27 11:06:58 -03:00
Roberto Ierusalimschy
f9deeac632 "luaI_malloc(s)" is just a macro to "luaI_realloc(NULL, s)". 1996-05-24 11:31:10 -03:00
Roberto Ierusalimschy
29f0021837 variables which contain string lengths must be long (if they also may
be negative) or size_t.
1996-05-22 18:59:07 -03:00
Roberto Ierusalimschy
7acddb871d memory manager for old versions of Lua. It should be in RCS since
the beginning.
1996-05-06 18:37:28 -03:00
Roberto Ierusalimschy
a7ca46405d unused "#include". 1996-05-06 13:59:00 -03:00
Roberto Ierusalimschy
0e2297afaa update of dependencies from "#include"s. 1996-05-06 11:38:40 -03:00
Roberto Ierusalimschy
0a1891f6a0 new version. 1996-05-06 11:32:59 -03:00
Roberto Ierusalimschy
1936a9e53b tables may grow bigger than words. 1996-05-06 11:30:27 -03:00
Roberto Ierusalimschy
820ec63bdf as strings are no more duplicated, "nextvar" can use "pushstring". 1996-05-06 11:29:35 -03:00
Roberto Ierusalimschy
01ea523b80 small corrections. 1996-05-03 17:10:59 -03:00
Roberto Ierusalimschy
88cf0836fc "isatty" is POSIX, but not ANSI. 1996-05-03 14:27:03 -03:00
Roberto Ierusalimschy
3ec9ee0d0f new function "luaI_openlib" to help open libs. 1996-04-30 18:13:55 -03:00
Roberto Ierusalimschy
21c9ebf4a9 new algotithm to adjust garbage collection: it tries to adapt gc calls
so that it collects half of the total objects when it is called.
1996-04-29 15:53:53 -03:00
Roberto Ierusalimschy
4fb77c4308 no more "lua_Reference"; new return value for "append";
documentation of "exit" (it was not in the manual).
1996-04-29 15:50:08 -03:00
Roberto Ierusalimschy
bced00ab9e lua_Reference is int, so say so. 1996-04-25 11:10:00 -03:00
Roberto Ierusalimschy
25116a3065 "malloc.h" is not ansi. 1996-04-25 11:01:27 -03:00
Roberto Ierusalimschy
eadbb9cff4 "stat" is not ansi. 1996-04-23 09:43:07 -03:00
Roberto Ierusalimschy
42b947296b "fileno" is not ansi. 1996-04-23 09:43:07 -03:00
Roberto Ierusalimschy
f37e65d1cb "exit" has an optional parameter of status. 1996-04-22 16:28:37 -03:00
Roberto Ierusalimschy
0ef5cf2289 lock mechanism seperseded by the REFERENCE mechanism. 1996-04-22 15:00:37 -03:00
Roberto Ierusalimschy
fed9408ab5 page size "letter". 1996-04-01 11:36:35 -03:00
Roberto Ierusalimschy
ce23901f04 smaller limit to stack size (otherwise C stack can finish first) 1996-03-22 16:12:15 -03:00
Roberto Ierusalimschy
df1ee1fb1c small "abstraction" 1996-03-22 14:57:24 -03:00
Roberto Ierusalimschy
f1d0276684 small bug in strfind. 1996-03-21 19:18:08 -03:00
Roberto Ierusalimschy
7ecc2ea597 new version 1996-03-21 18:30:29 -03:00
Roberto Ierusalimschy
7a35f23c16 a simplification about memory error messages. 1996-03-21 15:55:02 -03:00
Roberto Ierusalimschy
9284742a11 better control when growing arrays. 1996-03-21 13:33:47 -03:00
Roberto Ierusalimschy
9704ff4cb1 hook variables are global, no more "lua_set...hook" functions. 1996-03-20 15:44:02 -03:00
Roberto Ierusalimschy
e3c0ce9a69 dofile accepts pre-compiled chunks.
lua_is... do coercion.
small correction: = versus ==.
1996-03-19 19:39:07 -03:00
Roberto Ierusalimschy
85b76bcc01 functions "lua_is..." consider coercions.
small change when calling call hook.
1996-03-19 19:28:37 -03:00
Roberto Ierusalimschy
a275d9a25b functions "lua_is..." consider coercions. 1996-03-19 19:28:37 -03:00
Roberto Ierusalimschy
7e0be1fbde unused "#include" 1996-03-19 13:50:24 -03:00
Roberto Ierusalimschy
54ba642cc3 new module "undump.o" 1996-03-15 15:22:09 -03:00
Roberto Ierusalimschy
8826eb7918 small correction 1996-03-15 15:21:58 -03:00
Roberto Ierusalimschy
e701a86385 "openfile" now returns the file 1996-03-15 10:13:13 -03:00
Roberto Ierusalimschy
3e1f731826 integration with undump (execution of pre-compiled chuncks) 1996-03-15 10:13:13 -03:00
Roberto Ierusalimschy
f86c1367db new functions "rename" and "tmpname".
new option 'q' for function "format".
new example, about vararg.
1996-03-14 14:45:01 -03:00
Luiz Henrique de Figueiredo
58fd8aa851 added cast instead of union [lazy?] 1996-03-14 14:31:15 -03:00
Roberto Ierusalimschy
3226ac2da8 "lua_ntable" and "lua_nconstant" are public (undump.c uses them). 1996-03-14 12:57:19 -03:00
Roberto Ierusalimschy
3e9daa7416 creation of strings must call garbage collector. 1996-03-14 12:56:26 -03:00
Roberto Ierusalimschy
7236df875a new function "luaI_buffer". 1996-03-14 12:55:49 -03:00
Roberto Ierusalimschy
675e608325 new functions "rename" and "tmpname". 1996-03-14 12:55:18 -03:00
Roberto Ierusalimschy
1dc0e82aeb "freefunc" now is public. 1996-03-14 12:54:20 -03:00
Roberto Ierusalimschy
c2eb02aaf6 both "write" and "format" need "addquoted". 1996-03-14 12:53:09 -03:00
Roberto Ierusalimschy
2fee7e42c9 new option 'q' in function "format". 1996-03-14 12:52:35 -03:00
Roberto Ierusalimschy
281db390e8 no more "ugly" programs.
no more comments with '#'.
1996-03-14 12:17:28 -03:00
Luiz Henrique de Figueiredo
df8cf53cc9 removed tf->marked=0; 1996-03-12 17:00:40 -03:00
Roberto Ierusalimschy
40306b10db small corrections. 1996-03-12 12:56:03 -03:00
Luiz Henrique de Figueiredo
5eff5d3eac moved some includes from undump.h
LoadString now uses luaI_buffer
added LoadNewString
needs tf->marked=0
luaI_undump now returns int and aborts if luaI_dorun fails
1996-03-11 19:01:46 -03:00
Luiz Henrique de Figueiredo
8ad8426c43 moved some includes to undump.c
luaI_undump now returns int
1996-03-11 18:59:41 -03:00
Luiz Henrique de Figueiredo
3cab7cd025 undump.c is now a module
panic is now lua_error
 included swap.c
 tries float permutation earlier
 new functions: luaI_undump1 and luaI_undump
1996-03-08 18:44:12 -03:00
Luiz Henrique de Figueiredo
bb26efbbec definitions for lua decompiler
undump is now a module
1996-03-08 18:43:21 -03:00
Roberto Ierusalimschy
5c0e5fd36d details. 1996-03-08 09:04:04 -03:00
Roberto Ierusalimschy
621322a305 "PrintCode" now is defined in luac. 1996-03-08 09:02:37 -03:00
Luiz Henrique de Figueiredo
e33a3b8e0d now loads size as two words 1996-03-06 18:40:10 -03:00
Luiz Henrique de Figueiredo
9a6cccb08c removed support for local vars 1996-03-06 13:01:08 -03:00
Roberto Ierusalimschy
b58225e93b unused declaration removed. 1996-03-06 10:11:23 -03:00
Luiz Henrique de Figueiredo
852b919465 now swaps bytes (but need to make it more robust) 1996-03-05 22:41:18 -03:00
Roberto Ierusalimschy
ef94999647 parse.o was included twice in lua.a 1996-03-05 12:57:53 -03:00
Roberto Ierusalimschy
6f30fa98d8 small change to avoid error on "lua_pushstring(NULL)". 1996-03-04 11:46:35 -03:00
Roberto Ierusalimschy
74102bd716 small corrections. 1996-03-04 10:29:10 -03:00
Roberto Ierusalimschy
8d82aa821a small correction (about types) 1996-03-01 13:54:00 -03:00
Luiz Henrique de Figueiredo
cec1ffb80b uses ID_* constants
simplified signature checking
loads local vars
1996-03-01 00:43:50 -03:00
Luiz Henrique de Figueiredo
870967ca77 headers for Main and others are different 1996-02-28 20:10:46 -03:00
Roberto Ierusalimschy
66fc0f554a using double to read numbers. 1996-02-26 19:35:51 -03:00
Roberto Ierusalimschy
d6e4c29733 fixed strings (not collectable) don't need to be inserted in the constant table. 1996-02-26 18:00:27 -03:00
Luiz Henrique de Figueiredo
3e42969979 main always reads "luac.out" 1996-02-26 16:44:17 -03:00
Roberto Ierusalimschy
712ac505e0 small correction 1996-02-26 14:07:49 -03:00
Roberto Ierusalimschy
f935d3397e check if jump is bigger than 2^16. 1996-02-26 14:07:20 -03:00
Roberto Ierusalimschy
30dd3a2dbc small changes (preparing for new module of pre-compilation) 1996-02-26 14:06:39 -03:00
Luiz Henrique de Figueiredo
b04f88d581 functions now linked into a list headed by main 1996-02-24 13:44:28 -03:00
Luiz Henrique de Figueiredo
b3c10c8c41 fix to PUSHFUNCTION now correctly at tf->marked 1996-02-24 00:46:57 -03:00
Luiz Henrique de Figueiredo
5c1bd89a1c added fix to PUSHFUNCTION and support for main function 1996-02-23 19:00:26 -03:00
Luiz Henrique de Figueiredo
15f3ab09eb load bytecodes from files 1996-02-23 16:04:38 -03:00
Roberto Ierusalimschy
c7e834f424 function "write_quoted" rewritten more clearly. 1996-02-22 17:56:33 -03:00
Roberto Ierusalimschy
8c1a9899d4 functions "luaI_free" and "luaI_realloc" (or macro "growvector") may be
called with NULL.
1996-02-22 17:34:33 -03:00
Roberto Ierusalimschy
05caf09a36 list of incompatibilities with version 2.2.
new macro \Version.
1996-02-16 10:12:12 -03:00
Roberto Ierusalimschy
168a865e60 more appropriate error message for "date" 1996-02-16 10:10:14 -03:00
Roberto Ierusalimschy
15c17c24fa small improvements 1996-02-14 16:11:09 -03:00
Roberto Ierusalimschy
45cf24485d useless #include. 1996-02-14 15:25:04 -03:00
Roberto Ierusalimschy
c56e2b2e30 new version 1996-02-14 10:40:26 -03:00
Roberto Ierusalimschy
d1608c597e reserved words are stored in main string table; "marked" field is
used to indicate its type.
Table initializations centralized by "tree.c".
1996-02-14 10:35:51 -03:00
Roberto Ierusalimschy
0f4903a5d7 new header "lex.h". 1996-02-13 14:30:39 -03:00
Roberto Ierusalimschy
772f25d3dd new header for lex.c 1996-02-13 14:30:39 -03:00
Roberto Ierusalimschy
f1a1eda7c5 old trick in "strsub" does not work with new hash table for strings. 1996-02-12 15:34:44 -03:00
Roberto Ierusalimschy
41259bff31 BIG CHANGE: new data structure for constants, strings and globals, using
an array of hash tables for all them.
1996-02-12 15:32:40 -03:00
Roberto Ierusalimschy
afaa98a666 no more "lua_pushliteral". 1996-02-12 15:32:09 -03:00
Roberto Ierusalimschy
73be918285 a backslash followed by a newline allows the newline to go into
a string.
1996-02-09 17:35:23 -02:00
Roberto Ierusalimschy
ca412214cb new function "date", replaces old "date" and "time". 1996-02-09 17:02:30 -02:00
Roberto Ierusalimschy
801722825d "lua_check_number" accepts strings convertible to numbers. 1996-02-09 17:00:23 -02:00
Roberto Ierusalimschy
3abc25fa54 new functions "random" and "randomseed". 1996-02-09 15:21:27 -02:00
Roberto Ierusalimschy
f4d67761f1 new section describing the debug interface. 1996-02-09 14:37:58 -02:00
Roberto Ierusalimschy
369c5fe3c0 lock mechanism more robust; nil is pseudo-locked under index -1. 1996-02-08 17:08:34 -02:00
Roberto Ierusalimschy
7918c6cf11 small bug 1996-02-08 16:14:17 -02:00
Roberto Ierusalimschy
826d70fcba new type lua_Function for activation records 1996-02-08 15:03:20 -02:00
Roberto Ierusalimschy
bbb23048e3 correction of dependencies (include's). 1996-02-07 16:14:38 -02:00
Roberto Ierusalimschy
5a3a1fe458 debug interface functions to manipulated local variables:
"lua_getlocal" and "lua_setlocal".
1996-02-07 16:10:27 -02:00
Roberto Ierusalimschy
56fb06b6f5 "lua_debug" now is exported through debug interface (luadebug.h) 1996-02-07 12:14:40 -02:00
Roberto Ierusalimschy
995a9f7188 no more "Bool" type 1996-02-07 12:13:17 -02:00
Roberto Ierusalimschy
a0ef046ef1 elimination of unused declarations (left from old modifications) 1996-02-06 14:18:21 -02:00
Roberto Ierusalimschy
5fa51fc426 new option "q" in function "write", to write literal strings. 1996-02-05 19:32:19 -02:00
Roberto Ierusalimschy
15057aa0a4 new examples showing data structures and object-oriented programming.
generic improvements and corrections.
1996-02-05 12:52:47 -02:00
Roberto Ierusalimschy
1431b52e76 improve of compiling error messages. 1996-02-05 11:26:01 -02:00
Roberto Ierusalimschy
98fe770cab small bug 1996-02-04 14:59:12 -02:00
Roberto Ierusalimschy
43382ce5a2 new fallback "getglobal". 1996-01-30 13:25:23 -02:00
Roberto Ierusalimschy
abfebf1e21 new example showing how to build modules. 1996-01-30 13:24:49 -02:00
Roberto Ierusalimschy
b1c02c7f00 new fallback "getglobal".
modifications to generate an index (not automatically yet).
1996-01-30 10:55:10 -02:00
Roberto Ierusalimschy
84df3ac267 new functions "tostring", "assert", and "format". 1996-01-29 15:08:23 -02:00
Roberto Ierusalimschy
55a70c9719 "read('s')" was "eating" delimiter. 1996-01-29 14:40:09 -02:00
Roberto Ierusalimschy
0d50b87aa4 lua_table now has references to global variable names (TreeNode's). 1996-01-26 16:03:19 -02:00
Roberto Ierusalimschy
19290a8e92 "dofile" issues an error when called with non string arguments, and
runs stdin when called without arguments.
1996-01-26 14:52:47 -02:00
Roberto Ierusalimschy
d845963349 "setglobal" and "getglobal" moved to inout.c, as it concentrates pre-defined
library.
new function "assert".
1996-01-26 12:05:28 -02:00
Roberto Ierusalimschy
8dae4657a1 "setglobal" and "getglobal" moved to inout.c, as it concentrates pre-defined
library.
1996-01-26 12:04:32 -02:00
Roberto Ierusalimschy
ca7be1cfeb elimination of function "int2str", as it can be replaced by "format('%c', .)" 1996-01-26 10:11:28 -02:00
Roberto Ierusalimschy
445872a6e2 "dofile" does not issue a warning when unable to open the file,
but only returns an error code.
1996-01-23 16:43:07 -02:00
Roberto Ierusalimschy
3681d025ac new function "assert" 1996-01-23 16:39:45 -02:00
Roberto Ierusalimschy
2998049f51 local variable stack needs only the name of the variable (TreeNode);
this way is simpler and faster than old way.
1996-01-23 15:50:29 -02:00
Roberto Ierusalimschy
24ccc7c038 correction of some order dependencies in debug code. 1996-01-22 16:39:37 -02:00
Roberto Ierusalimschy
be48c4d91e add_char now is global.
time returns week-day.
1996-01-22 15:46:55 -02:00
Roberto Ierusalimschy
a19f9056f3 new function "tostring". 1996-01-22 15:40:00 -02:00
Roberto Ierusalimschy
5b71ab780c add_char now is global.
new function format.
1996-01-22 15:38:57 -02:00
Roberto Ierusalimschy
481bafd581 add_char now is global. 1996-01-22 15:38:57 -02:00
Roberto Ierusalimschy
e74b250d71 memory overflow tries a garbage collection; if it fails then exit the
program.
1996-01-22 12:15:13 -02:00
Roberto Ierusalimschy
cd54c95ee1 bug: "read" with format MUST read given number of chars (if file ends
before that reports an error, returning nil).
"readuntil" can be called with nil or no parameters to read until EOF.
1996-01-12 15:00:30 -02:00
Roberto Ierusalimschy
bf006eeaf5 "getobjectname" got a "lua_" prefix. 1996-01-09 18:23:19 -02:00
Roberto Ierusalimschy
b2afc410fa hooks for line change and function calls; first version. 1996-01-09 18:22:44 -02:00
Roberto Ierusalimschy
19cfa32393 correction of dependencies from "luadebug.h". 1996-01-09 18:22:08 -02:00
Roberto Ierusalimschy
27ae8432b6 names generated by yacc (starting with "yy") are changed to start with
"luaY_", to avoid name clashes with hosts using yacc.
1995-12-21 14:14:04 -02:00
Roberto Ierusalimschy
415ee250b5 bug: luaI_findconstantbyname may change the value of lua_constant. 1995-12-18 14:47:29 -02:00
Roberto Ierusalimschy
f188e1000b useless "#include math.h" 1995-11-16 18:46:24 -02:00
Roberto Ierusalimschy
07d64e78b6 reference manual 1995-11-16 18:46:02 -02:00
Roberto Ierusalimschy
fa649fbc26 new distribution 1995-11-13 13:36:52 -02:00
Roberto Ierusalimschy
0c3e0fd95d "read" must return 'nil' on EOF. 1995-11-10 16:32:59 -02:00
Roberto Ierusalimschy
3bb6443131 changes to improve portability 1995-11-10 15:56:06 -02:00
Roberto Ierusalimschy
f57afd6e32 re-implementation of functions "write" and "read" 1995-11-10 15:55:48 -02:00
Roberto Ierusalimschy
5f664a4516 error functions are shared by all libraries 1995-11-10 15:54:31 -02:00
Roberto Ierusalimschy
87fe07c0d4 little improvement 1995-11-10 12:12:02 -02:00
Roberto Ierusalimschy
f9a9bd77e4 print_stack now gets a parameter (file to print);
small changes.
1995-11-03 13:43:50 -02:00
Roberto Ierusalimschy
63b8a6fd20 "getobjname" checks first fallbacks (so, if a function is global and
a fallback, it is reported as a fallback).
1995-11-03 13:30:50 -02:00
Roberto Ierusalimschy
024f2374ab "AUTHORS" separated from COPYRIGHT. 1995-10-31 15:05:35 -02:00
Roberto Ierusalimschy
9d9f9c48ff local variables may appear inside blocks in main code. 1995-10-26 15:02:50 -02:00
Roberto Ierusalimschy
15d48576ea functions now may be declared with any "var" as a name;
therefore they do not have a "baptism" name.
Changes in debug API to acomodate that.
1995-10-26 12:21:56 -02:00
Roberto Ierusalimschy
39b071f7b1 new syntax for function declarations: "function a.x () ... "
new semantics for function declarations: function f () is valid only
at run-time.
1995-10-25 12:33:25 -02:00
Roberto Ierusalimschy
9efc257d9d new method to keep debug line information: current line is stored on the
Lua stack, just below (new) base, with tag LUA_T_LINE.
SETLINE opcodes are generated by lex.
1995-10-25 11:05:51 -02:00
Roberto Ierusalimschy
fa71304e54 "dofile" now accepts NULL as parameter, to run stdin. 1995-10-23 11:54:11 -02:00
Roberto Ierusalimschy
b5745d11cd uses "isatty" to check if executes stdin line by line or as a file. 1995-10-23 11:54:11 -02:00
Roberto Ierusalimschy
ebcf546a55 small changes in the format of debug information. 1995-10-23 11:53:48 -02:00
Roberto Ierusalimschy
2b45f8967c small bug 1995-10-17 16:16:58 -02:00
Roberto Ierusalimschy
a66404aca6 function "setfallback" now gives an error if called with wrong parameters. 1995-10-17 12:30:05 -02:00
Roberto Ierusalimschy
d80659759b new module luadebug.h. 1995-10-17 12:12:45 -02:00
Roberto Ierusalimschy
d24253d92f module to declare API for debuging. 1995-10-17 12:12:45 -02:00
Roberto Ierusalimschy
2cffb08a5c new style for debug information about functions: no more SETFUNCTION
opcodes. When a function is called, its entry in the stack is marked with
LUA_T_(C)MARK, so function 'luaD_stackedfunction' can find it if
needed.
Functions now have their file names in the headers, so there is no need
of 'addfile' and the like.
1995-10-17 09:58:41 -02:00
Roberto Ierusalimschy
15f40fddca 'nextvar' now traverses the symbol array, instead of the constant tree. 1995-10-17 09:53:53 -02:00
Roberto Ierusalimschy
970995c3f2 'luaI_travfallbacks' now can look for a fallback. 1995-10-17 09:52:38 -02:00
Roberto Ierusalimschy
b17c76817d new function "luaI_findconstantbyname". 1995-10-13 12:16:25 -03:00
Roberto Ierusalimschy
b074306267 bug. "fgets" reads n-1 chars. 1995-10-11 17:50:56 -03:00
Roberto Ierusalimschy
3c75b75516 new module "func", for GC of functions,
and new "defines" for configuration setup.
1995-10-09 15:51:49 -03:00
Roberto Ierusalimschy
36a7fda014 bug: stack overflow error must leave space on the stack for error function. 1995-10-09 15:45:59 -03:00
Roberto Ierusalimschy
1bb3fb73cc fallback table now has number of parameters and results of each
fallback. This information is used by opcode.c, when calling a fallback.
1995-10-09 10:14:29 -03:00
Roberto Ierusalimschy
7e01348658 "docall" now assumes that called function is always on the stack, just
below "base". That gives more regularity for the stack shape, and
prevents fallbacks of being garbage collected if they are redefined
during execution.
1995-10-09 10:10:20 -03:00
Roberto Ierusalimschy
28b3017baf lua function "type" now returns the string "function" both for lua
functions and c functions.
1995-10-09 10:06:20 -03:00
Roberto Ierusalimschy
ae808860ae new functions: "ascii" and "int2str",
small "re-engineering" on parameter checking.
1995-10-09 09:49:21 -03:00
Roberto Ierusalimschy
a47e8c7dd0 small "re-engineering" on parameter checking.
correction of function "atan2".
1995-10-09 09:48:38 -03:00
Roberto Ierusalimschy
79ce619876 new command line options: -v to print Copyright message, and
- to read stdin.
1995-10-06 11:11:40 -03:00
Roberto Ierusalimschy
233f0b0cc7 definitions for Copyright and version notices 1995-10-06 11:11:10 -03:00
Roberto Ierusalimschy
025589f772 nova forma de comentarios: de '#' ate' fim de linha (para uso de lua
como shell)
1995-10-06 10:10:53 -03:00
Roberto Ierusalimschy
68f337dfa6 Garbage collection of functions + header structure for functions 1995-10-04 14:13:02 -03:00
Roberto Ierusalimschy
f132ac03bc Module to manipulate function headers. 1995-10-04 11:20:26 -03:00
Roberto Ierusalimschy
ec785a1d65 new option for "writeto" and "readfrom", to allow piped I/O on
machines that support it.
1995-10-04 10:53:10 -03:00
Roberto Ierusalimschy
e0621e6115 new function "atan2". 1995-10-04 10:52:09 -03:00
Roberto Ierusalimschy
38411aa102 small correction to avoid problems with DOS/Windows 1995-10-03 15:06:10 -03:00
Roberto Ierusalimschy
3ec4f4eb86 small corrections to avoid warnings. 1995-10-02 14:03:33 -03:00
Roberto Ierusalimschy
367139c6d9 buffer for literals now grows dynamically, allowing big programs between [[ and ]]. 1995-09-15 17:48:26 -03:00
Roberto Ierusalimschy
457bac94ce small corrections to avoid uninitialized global variables. 1995-09-15 17:47:53 -03:00
Roberto Ierusalimschy
bcf46ee83b new syntax for strings: [[ ... ]]. Still in tests,
since the code does not check buffer overflow.
1995-07-06 14:47:08 -03:00
Roberto Ierusalimschy
97b2fd1ba1 syntax for {...;...} is more flexible now. 1995-06-08 16:47:28 -03:00
Waldemar Celes
e13753e2fb Ajustar limites para garbage collection. 1995-05-16 16:23:55 -03:00
Roberto Ierusalimschy
ec79f25286 new lua function "getstack"; new interface to function luaI_reportbug. 1995-05-16 14:23:58 -03:00
Roberto Ierusalimschy
18ea2eff80 calls to "lua_reportbug" changed to "lua_error", since
"lua_reportbug" is only an internal function to build debug information
1995-05-02 15:43:03 -03:00
Waldemar Celes
8156604823 run-time stack now is controled at run time, instead of
compilation time.
1995-04-11 14:56:30 -03:00
Roberto Ierusalimschy
36b6fdda83 function "type" now returns a second result: the tag of the type,
so lua can discriminate different kinds of user data.
1995-03-17 17:42:20 -03:00
Waldemar Celes
3c67d2595b error message buffer got a bigger size 1995-03-17 17:27:11 -03:00
Roberto Ierusalimschy
2043a0ca30 adjust checks if stack has enough space 1995-02-10 10:51:29 -02:00
Luiz Henrique de Figueiredo
0761c4c036 included string.h 1995-02-07 14:04:15 -02:00
Roberto Ierusalimschy
2d053126e6 new function for copy strings (strdup is not ANSI) 1995-02-06 17:37:51 -02:00
Roberto Ierusalimschy
3203460c9e better approximation for PI 1995-02-06 17:36:43 -02:00
Roberto Ierusalimschy
bb00cd66a7 function "stat" needs "sys/types.h" 1995-02-06 17:36:13 -02:00
Roberto Ierusalimschy
7c342c488e header "stdlib.h" was missing (gcc does not warn that) 1995-02-06 17:35:09 -02:00
Roberto Ierusalimschy
b36cd823b1 header "string.h" was missing (gcc does not warn that) 1995-02-06 17:34:03 -02:00
Roberto Ierusalimschy
cda444d7f4 type names changed to avoid clashes 1995-02-06 17:32:43 -02:00
Roberto Ierusalimschy
dd28b830e9 a null lua_Object is LUA_NOOBJECT, not NULL. 1995-02-02 18:05:37 -02:00
Roberto Ierusalimschy
572ee14b52 use yacc++ instead of yacc. 1995-02-02 17:04:16 -02:00
Roberto Ierusalimschy
6198626138 libs should not use Lua internal functions (like mem.h).
a null lua_Object is LUA_NOOBJECT, not NULL.
1995-02-02 16:54:58 -02:00
Waldemar Celes
8795aab83e new API function lua_pushlocked & lua_checkstack is a macro 1995-01-27 15:19:06 -02:00
Waldemar Celes
f83db16cab new API function lua_pushlocked 1995-01-27 15:19:06 -02:00
Waldemar Celes
6e0e9935ec trocar a funcao para garbage colector adaptativo. 1995-01-18 18:15:54 -02:00
Waldemar Celes
97053335fb Trocar 'pushstring' por 'pushliteral' na macro 'getfield'. 1995-01-18 18:15:05 -02:00
Roberto Ierusalimschy
f4591397da strdup is done via mem.c to control its memory allocation 1995-01-14 13:40:26 -02:00
Roberto Ierusalimschy
8faf4d1de2 control of garbage collection is done with Longs, as there can be
more than WORD objects to collect.
1995-01-12 12:19:04 -02:00
Roberto Ierusalimschy
53c0a0f43c function 'strfind' now has two optional parameters, to specify where
to start and stop the search.
1995-01-06 18:31:10 -02:00
Roberto Ierusalimschy
ad97e9ccbc small bug in fallback for power operator 1995-01-04 16:49:54 -02:00
Waldemar Celes
e4c69cf917 correcao de bug na construcao do formato. 1995-01-03 11:14:13 -02:00
Roberto Ierusalimschy
5b8ced84b4 stack is indexed by integers, not Words, to allow bigger stack on 32 bit machines 1994-12-30 15:45:11 -02:00
Roberto Ierusalimschy
df3a81ec88 functions that no more return error codes now have return type void 1994-12-28 10:55:47 -02:00
Waldemar Celes
b8e76d9b5c 'lua_getsubscript' and 'lua_storesubscript' now run unprotected (to improve efficiency) 1994-12-27 18:53:15 -02:00
Waldemar Celes
dc97a07e19 better names for 'y.tab.c' and 'y.tab.h' (now they are moved to 'parser.c' and 'parser.h') 1994-12-27 18:50:38 -02:00
Waldemar Celes
4dce79f7e3 uses 'limits.h' for MAX_WORD and MAX_INT 1994-12-27 18:41:47 -02:00
Waldemar Celes
a8220feed2 bytecodes are indexed by integers, not Words, to allow bigger code on 32 bit machines 1994-12-27 18:41:11 -02:00
Waldemar Celes
8bc4b0d741 routines are defined before rules, to allow correct compilation with bison 1994-12-27 18:04:29 -02:00
Roberto Ierusalimschy
96b2b90c50 new file 'types.h' 1994-12-23 18:47:59 -02:00
Roberto Ierusalimschy
89d823f16b implementation dependent types 1994-12-20 19:31:01 -02:00
Roberto Ierusalimschy
8cb8594a3b better control of integer types and their limits 1994-12-20 19:20:36 -02:00
Roberto Ierusalimschy
fe8338335d a field with value 'nil' must call the fallback 'index' 1994-12-16 14:08:34 -02:00
Roberto Ierusalimschy
068d1cd1ee new constant LUA_NOOBJECT.
'lua_createtable' does not have parameters.
'lua_copystring' now is a macro
1994-12-16 13:56:45 -02:00
Roberto Ierusalimschy
3365a35243 new constant LUA_NOOBJECT 1994-12-16 13:55:04 -02:00
Roberto Ierusalimschy
fad57bfa00 new constant LUA_NOOBJECT.
'lua_error' never returns
1994-12-16 13:53:57 -02:00
Waldemar Celes
891cab8a31 Passar os argv apos '--' para Lua.
Captura-se cada argv com a funcao argv(i), onde i = 1, 2, ...
1994-12-14 17:58:20 -02:00
Roberto Ierusalimschy
2486d677c9 no special treatment for C++ (this should be done in the C++ code) 1994-12-13 13:59:16 -02:00
Roberto Ierusalimschy
84b99d25ad debug message goes to stderr 1994-12-13 13:55:41 -02:00
Roberto Ierusalimschy
5dfd17dd76 new API function 'lua_pushliteral' 1994-12-13 13:54:21 -02:00
Roberto Ierusalimschy
ce4fb88b34 opcode PUSHSELF has a parameter that indicates the method to be called 1994-12-06 12:27:18 -02:00
Roberto Ierusalimschy
e742d54253 small bug correction 1994-11-30 19:20:37 -02:00
Roberto Ierusalimschy
0f580df73c 'main' returns condition code 1994-11-28 15:12:49 -02:00
Roberto Ierusalimschy
2b301d711b new hash function; hash value for strings are kept with the string 1994-11-28 13:10:51 -02:00
Roberto Ierusalimschy
10bdd83844 new hash function; hash value for strings are kept with the string 1994-11-25 17:27:03 -02:00
Roberto Ierusalimschy
fbfa1cbe9b erased function yywrap (nobody used it) 1994-11-25 17:24:57 -02:00
Roberto Ierusalimschy
10c1641b8e new modules 'mem' and 'fallback'.
correction of dependencies
1994-11-23 18:15:04 -02:00
Roberto Ierusalimschy
e901e0feae modifications to avoid warnings when compiling yacc code 1994-11-23 12:39:52 -02:00
Roberto Ierusalimschy
d490555ec9 garbage collection tag for strings organized in struct TaggedString 1994-11-23 12:32:00 -02:00
Roberto Ierusalimschy
ad0ec203f6 small simplification 1994-11-22 14:13:45 -02:00
Roberto Ierusalimschy
577ae944e9 correction of function tonumber 1994-11-22 14:02:53 -02:00
Roberto Ierusalimschy
68d1091b79 no more unary '+' 1994-11-22 13:50:46 -02:00
Roberto Ierusalimschy
52db68a600 debug shows lines where functions were called 1994-11-21 19:41:09 -02:00
Roberto Ierusalimschy
bba1ae427f new lua functions 'getglobal' and 'setglobal' 1994-11-21 19:41:09 -02:00
Roberto Ierusalimschy
609392ff2e fallback for "call expression not a function" errors 1994-11-21 16:22:58 -02:00
Roberto Ierusalimschy
96ea2e0fb4 fallback to unary minus is 'arith' with operation code 'unm' 1994-11-21 11:30:15 -02:00
Roberto Ierusalimschy
93ccdd52ef lua_lock receives its parameter via stack.
beginblock and endblock do not have parameters
1994-11-18 17:46:21 -02:00
Roberto Ierusalimschy
333a4f13d0 lua_lock receives its parameter via stack 1994-11-18 17:46:21 -02:00
Roberto Ierusalimschy
73664eb739 function 'lua_createstring' moved from table.c to tree.c 1994-11-18 17:27:38 -02:00
Roberto Ierusalimschy
feed56a01c small correction 1994-11-17 19:27:30 -02:00
Roberto Ierusalimschy
1929ddcf49 userdata can have different tags 1994-11-17 19:23:43 -02:00
Roberto Ierusalimschy
aa4cd37adf small bug corrected 1994-11-17 19:11:37 -02:00
Roberto Ierusalimschy
a84aa11f71 pow operation is defined in mathlib.c 1994-11-17 17:43:34 -02:00
Roberto Ierusalimschy
9bee23fd05 listing did not list POWOP 1994-11-17 17:09:46 -02:00
Roberto Ierusalimschy
3bd0f9e211 uses new memory module (mem.c).
small changes in seting debug line.
if and elseif unified in a outine 'codeIf'
1994-11-17 16:59:06 -02:00
Roberto Ierusalimschy
5406d391cd new API functions startblock and endblock 1994-11-17 14:41:42 -02:00
Roberto Ierusalimschy
b234da1cc2 changes in garbage collection control 1994-11-17 11:58:57 -02:00
Roberto Ierusalimschy
d6a1699e37 uses a single list to keep allocated strings. 1994-11-16 16:09:11 -02:00
Roberto Ierusalimschy
a5862498a1 set first position of a free block to -1, to catch errors 1994-11-16 16:09:11 -02:00
Roberto Ierusalimschy
2b5bc5d1a8 new module for memory allocation 1994-11-16 15:39:16 -02:00
Roberto Ierusalimschy
94686ce585 correction of function 'nextvar' 1994-11-16 14:03:48 -02:00
Roberto Ierusalimschy
86b35cf4f6 unification of symbol tree and constant tree 1994-11-14 19:40:14 -02:00
Roberto Ierusalimschy
3b7a36653b lua_equalObj now is global (and is used by opcode) 1994-11-14 16:41:15 -02:00
Roberto Ierusalimschy
e1d91fd0e1 new API function to create tables 1994-11-13 14:17:04 -02:00
Roberto Ierusalimschy
5e60b961de small changes to avoid shadowing 1994-11-13 12:54:18 -02:00
Roberto Ierusalimschy
e4645c835d small changes in 'ugly' part. 1994-11-13 12:39:04 -02:00
Roberto Ierusalimschy
0c5ac77c99 small corrections to avoid 'warings' with acc.
do_call was moving results in the wrong order.
1994-11-11 12:00:08 -02:00
Roberto Ierusalimschy
b8996eaaba small corrections to avoid 'warings' with acc 1994-11-11 12:00:08 -02:00
Roberto Ierusalimschy
ff7f769454 small changes in error recovery 1994-11-10 18:41:37 -02:00
Roberto Ierusalimschy
8a0521fa52 fallback for garbage collection 1994-11-10 15:36:54 -02:00
Roberto Ierusalimschy
9deac27704 fallback list moved from opcode.c to fallback.c 1994-11-10 15:11:52 -02:00
Roberto Ierusalimschy
d531ccd082 execution of 'mains' separated from calls 1994-11-09 16:13:29 -02:00
Roberto Ierusalimschy
df0cfc1e19 calls lua_reportbug instead of lua_error, in default fallbacks 1994-11-09 16:12:42 -02:00
Roberto Ierusalimschy
5f2d187b73 frees file names when unstacked 1994-11-09 16:11:47 -02:00
Roberto Ierusalimschy
6b387e01b2 lua_parse has a different interface 1994-11-09 16:10:58 -02:00
Roberto Ierusalimschy
d0780fa16d lua_call cannot be a macro, because it would push the function
over the parameters
1994-11-09 16:10:11 -02:00
Roberto Ierusalimschy
fc0de64c2c lua_debugline is kept in the stack 'funcstack' when debugging. 1994-11-09 16:09:22 -02:00
Roberto Ierusalimschy
b8bfa9628d because lua_error does a longjmp, there is no need to a variable
'err'.
lua_parse has a different interface, to allow the free of the main
block even if compilation fails.
small changes in the debug system.
1994-11-09 16:07:38 -02:00
Roberto Ierusalimschy
dabe09518f garbage collection for locked objects 1994-11-08 18:07:54 -02:00
Roberto Ierusalimschy
65f28f0824 error function for Lua 1994-11-08 18:06:15 -02:00
Roberto Ierusalimschy
2cf954b8ae lock mechanism 1994-11-08 17:56:39 -02:00
Roberto Ierusalimschy
aa7b1fcec4 new API 1994-11-07 16:27:39 -02:00
Roberto Ierusalimschy
d95a8b3121 new API: lua_Object now is an integer 1994-11-07 14:34:44 -02:00
Roberto Ierusalimschy
9ffba7a3db first implementation of 'fallbacks' 1994-11-07 13:20:56 -02:00
Roberto Ierusalimschy
de4e2305c5 Type renamed to lua_Type 1994-11-07 13:20:56 -02:00
Roberto Ierusalimschy
63d300167e module to implement default fallbacks and lock mechanisms 1994-11-07 13:20:56 -02:00
Roberto Ierusalimschy
62ec3797d5 inheritance is not built-in 1994-11-07 13:19:51 -02:00
Roberto Ierusalimschy
0a5dce5704 new opcodes for '>' and '>=' 1994-11-06 13:35:04 -02:00
Roberto Ierusalimschy
8c22057b2e new global function 'setfallback' 1994-11-04 15:20:00 -02:00
Roberto Ierusalimschy
253655ae4b small corrections. 1994-11-04 08:47:49 -02:00
Roberto Ierusalimschy
c635044f2f creation of function do_protectedrun, that executes lua code enclosed
in a setjmp, with error recovery.
Elimination of functions lua_isnil, etc.
1994-11-04 08:47:49 -02:00
Roberto Ierusalimschy
3db06a95a3 Elimination of functions lua_isnil, etc. 1994-11-04 08:47:49 -02:00
Roberto Ierusalimschy
31d58e2f01 more functions from opcode.c
'open_file' and 'open_string' return an error message
lua_type renamed to luaI_type (I for Internal, as this function is not
exported outside lua)
1994-11-03 20:34:29 -02:00
Roberto Ierusalimschy
42ef3f9388 there is no need of predefined constants. 1994-11-03 20:33:40 -02:00
Roberto Ierusalimschy
2651afc455 RESET is generated at codereturn. 1994-11-03 20:32:42 -02:00
Roberto Ierusalimschy
5cb6856ebc because lua_error now does a longjmp, many functions do not need
to check conditions.
1994-11-03 20:20:15 -02:00
Roberto Ierusalimschy
852d9a8597 function 'lua_addfile' returns an error message 1994-11-03 19:48:36 -02:00
Roberto Ierusalimschy
6b18cc9a17 prototype for function 'yylex' 1994-11-03 15:09:20 -02:00
Roberto Ierusalimschy
fbf887ec2b new way to call functions, plus several small changes. This is
a temporary version!
1994-11-02 18:30:53 -02:00
Roberto Ierusalimschy
ae77864844 tags T_NIL, etc, changed to LUA_T_NIL, etc
some lua_ functions changed form opcode.c to here
1994-11-02 18:29:39 -02:00
Roberto Ierusalimschy
0162decc58 tags T_NIL, etc, changed to LUA_T_NIL, etc 1994-11-02 18:29:09 -02:00
Roberto Ierusalimschy
ac68a3abc4 frees filename from file stack 1994-11-02 17:09:23 -02:00
Roberto Ierusalimschy
f53460aab9 CREATEARRAY now has an argument, the size of the array to create. 1994-11-01 16:25:20 -02:00
Roberto Ierusalimschy
41e4c5798e small corrections 1994-11-01 15:54:31 -02:00
Roberto Ierusalimschy
fb23cd2e26 deletion of 'include mm.h' 1994-10-21 17:00:12 -02:00
Waldemar Celes
2f1de3b1e1 implementacao das funcoes 'date', 'time' e 'beep'.
troca de nome de 'abort' para 'exit'
1994-10-19 15:02:20 -02:00
Roberto Ierusalimschy
1a6536aaad deletion of 'include mm.h' 1994-10-18 16:34:47 -02:00
Waldemar Celes
d7cb47fadf new parameter in function 'tree_create'. Maybe we will return to
version 1.1
1994-10-18 15:36:11 -02:00
Waldemar Celes
f84abc6799 split to 'ugly.h'. 1994-10-18 15:34:34 -02:00
Waldemar Celes
3386e3c1fb definition of ugly tokens 1994-10-18 12:30:29 -02:00
Roberto Ierusalimschy
25010f8e09 remove of 'printf' for debuging. 1994-10-17 19:45:00 -02:00
Waldemar Celes
424db1db0c power operator (^).
no more contructors (@).
methods can be called on indexed variables.
fixed debuging information.
1994-10-17 17:05:32 -02:00
Waldemar Celes
e9049cbfc9 files end with EOF, instead of 0. 1994-10-17 17:04:19 -02:00
Waldemar Celes
f8c8159362 adaptative garbage collection. 1994-10-17 17:03:23 -02:00
Waldemar Celes
d1c5f42943 new algorithm for reading floats.
files end with EOF, instead of 0.
1994-10-17 17:01:53 -02:00
Waldemar Celes
ad07c0f638 new operations POWOP (power) and PUSHMARKMET (for marking method calls).
remove of operation PUSHOBJECT.
1994-10-17 17:00:40 -02:00
Waldemar Celes
fca10c6733 Aumentar buffer para saida. 1994-10-13 16:28:54 -03:00
Waldemar Celes
6bc68d4645 Acertar bug para evitar formato "%5.0s", por exemplo. 1994-10-13 14:18:32 -03:00
Waldemar Celes
ceaaa0cca8 Correcao do tratamento de erro reportado dentro de uma funcao. 1994-10-11 11:38:17 -03:00
Waldemar Celes
82ceb12b7a Implementacao das funcoes para conversao de angulos rad r deg. 1994-10-11 10:06:47 -03:00
Waldemar Celes
87dded9363 Mudancas na sintaxe para a versao 2.0. Igual relacional passa
a ser ==, tiramos o colchete na criacao de tabelas usando apenas
chaves (podendo fazer inicializacao mista). O caracter  @ so' deve
estar presente quando se tem construtores associados.
/
1994-10-11 10:02:39 -03:00
Waldemar Celes
d107d5bfd2 implementacao de busca no campo godparent em substituicao
ao campo parents.
1994-10-11 09:59:49 -03:00
Waldemar Celes
d7d7b477bb consertar bug no formato real com zero casas decimais e
implementar a funcao readuntil.
1994-10-07 19:47:05 -03:00
Waldemar Celes
dc6d0dcc09 retirar especificador de formato %n da funcao ToReal e
acertar funcao lua_convtonumber.
1994-09-27 18:43:30 -03:00
Waldemar Celes
7cfb5ff41f Mudancas para tornar lex.c um modulo independente dos outros
modulos de Lua
1994-09-26 13:21:52 -03:00
Luiz Henrique de Figueiredo
24c962de43 added support for ugly tokens 1994-09-22 09:44:00 -03:00
Waldemar Celes
98d9509676 sai strtod, entra sscanf. permite conversao de numeros com espacos em volta. 1994-09-20 12:11:11 -03:00
Waldemar Celes
98263e2ef1 acertar bug no formato de string. 1994-09-12 16:24:31 -03:00
Waldemar Celes
d2117d66ec default size for arrays is no more 101, as arrays now can grow. 1994-09-08 13:51:49 -03:00
Waldemar Celes
0dcae99d74 new field 'next' in struct 'Hash', to list tables for garbage collection. 1994-09-08 13:51:49 -03:00
Waldemar Celes
b826a39919 Implementacao de heranca multipla. 1994-09-08 12:27:10 -03:00
Waldemar Celes
1ea0d09281 Alteracao do buffer de funcao de 32 para 64. 1994-09-05 18:22:43 -03:00
Waldemar Celes
3693f3f062 escapes \' e \" em strings; correcao do escape \\ 1994-09-05 16:14:40 -03:00
Waldemar Celes
0c6b906c8c Compatibilizacao com C++. 1994-08-24 12:29:02 -03:00
Roberto Ierusalimschy
9294a2787f nova funcao 'debug', para auxiliar debugacao de programas lua. 1994-08-17 19:34:20 -03:00
Roberto Ierusalimschy
0ec3a21451 inclui 'lua.h' que contem prototipos das funcoes 'lua_errorfunction' e
'lua_error'.
1994-08-17 19:22:44 -03:00
Waldemar Celes
0624540eef Implementacao da macro 'lua_strcmp' 1994-08-17 14:41:50 -03:00
Waldemar Celes
a4eeb099c8 Alteracao na macro 'streq' 1994-08-17 14:41:23 -03:00
Waldemar Celes
c364c7286f inclusao de 'lualib.h' para ter prototipos das funcoes de
'iolib_open' e 'strlib_open'.
1994-08-17 12:10:04 -03:00
Waldemar Celes
7c05266050 novas funcoes 'gettable' e 'pushtable'. 1994-08-17 12:05:08 -03:00
Waldemar Celes
592a949272 heranca e nova implementacao do hash. 1994-08-17 12:03:11 -03:00
Waldemar Celes
c4b8b1b989 novas funcoes 'gettable' e 'pushtable', nova implementacao do hash e
heranca nas indexacoes.
1994-08-17 12:02:03 -03:00
Waldemar Celes
f490b1bff8 Implementacao das funcoes 'log', 'log10' e 'exp'. 1994-08-15 11:13:44 -03:00
Waldemar Celes
3921b43e44 Implementacao das funcoes 'getenv' e 'abort' 1994-08-11 20:11:57 -03:00
Waldemar Celes
b28da81cfe Alteracao do hash, trocando tratamento de colisao por lista
pela estrategia de re-hash.
Foi feito uma avaliacao da funcao de hash, e constatado sua
eficiencia com uma media de 4 acessos no hash ate' 70% ocupado.
1994-08-09 08:24:45 -03:00
Waldemar Celes
41fd23287a Implementacao da definicao e chamada de METODOS. 1994-08-05 16:31:09 -03:00
Waldemar Celes
be7aa3854b implementacao de dois buffer de 'yytext' para evitar bug
no look ahead do yacc
1994-08-05 16:27:41 -03:00
Waldemar Celes
088cc3f380 evitar, durante consultas, criacao de nos nao encontrados. 1994-08-05 16:25:09 -03:00
Waldemar Celes
5034be6635 Alteracao na funcao 'write" para permitir acrescentar caracteres
de espacamento, tabs, newline, etc. nos formatos.
Corrigiu tambem bug do formato 'F' maiusculo.
1994-08-04 13:23:29 -03:00
Waldemar Celes
b1e9b37883 Implementacao de funcoes para tratar Lua function em C e
correcoes de bugs nas tabelas dinamicas.
1994-08-03 11:15:46 -03:00
Roberto Ierusalimschy
467288e5b3 arquivo nao mais utilizado em Lua. 1994-07-21 14:27:43 -03:00
Waldemar Celes
e9e9cb03f0 Aumentar precisao do valor de PI. 1994-07-20 19:12:27 -03:00
Waldemar Celes
0eb6ee3fee novos warnings "missing-prototypes" e "ansi". 1994-07-19 19:17:02 -03:00
Waldemar Celes
6c99b8bbdf opcao "clear" para limpar arquivos que podem ser reconstruidos pelo
make (menos os .a e o executavel "lua").
1994-07-19 19:04:51 -03:00
34 changed files with 7275 additions and 3405 deletions

View File

@@ -1,3 +0,0 @@
1d
x

191
fallback.c Normal file
View File

@@ -0,0 +1,191 @@
/*
** fallback.c
** TecCGraf - PUC-Rio
*/
char *rcs_fallback="$Id: fallback.c,v 1.24 1996/04/22 18:00:37 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
#include "mem.h"
#include "fallback.h"
#include "opcode.h"
#include "lua.h"
#include "table.h"
static void errorFB (void);
static void indexFB (void);
static void gettableFB (void);
static void arithFB (void);
static void concatFB (void);
static void orderFB (void);
static void GDFB (void);
static void funcFB (void);
/*
** Warning: This list must be in the same order as the #define's
*/
struct FB luaI_fallBacks[] = {
{"error", {LUA_T_CFUNCTION, {errorFB}}, 1, 0},
{"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1},
{"gettable", {LUA_T_CFUNCTION, {gettableFB}}, 2, 1},
{"arith", {LUA_T_CFUNCTION, {arithFB}}, 3, 1},
{"order", {LUA_T_CFUNCTION, {orderFB}}, 3, 1},
{"concat", {LUA_T_CFUNCTION, {concatFB}}, 2, 1},
{"settable", {LUA_T_CFUNCTION, {gettableFB}}, 3, 0},
{"gc", {LUA_T_CFUNCTION, {GDFB}}, 1, 0},
{"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1},
/* no fixed number of params or results */
{"getglobal", {LUA_T_CFUNCTION, {indexFB}}, 1, 1}
/* same default behavior of index FB */
};
#define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB))
void luaI_setfallback (void)
{
int i;
char *name = lua_getstring(lua_getparam(1));
lua_Object func = lua_getparam(2);
if (name == NULL || !lua_isfunction(func))
lua_error("incorrect argument to function `setfallback'");
for (i=0; i<N_FB; i++)
{
if (strcmp(luaI_fallBacks[i].kind, name) == 0)
{
luaI_pushobject(&luaI_fallBacks[i].function);
luaI_fallBacks[i].function = *luaI_Address(func);
return;
}
}
/* name not found */
lua_error("incorrect argument to function `setfallback'");
}
static void errorFB (void)
{
lua_Object o = lua_getparam(1);
if (lua_isstring(o))
fprintf (stderr, "lua: %s\n", lua_getstring(o));
else
fprintf(stderr, "lua: unknown error\n");
}
static void indexFB (void)
{
lua_pushnil();
}
static void gettableFB (void)
{
lua_error("indexed expression not a table");
}
static void arithFB (void)
{
lua_error("unexpected type at conversion to number");
}
static void concatFB (void)
{
lua_error("unexpected type at conversion to string");
}
static void orderFB (void)
{
lua_error("unexpected type at comparison");
}
static void GDFB (void) { }
static void funcFB (void)
{
lua_error("call expression not a function");
}
/*
** Reference routines
*/
static struct ref {
Object o;
enum {LOCK, HOLD, FREE, COLLECTED} status;
} *refArray = NULL;
static int refSize = 0;
int luaI_ref (Object *object, int lock)
{
int i;
int oldSize;
if (tag(object) == LUA_T_NIL)
return -1; /* special ref for nil */
for (i=0; i<refSize; i++)
if (refArray[i].status == FREE)
goto found;
/* no more empty spaces */
oldSize = refSize;
refSize = growvector(&refArray, refSize, struct ref, refEM, MAX_WORD);
for (i=oldSize; i<refSize; i++)
refArray[i].status = FREE;
i = oldSize;
found:
refArray[i].o = *object;
refArray[i].status = lock ? LOCK : HOLD;
return i;
}
void lua_unref (int ref)
{
if (ref >= 0 && ref < refSize)
refArray[ref].status = FREE;
}
Object *luaI_getref (int ref)
{
static Object nul = {LUA_T_NIL, {0}};
if (ref == -1)
return &nul;
if (ref >= 0 && ref < refSize &&
(refArray[ref].status == LOCK || refArray[ref].status == HOLD))
return &refArray[ref].o;
else
return NULL;
}
void luaI_travlock (int (*fn)(Object *))
{
int i;
for (i=0; i<refSize; i++)
if (refArray[i].status == LOCK)
fn(&refArray[i].o);
}
void luaI_invalidaterefs (void)
{
int i;
for (i=0; i<refSize; i++)
if (refArray[i].status == HOLD && !luaI_ismarked(&refArray[i].o))
refArray[i].status = COLLECTED;
}
char *luaI_travfallbacks (int (*fn)(Object *))
{
int i;
for (i=0; i<N_FB; i++)
if (fn(&luaI_fallBacks[i].function))
return luaI_fallBacks[i].kind;
return NULL;
}

37
fallback.h Normal file
View File

@@ -0,0 +1,37 @@
/*
** $Id: fallback.h,v 1.12 1996/04/22 18:00:37 roberto Exp roberto $
*/
#ifndef fallback_h
#define fallback_h
#include "lua.h"
#include "opcode.h"
extern struct FB {
char *kind;
Object function;
int nParams;
int nResults;
} luaI_fallBacks[];
#define FB_ERROR 0
#define FB_INDEX 1
#define FB_GETTABLE 2
#define FB_ARITH 3
#define FB_ORDER 4
#define FB_CONCAT 5
#define FB_SETTABLE 6
#define FB_GC 7
#define FB_FUNCTION 8
#define FB_GETGLOBAL 9
void luaI_setfallback (void);
int luaI_ref (Object *object, int lock);
Object *luaI_getref (int ref);
void luaI_travlock (int (*fn)(Object *));
void luaI_invalidaterefs (void);
char *luaI_travfallbacks (int (*fn)(Object *));
#endif

156
func.c Normal file
View File

@@ -0,0 +1,156 @@
#include <string.h>
#include "luadebug.h"
#include "table.h"
#include "mem.h"
#include "func.h"
#include "opcode.h"
static TFunc *function_root = NULL;
static LocVar *currvars = NULL;
static int numcurrvars = 0;
static int maxcurrvars = 0;
/*
** Initialize TFunc struct
*/
void luaI_initTFunc (TFunc *f)
{
f->next = NULL;
f->marked = 0;
f->size = 0;
f->code = NULL;
f->lineDefined = 0;
f->fileName = NULL;
f->locvars = NULL;
}
/*
** Insert function in list for GC
*/
void luaI_insertfunction (TFunc *f)
{
lua_pack();
f->next = function_root;
function_root = f;
f->marked = 0;
}
/*
** Free function
*/
void luaI_freefunc (TFunc *f)
{
luaI_free (f->code);
luaI_free (f->locvars);
luaI_free (f);
}
/*
** Garbage collection function.
** This function traverse the function list freeing unindexed functions
*/
Long luaI_funccollector (void)
{
TFunc *curr = function_root;
TFunc *prev = NULL;
Long counter = 0;
while (curr)
{
TFunc *next = curr->next;
if (!curr->marked)
{
if (prev == NULL)
function_root = next;
else
prev->next = next;
luaI_freefunc (curr);
++counter;
}
else
{
curr->marked = 0;
prev = curr;
}
curr = next;
}
return counter;
}
void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
{
Object *f = luaI_Address(func);
if (f->tag == LUA_T_MARK || f->tag == LUA_T_FUNCTION)
{
*filename = f->value.tf->fileName;
*linedefined = f->value.tf->lineDefined;
}
else if (f->tag == LUA_T_CMARK || f->tag == LUA_T_CFUNCTION)
{
*filename = "(C)";
*linedefined = -1;
}
}
/*
** Stores information to know that variable has been declared in given line
*/
void luaI_registerlocalvar (TaggedString *varname, int line)
{
if (numcurrvars >= maxcurrvars)
maxcurrvars = growvector(&currvars, maxcurrvars, LocVar, "", MAX_WORD);
currvars[numcurrvars].varname = varname;
currvars[numcurrvars].line = line;
numcurrvars++;
}
/*
** Stores information to know that variable has been out of scope in given line
*/
void luaI_unregisterlocalvar (int line)
{
luaI_registerlocalvar(NULL, line);
}
/*
** Copies "currvars" into a new area and store it in function header.
** The values (varname = NULL, line = -1) signal the end of vector.
*/
void luaI_closelocalvars (TFunc *func)
{
func->locvars = newvector (numcurrvars+1, LocVar);
memcpy (func->locvars, currvars, numcurrvars*sizeof(LocVar));
func->locvars[numcurrvars].varname = NULL;
func->locvars[numcurrvars].line = -1;
numcurrvars = 0; /* prepares for next function */
}
/*
** Look for n-esim local variable at line "line" in function "func".
** Returns NULL if not found.
*/
char *luaI_getlocalname (TFunc *func, int local_number, int line)
{
int count = 0;
char *varname = NULL;
LocVar *lv = func->locvars;
if (lv == NULL)
return NULL;
for (; lv->line != -1 && lv->line < line; lv++)
{
if (lv->varname) /* register */
{
if (++count == local_number)
varname = lv->varname->str;
}
else /* unregister */
if (--count < local_number)
varname = NULL;
}
return varname;
}

44
func.h Normal file
View File

@@ -0,0 +1,44 @@
/*
** $Id: func.h,v 1.7 1996/03/08 12:04:04 roberto Exp roberto $
*/
#ifndef func_h
#define func_h
#include "types.h"
#include "lua.h"
#include "tree.h"
typedef struct LocVar
{
TaggedString *varname; /* NULL signals end of scope */
int line;
} LocVar;
/*
** Function Headers
*/
typedef struct TFunc
{
struct TFunc *next;
int marked;
int size;
Byte *code;
int lineDefined;
char *fileName;
LocVar *locvars;
} TFunc;
Long luaI_funccollector (void);
void luaI_insertfunction (TFunc *f);
void luaI_initTFunc (TFunc *f);
void luaI_freefunc (TFunc *f);
void luaI_registerlocalvar (TaggedString *varname, int line);
void luaI_unregisterlocalvar (int line);
void luaI_closelocalvars (TFunc *func);
char *luaI_getlocalname (TFunc *func, int local_number, int line);
#endif

416
hash.c
View File

@@ -1,135 +1,136 @@
/*
** hash.c
** hash manager for lua
** Luiz Henrique de Figueiredo - 17 Aug 90
*/
char *rcs_hash="$Id: hash.c,v 2.1 1994/04/20 22:07:57 celes Exp celes $";
char *rcs_hash="$Id: hash.c,v 2.31 1996/07/12 20:00:26 roberto Exp roberto $";
#include <string.h>
#include <stdlib.h>
#include "mm.h"
#include "mem.h"
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "lua.h"
#define streq(s1,s2) (strcmp(s1,s2)==0)
#define strneq(s1,s2) (strcmp(s1,s2)!=0)
#define new(s) ((s *)malloc(sizeof(s)))
#define newvector(n,s) ((s *)calloc(n,sizeof(s)))
#define nhash(t) ((t)->nhash)
#define nodelist(t) ((t)->list)
#define list(t,i) ((t)->list[i])
#define nuse(t) ((t)->nuse)
#define markarray(t) ((t)->mark)
#define ref_tag(n) (tag(&(n)->ref))
#define ref_nvalue(n) (nvalue(&(n)->ref))
#define ref_svalue(n) (svalue(&(n)->ref))
#define nodevector(t) ((t)->node)
#define node(t,i) (&(t)->node[i])
#define ref(n) (&(n)->ref)
#define val(n) (&(n)->val)
typedef struct ArrayList
#define REHASH_LIMIT 0.70 /* avoid more than this % full */
static Hash *listhead = NULL;
/* hash dimensions values */
static Long dimensions[] =
{3L, 5L, 7L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L,
12853L, 25717L, 51437L, 102811L, 205619L, 411233L, 822433L,
1644817L, 3289613L, 6579211L, 13158023L, MAX_INT};
int luaI_redimension (int nhash)
{
Hash *array;
struct ArrayList *next;
} ArrayList;
static ArrayList *listhead = NULL;
static int head (Hash *t, Object *ref) /* hash function */
{
if (tag(ref) == T_NUMBER) return (((int)nvalue(ref))%nhash(t));
else if (tag(ref) == T_STRING)
int i;
for (i=0; dimensions[i]<MAX_INT; i++)
{
int h;
char *name = svalue(ref);
for (h=0; *name!=0; name++) /* interpret name as binary number */
{
h <<= 8;
h += (unsigned char) *name; /* avoid sign extension */
h %= nhash(t); /* make it a valid index */
if (dimensions[i] > nhash)
return dimensions[i];
}
lua_error("table overflow");
return 0; /* to avoid warnings */
}
static int hashindex (Hash *t, Object *ref) /* hash function */
{
long int h;
switch (tag(ref)) {
case LUA_T_NIL:
lua_error ("unexpected type to index table");
h = 0; /* UNREACHEABLE */
case LUA_T_NUMBER:
h = (long int)nvalue(ref); break;
case LUA_T_STRING:
h = tsvalue(ref)->hash; break;
case LUA_T_FUNCTION:
h = (IntPoint)ref->value.tf; break;
case LUA_T_CFUNCTION:
h = (IntPoint)fvalue(ref); break;
case LUA_T_ARRAY:
h = (IntPoint)avalue(ref); break;
default: /* user data */
h = (IntPoint)uvalue(ref); break;
}
return h;
}
else
{
lua_reportbug ("unexpected type to index table");
return -1;
}
if (h < 0) h = -h;
return h%nhash(t); /* make it a valid index */
}
static Node *present(Hash *t, Object *ref, int h)
int lua_equalObj (Object *t1, Object *t2)
{
Node *n=NULL, *p;
if (tag(ref) == T_NUMBER)
{
for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)
if (ref_tag(n) == T_NUMBER && nvalue(ref) == ref_nvalue(n)) break;
}
else if (tag(ref) == T_STRING)
{
for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)
if (ref_tag(n) == T_STRING && streq(svalue(ref),ref_svalue(n))) break;
}
if (n==NULL) /* name not present */
return NULL;
#if 0
if (p!=NULL) /* name present but not first */
{
p->next=n->next; /* move-to-front self-organization */
n->next=list(t,h);
list(t,h)=n;
}
#endif
return n;
if (tag(t1) != tag(t2)) return 0;
switch (tag(t1))
{
case LUA_T_NIL: return 1;
case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
case LUA_T_STRING: return svalue(t1) == svalue(t2);
case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf;
case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2);
default: return uvalue(t1) == uvalue(t2);
}
}
static void freelist (Node *n)
{
while (n)
static int present (Hash *t, Object *ref)
{
int h = hashindex(t, ref);
while (tag(ref(node(t, h))) != LUA_T_NIL)
{
Node *next = n->next;
free (n);
n = next;
if (lua_equalObj(ref, ref(node(t, h))))
return h;
h = (h+1) % nhash(t);
}
return h;
}
/*
** Alloc a vector node
*/
static Node *hashnodecreate (int nhash)
{
int i;
Node *v = newvector (nhash, Node);
for (i=0; i<nhash; i++)
tag(ref(&v[i])) = LUA_T_NIL;
return v;
}
/*
** Create a new hash. Return the hash pointer or NULL on error.
*/
static Hash *hashcreate (unsigned int nhash)
static Hash *hashcreate (int nhash)
{
Hash *t = new (Hash);
if (t == NULL)
{
lua_error ("not enough memory");
return NULL;
}
Hash *t = new(Hash);
nhash = luaI_redimension((int)((float)nhash/REHASH_LIMIT));
nodevector(t) = hashnodecreate(nhash);
nhash(t) = nhash;
nuse(t) = 0;
markarray(t) = 0;
nodelist(t) = newvector (nhash, Node*);
if (nodelist(t) == NULL)
{
lua_error ("not enough memory");
return NULL;
}
return t;
}
/*
** Delete a hash
*/
static void hashdelete (Hash *h)
static void hashdelete (Hash *t)
{
int i;
for (i=0; i<nhash(h); i++)
freelist (list(h,i));
free (nodelist(h));
free(h);
luaI_free (nodevector(t));
luaI_free(t);
}
@@ -144,8 +145,8 @@ void lua_hashmark (Hash *h)
markarray(h) = 1;
for (i=0; i<nhash(h); i++)
{
Node *n;
for (n = list(h,i); n != NULL; n = n->next)
Node *n = node(h,i);
if (tag(ref(n)) != LUA_T_NIL)
{
lua_markobject(&n->ref);
lua_markobject(&n->val);
@@ -153,92 +154,125 @@ void lua_hashmark (Hash *h)
}
}
}
static void call_fallbacks (void)
{
Hash *curr_array;
Object t;
tag(&t) = LUA_T_ARRAY;
for (curr_array = listhead; curr_array; curr_array = curr_array->next)
if (markarray(curr_array) != 1)
{
avalue(&t) = curr_array;
luaI_gcFB(&t);
}
tag(&t) = LUA_T_NIL;
luaI_gcFB(&t); /* end of list */
}
/*
** Garbage collection to arrays
** Delete all unmarked arrays.
*/
void lua_hashcollector (void)
Long lua_hashcollector (void)
{
ArrayList *curr = listhead, *prev = NULL;
while (curr != NULL)
Hash *curr_array = listhead, *prev = NULL;
Long counter = 0;
call_fallbacks();
while (curr_array != NULL)
{
ArrayList *next = curr->next;
if (markarray(curr->array) != 1)
Hash *next = curr_array->next;
if (markarray(curr_array) != 1)
{
if (prev == NULL) listhead = next;
else prev->next = next;
hashdelete(curr->array);
free(curr);
hashdelete(curr_array);
++counter;
}
else
{
markarray(curr->array) = 0;
prev = curr;
markarray(curr_array) = 0;
prev = curr_array;
}
curr = next;
curr_array = next;
}
return counter;
}
/*
** Create a new array
** This function insert the new array at array list. It also
** execute garbage collection if the number of array created
** This function inserts the new array in the array list. It also
** executes garbage collection if the number of arrays created
** exceed a pre-defined range.
*/
Hash *lua_createarray (int nhash)
{
ArrayList *new = new(ArrayList);
if (new == NULL)
{
lua_error ("not enough memory");
return NULL;
}
new->array = hashcreate(nhash);
if (new->array == NULL)
{
lua_error ("not enough memory");
return NULL;
}
Hash *array;
lua_pack();
array = hashcreate(nhash);
array->next = listhead;
listhead = array;
return array;
}
if (lua_nentity == lua_block)
lua_pack();
lua_nentity++;
new->next = listhead;
listhead = new;
return new->array;
/*
** Re-hash
*/
static void rehash (Hash *t)
{
int i;
int nold = nhash(t);
Node *vold = nodevector(t);
nhash(t) = luaI_redimension(nhash(t));
nodevector(t) = hashnodecreate(nhash(t));
for (i=0; i<nold; i++)
{
Node *n = vold+i;
if (tag(ref(n)) != LUA_T_NIL && tag(val(n)) != LUA_T_NIL)
*node(t, present(t, ref(n))) = *n; /* copy old node to new hahs */
}
luaI_free(vold);
}
/*
** If the hash node is present, return its pointer, otherwise return
** null.
*/
Object *lua_hashget (Hash *t, Object *ref)
{
int h = present(t, ref);
if (tag(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h));
else return NULL;
}
/*
** If the hash node is present, return its pointer, otherwise create a new
** node for the given reference and also return its pointer.
** On error, return NULL.
*/
Object *lua_hashdefine (Hash *t, Object *ref)
{
int h;
Node *n;
h = head (t, ref);
if (h < 0) return NULL;
n = present(t, ref, h);
if (n == NULL)
h = present(t, ref);
n = node(t, h);
if (tag(ref(n)) == LUA_T_NIL)
{
n = new(Node);
if (n == NULL)
nuse(t)++;
if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT)
{
lua_error ("not enough memory");
return NULL;
rehash(t);
h = present(t, ref);
n = node(t, h);
}
n->ref = *ref;
tag(&n->val) = T_NIL;
n->next = list(t,h); /* link node to head of list */
list(t,h) = n;
*ref(n) = *ref;
tag(val(n)) = LUA_T_NIL;
}
return (&n->val);
return (val(n));
}
@@ -248,98 +282,38 @@ Object *lua_hashdefine (Hash *t, Object *ref)
** in the hash.
** This function pushs the element value and its reference to the stack.
*/
static void firstnode (Hash *a, int h)
static void hashnext (Hash *t, int i)
{
if (h < nhash(a))
{
int i;
for (i=h; i<nhash(a); i++)
{
if (list(a,i) != NULL)
{
if (tag(&list(a,i)->val) != T_NIL)
{
lua_pushobject (&list(a,i)->ref);
lua_pushobject (&list(a,i)->val);
return;
}
else
{
Node *next = list(a,i)->next;
while (next != NULL && tag(&next->val) == T_NIL) next = next->next;
if (next != NULL)
{
lua_pushobject (&next->ref);
lua_pushobject (&next->val);
return;
}
}
}
}
if (i >= nhash(t))
return;
while (tag(ref(node(t,i))) == LUA_T_NIL || tag(val(node(t,i))) == LUA_T_NIL)
{
if (++i >= nhash(t))
return;
}
lua_pushnil();
lua_pushnil();
luaI_pushobject(ref(node(t,i)));
luaI_pushobject(val(node(t,i)));
}
void lua_next (void)
{
Hash *a;
Object *o = lua_getparam (1);
Object *r = lua_getparam (2);
if (o == NULL || r == NULL)
{ lua_error ("too few arguments to function `next'"); return; }
if (lua_getparam (3) != NULL)
{ lua_error ("too many arguments to function `next'"); return; }
if (tag(o) != T_ARRAY)
{ lua_error ("first argument of function `next' is not a table"); return; }
a = avalue(o);
if (tag(r) == T_NIL)
Hash *t;
lua_Object o = lua_getparam(1);
lua_Object r = lua_getparam(2);
if (o == LUA_NOOBJECT || r == LUA_NOOBJECT)
lua_error ("too few arguments to function `next'");
if (lua_getparam(3) != LUA_NOOBJECT)
lua_error ("too many arguments to function `next'");
if (!lua_istable(o))
lua_error ("first argument of function `next' is not a table");
t = avalue(luaI_Address(o));
if (lua_isnil(r))
{
firstnode (a, 0);
return;
hashnext(t, 0);
}
else
{
int h = head (a, r);
if (h >= 0)
{
Node *n = list(a,h);
while (n)
{
if (memcmp(&n->ref,r,sizeof(Object)) == 0)
{
if (n->next == NULL)
{
firstnode (a, h+1);
return;
}
else if (tag(&n->next->val) != T_NIL)
{
lua_pushobject (&n->next->ref);
lua_pushobject (&n->next->val);
return;
}
else
{
Node *next = n->next->next;
while (next != NULL && tag(&next->val) == T_NIL) next = next->next;
if (next == NULL)
{
firstnode (a, h+1);
return;
}
else
{
lua_pushobject (&next->ref);
lua_pushobject (&next->val);
}
return;
}
}
n = n->next;
}
if (n == NULL)
lua_error ("error in function 'next': reference not found");
}
int h = present (t, luaI_Address(r));
hashnext(t, h+1);
}
}

18
hash.h
View File

@@ -1,31 +1,37 @@
/*
** hash.h
** hash manager for lua
** Luiz Henrique de Figueiredo - 17 Aug 90
** $Id: hash.h,v 1.1 1993/12/17 18:41:19 celes Exp celes $
** $Id: hash.h,v 2.11 1996/03/08 12:04:04 roberto Exp roberto $
*/
#ifndef hash_h
#define hash_h
#include "types.h"
#include "opcode.h"
typedef struct node
{
Object ref;
Object val;
struct node *next;
} Node;
typedef struct Hash
{
struct Hash *next;
Node *node;
int nhash;
int nuse;
char mark;
unsigned int nhash;
Node **list;
} Hash;
int lua_equalObj (Object *t1, Object *t2);
int luaI_redimension (int nhash);
Hash *lua_createarray (int nhash);
void lua_hashmark (Hash *h);
void lua_hashcollector (void);
Long lua_hashcollector (void);
Object *lua_hashget (Hash *t, Object *ref);
Object *lua_hashdefine (Hash *t, Object *ref);
void lua_next (void);

334
inout.c
View File

@@ -2,50 +2,38 @@
** inout.c
** Provide function to realise the input/output function and debugger
** facilities.
** Also provides some predefined lua functions.
*/
char *rcs_inout="$Id: inout.c,v 1.2 1993/12/22 21:15:16 roberto Exp celes $";
char *rcs_inout="$Id: inout.c,v 2.42 1996/09/24 21:46:44 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
#include "lex.h"
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "tree.h"
#include "lua.h"
#include "mem.h"
/* Exported variables */
int lua_linenumber;
int lua_debug;
int lua_debugline;
Word lua_linenumber;
char *lua_parsedfile;
/* Internal variables */
#ifndef MAXFUNCSTACK
#define MAXFUNCSTACK 32
#endif
static struct { int file; int function; } funcstack[MAXFUNCSTACK];
static int nfuncstack=0;
static FILE *fp;
static char *st;
static void (*usererror) (char *s);
/*
** Function to set user function to handle errors.
*/
void lua_errorfunction (void (*fn) (char *s))
{
usererror = fn;
}
/*
** Function to get the next character from the input file
*/
static int fileinput (void)
{
int c = fgetc (fp);
return (c == EOF ? 0 : c);
int c = fgetc(fp);
return (c == EOF) ? 0 : c;
}
/*
@@ -53,22 +41,27 @@ static int fileinput (void)
*/
static int stringinput (void)
{
st++;
return (*(st-1));
return *st++;
}
/*
** Function to open a file to be input unit.
** Return 0 on success or 1 on error.
** Return the file.
*/
int lua_openfile (char *fn)
FILE *lua_openfile (char *fn)
{
lua_linenumber = 1;
lua_setinput (fileinput);
fp = fopen (fn, "r");
if (fp == NULL) return 1;
if (lua_addfile (fn)) return 1;
return 0;
if (fn == NULL)
{
fp = stdin;
fn = "(stdin)";
}
else
fp = fopen (fn, "r");
if (fp == NULL)
return NULL;
lua_parsedfile = luaI_createfixedstring(fn)->str;
return fp;
}
/*
@@ -76,9 +69,8 @@ int lua_openfile (char *fn)
*/
void lua_closefile (void)
{
if (fp != NULL)
if (fp != NULL && fp != stdin)
{
lua_delfile();
fclose (fp);
fp = NULL;
}
@@ -87,17 +79,16 @@ void lua_closefile (void)
/*
** Function to open a string to be input unit
*/
int lua_openstring (char *s)
#define SIZE_PREF 20 /* size of string prefix to appear in error messages */
void lua_openstring (char *s)
{
lua_linenumber = 1;
lua_setinput (stringinput);
st = s;
{
char sn[64];
sprintf (sn, "String: %10.10s...", s);
if (lua_addfile (sn)) return 1;
}
return 0;
char buff[SIZE_PREF+25];
lua_setinput(stringinput);
st = s;
strcpy(buff, "(dostring) >> ");
strncat(buff, s, SIZE_PREF);
if (strlen(s) > SIZE_PREF) strcat(buff, "...");
lua_parsedfile = luaI_createfixedstring(buff)->str;
}
/*
@@ -105,74 +96,205 @@ int lua_openstring (char *s)
*/
void lua_closestring (void)
{
lua_delfile();
}
/*
** Call user function to handle error messages, if registred. Or report error
** using standard function (fprintf).
*/
void lua_error (char *s)
{
if (usererror != NULL) usererror (s);
else fprintf (stderr, "lua: %s\n", s);
}
/*
** Called to execute SETFUNCTION opcode, this function pushs a function into
** function stack. Return 0 on success or 1 on error.
*/
int lua_pushfunction (int file, int function)
static void check_arg (int cond, char *func)
{
if (nfuncstack >= MAXFUNCSTACK-1)
{
lua_error ("function stack overflow");
return 1;
}
funcstack[nfuncstack].file = file;
funcstack[nfuncstack].function = function;
nfuncstack++;
return 0;
}
/*
** Called to execute RESET opcode, this function pops a function from
** function stack.
*/
void lua_popfunction (void)
{
nfuncstack--;
}
/*
** Report bug building a message and sending it to lua_error function.
*/
void lua_reportbug (char *s)
{
char msg[1024];
strcpy (msg, s);
if (lua_debugline != 0)
{
int i;
if (nfuncstack > 0)
if (!cond)
{
sprintf (strchr(msg,0),
"\n\tin statement begining at line %d in function \"%s\" of file \"%s\"",
lua_debugline, lua_varname(funcstack[nfuncstack-1].function),
lua_file[funcstack[nfuncstack-1].file]);
sprintf (strchr(msg,0), "\n\tactive stack\n");
for (i=nfuncstack-1; i>=0; i--)
sprintf (strchr(msg,0), "\t-> function \"%s\" of file \"%s\"\n",
lua_varname(funcstack[i].function),
lua_file[funcstack[i].file]);
char buff[100];
sprintf(buff, "incorrect argument to function `%s'", func);
lua_error(buff);
}
}
static int passresults (void)
{
int arg = 0;
lua_Object obj;
while ((obj = lua_getresult(++arg)) != LUA_NOOBJECT)
lua_pushobject(obj);
return arg-1;
}
/*
** Internal function: do a string
*/
void lua_internaldostring (void)
{
lua_Object obj = lua_getparam (1);
if (lua_isstring(obj) && lua_dostring(lua_getstring(obj)) == 0)
if (passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
/*
** Internal function: do a file
*/
void lua_internaldofile (void)
{
lua_Object obj = lua_getparam (1);
char *fname = NULL;
if (lua_isstring(obj))
fname = lua_getstring(obj);
else if (obj != LUA_NOOBJECT)
lua_error("invalid argument to function `dofile'");
/* else fname = NULL */
if (lua_dofile(fname) == 0)
if (passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
static char *tostring (lua_Object obj)
{
char *buff = luaI_buffer(20);
if (lua_isstring(obj)) /* get strings and numbers */
return lua_getstring(obj);
else switch(lua_type(obj))
{
case LUA_T_FUNCTION:
sprintf(buff, "function: %p", (luaI_Address(obj))->value.tf);
break;
case LUA_T_CFUNCTION:
sprintf(buff, "cfunction: %p", lua_getcfunction(obj));
break;
case LUA_T_ARRAY:
sprintf(buff, "table: %p", avalue(luaI_Address(obj)));
break;
case LUA_T_NIL:
sprintf(buff, "nil");
break;
default:
sprintf(buff, "userdata: %p", lua_getuserdata(obj));
break;
}
return buff;
}
void luaI_tostring (void)
{
lua_pushstring(tostring(lua_getparam(1)));
}
void luaI_print (void)
{
int i = 1;
lua_Object obj;
while ((obj = lua_getparam(i++)) != LUA_NOOBJECT)
printf("%s\n", tostring(obj));
}
/*
** Internal function: return an object type.
*/
void luaI_type (void)
{
lua_Object o = lua_getparam(1);
int t;
if (o == LUA_NOOBJECT)
lua_error("no parameter to function 'type'");
t = lua_type(o);
switch (t)
{
case LUA_T_NIL :
lua_pushliteral("nil");
break;
case LUA_T_NUMBER :
lua_pushliteral("number");
break;
case LUA_T_STRING :
lua_pushliteral("string");
break;
case LUA_T_ARRAY :
lua_pushliteral("table");
break;
case LUA_T_FUNCTION :
case LUA_T_CFUNCTION :
lua_pushliteral("function");
break;
default :
lua_pushliteral("userdata");
break;
}
lua_pushnumber(t);
}
/*
** Internal function: convert an object to a number
*/
void lua_obj2number (void)
{
lua_Object o = lua_getparam(1);
if (lua_isnumber(o))
lua_pushnumber(lua_getnumber(o));
}
void luaI_error (void)
{
char *s = lua_getstring(lua_getparam(1));
if (s == NULL) s = "(no message)";
lua_error(s);
}
void luaI_assert (void)
{
lua_Object p = lua_getparam(1);
if (p == LUA_NOOBJECT || lua_isnil(p))
lua_error("assertion failed!");
}
void luaI_setglobal (void)
{
lua_Object name = lua_getparam(1);
lua_Object value = lua_getparam(2);
check_arg(lua_isstring(name), "setglobal");
lua_pushobject(value);
lua_storeglobal(lua_getstring(name));
lua_pushobject(value); /* return given value */
}
void luaI_getglobal (void)
{
lua_Object name = lua_getparam(1);
check_arg(lua_isstring(name), "getglobal");
lua_pushobject(lua_getglobal(lua_getstring(name)));
}
#define MAXPARAMS 256
void luaI_call (void)
{
lua_Object f = lua_getparam(1);
lua_Object arg = lua_getparam(2);
lua_Object temp, params[MAXPARAMS];
int narg, i;
check_arg(lua_istable(arg), "call");
check_arg(lua_isfunction(f), "call");
/* narg = arg.n */
lua_pushobject(arg);
lua_pushstring("n");
temp = lua_getsubscript();
narg = lua_isnumber(temp) ? lua_getnumber(temp) : MAXPARAMS+1;
/* read arg[1...n] */
for (i=0; i<narg; i++) {
if (i>=MAXPARAMS)
lua_error("argument list too long in function `call'");
lua_pushobject(arg);
lua_pushnumber(i+1);
params[i] = lua_getsubscript();
if (narg == MAXPARAMS+1 && lua_isnil(params[i])) {
narg = i;
break;
}
}
/* push parameters and do the call */
for (i=0; i<narg; i++)
lua_pushobject(params[i]);
if (lua_callfunction(f))
lua_error(NULL);
else
{
sprintf (strchr(msg,0),
"\n\tin statement begining at line %d of file \"%s\"",
lua_debugline, lua_filename());
}
}
lua_error (msg);
passresults();
}

31
inout.h
View File

@@ -1,21 +1,34 @@
/*
** $Id: $
** $Id: inout.h,v 1.15 1996/03/15 18:21:58 roberto Exp roberto $
*/
#ifndef inout_h
#define inout_h
extern int lua_linenumber;
extern int lua_debug;
extern int lua_debugline;
#include "types.h"
#include <stdio.h>
int lua_openfile (char *fn);
extern Word lua_linenumber;
extern Word lua_debugline;
extern char *lua_parsedfile;
FILE *lua_openfile (char *fn);
void lua_closefile (void);
int lua_openstring (char *s);
void lua_openstring (char *s);
void lua_closestring (void);
int lua_pushfunction (int file, int function);
void lua_popfunction (void);
void lua_reportbug (char *s);
void lua_internaldofile (void);
void lua_internaldostring (void);
void luaI_tostring (void);
void luaI_print (void);
void luaI_type (void);
void lua_obj2number (void);
void luaI_error (void);
void luaI_assert (void);
void luaI_setglobal (void);
void luaI_getglobal (void);
void luaI_call (void);
#endif

680
iolib.c
View File

@@ -1,479 +1,295 @@
/*
** iolib.c
** Input/output library to LUA
*/
char *rcs_iolib="$Id: iolib.c,v 1.3 1994/03/28 15:14:02 celes Exp celes $";
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/stat.h>
#ifdef __GNUC__
#include <floatingpoint.h>
#endif
#include "mm.h"
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include "lua.h"
#include "luadebug.h"
#include "lualib.h"
FILE *lua_infile, *lua_outfile;
#ifdef POPEN
FILE *popen();
int pclose();
#else
#define popen(x,y) NULL /* that is, popen always fails */
#define pclose(x) (-1)
#endif
static void pushresult (int i)
{
if (i)
lua_pushuserdata(NULL);
else {
lua_pushnil();
#ifndef NOSTRERROR
lua_pushstring(strerror(errno));
#else
lua_pushstring("system unable to define the error");
#endif
}
}
static void closefile (FILE *f)
{
if (f == stdin || f == stdout)
return;
if (f == lua_infile)
lua_infile = stdin;
if (f == lua_outfile)
lua_outfile = stdout;
if (pclose(f) == -1)
fclose(f);
}
static FILE *in=stdin, *out=stdout;
/*
** Open a file to read.
** LUA interface:
** status = readfrom (filename)
** where:
** status = 1 -> success
** status = 0 -> error
*/
static void io_readfrom (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart input */
{
if (in != stdin)
{
fclose (in);
in = stdin;
lua_Object f = lua_getparam(1);
if (f == LUA_NOOBJECT)
closefile(lua_infile); /* restore standart input */
else if (lua_isuserdata(f))
lua_infile = lua_getuserdata(f);
else {
char *s = lua_check_string(1, "readfrom");
FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
if (fp)
lua_infile = fp;
else {
pushresult(0);
return;
}
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'readfrom`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"r");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (in != stdin) fclose (in);
in = fp;
lua_pushnumber (1);
}
}
}
lua_pushuserdata(lua_infile);
}
/*
** Open a file to write.
** LUA interface:
** status = writeto (filename)
** where:
** status = 1 -> success
** status = 0 -> error
*/
static void io_writeto (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart output */
{
if (out != stdout)
{
fclose (out);
out = stdout;
lua_Object f = lua_getparam(1);
if (f == LUA_NOOBJECT)
closefile(lua_outfile); /* restore standart output */
else if (lua_isuserdata(f))
lua_outfile = lua_getuserdata(f);
else {
char *s = lua_check_string(1, "writeto");
FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
if (fp)
lua_outfile = fp;
else {
pushresult(0);
return;
}
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'writeto`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"w");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (out != stdout) fclose (out);
out = fp;
lua_pushnumber (1);
}
}
}
lua_pushuserdata(lua_outfile);
}
/*
** Open a file to write appended.
** LUA interface:
** status = appendto (filename)
** where:
** status = 2 -> success (already exist)
** status = 1 -> success (new file)
** status = 0 -> error
*/
static void io_appendto (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart output */
{
if (out != stdout)
{
fclose (out);
out = stdout;
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'appendto`");
lua_pushnumber (0);
char *s = lua_check_string(1, "appendto");
FILE *fp = fopen (s, "a");
if (fp != NULL) {
lua_outfile = fp;
lua_pushuserdata(lua_outfile);
}
else
{
int r;
FILE *fp;
struct stat st;
if (stat(lua_getstring(o), &st) == -1) r = 1;
else r = 2;
fp = fopen (lua_getstring(o),"a");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (out != stdout) fclose (out);
out = fp;
lua_pushnumber (r);
}
}
}
pushresult(0);
}
#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
/*
** Read a variable. On error put nil on stack.
** LUA interface:
** variable = read ([format])
**
** O formato pode ter um dos seguintes especificadores:
**
** s ou S -> para string
** f ou F, g ou G, e ou E -> para reais
** i ou I -> para inteiros
**
** Estes especificadores podem vir seguidos de numero que representa
** o numero de campos a serem lidos.
*/
static void io_read (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring(o)) /* free format */
{
int c;
char s[256];
while (isspace(c=fgetc(in)))
;
if (c == '\"')
{
int c, n=0;
while((c = fgetc(in)) != '\"')
{
if (c == EOF)
{
lua_pushnil ();
return;
char *buff;
char *p = lua_opt_string(1, "[^\n]*{\n}", "read");
int inskip = 0; /* to control {skips} */
int c = NEED_OTHER;
luaI_addchar(0);
while (*p) {
if (*p == '{' || *p == '}') {
inskip = (*p == '{');
p++;
}
s[n++] = c;
}
s[n] = 0;
}
else if (c == '\'')
{
int c, n=0;
while((c = fgetc(in)) != '\'')
{
if (c == EOF)
{
lua_pushnil ();
return;
else {
char *ep = item_end(p); /* get what is next */
int m; /* match result */
if (c == NEED_OTHER) c = getc(lua_infile);
m = (c == EOF) ? 0 : singlematch((char)c, p);
if (m) {
if (!inskip) luaI_addchar(c);
c = NEED_OTHER;
}
switch (*ep) {
case '*': /* repetition */
if (!m) p = ep+1; /* else stay in (repeat) the same item */
break;
case '?': /* optional */
p = ep+1; /* continues reading the pattern */
break;
default:
if (m) p = ep; /* continues reading the pattern */
else
goto break_while; /* pattern fails */
}
}
s[n++] = c;
}
s[n] = 0;
}
else
{
char *ptr;
double d;
ungetc (c, in);
if (fscanf (in, "%s", s) != 1)
{
lua_pushnil ();
return;
}
d = strtod (s, &ptr);
if (!(*ptr))
{
lua_pushnumber (d);
return;
}
}
lua_pushstring (s);
return;
}
else /* formatted */
{
char *e = lua_getstring(o);
char t;
int m=0;
while (isspace(*e)) e++;
t = *e++;
while (isdigit(*e))
m = m*10 + (*e++ - '0');
if (m > 0)
{
char f[80];
char s[256];
sprintf (f, "%%%ds", m);
if (fgets (s, m, in) == NULL)
{
lua_pushnil();
return;
}
else
{
if (s[strlen(s)-1] == '\n')
s[strlen(s)-1] = 0;
}
switch (tolower(t))
{
case 'i':
{
long int l;
sscanf (s, "%ld", &l);
lua_pushnumber(l);
}
break;
case 'f': case 'g': case 'e':
{
float f;
sscanf (s, "%f", &f);
lua_pushnumber(f);
}
break;
default:
lua_pushstring(s);
break;
}
}
else
{
switch (tolower(t))
{
case 'i':
{
long int l;
if (fscanf (in, "%ld", &l) == EOF)
lua_pushnil();
else lua_pushnumber(l);
}
break;
case 'f': case 'g': case 'e':
{
float f;
if (fscanf (in, "%f", &f) == EOF)
lua_pushnil();
else lua_pushnumber(f);
}
break;
default:
{
char s[256];
if (fscanf (in, "%s", s) == EOF)
lua_pushnil();
else lua_pushstring(s);
}
break;
}
}
}
} break_while:
if (c >= 0) /* not EOF nor NEED_OTHER? */
ungetc(c, lua_infile);
buff = luaI_addchar(0);
if (*buff != 0 || *p == 0) /* read something or did not fail? */
lua_pushstring(buff);
}
/*
** Write a variable. On error put 0 on stack, otherwise put 1.
** LUA interface:
** status = write (variable [,format])
**
** O formato pode ter um dos seguintes especificadores:
**
** s ou S -> para string
** f ou F, g ou G, e ou E -> para reais
** i ou I -> para inteiros
**
** Estes especificadores podem vir seguidos de:
**
** [?][m][.n]
**
** onde:
** ? -> indica justificacao
** < = esquerda
** | = centro
** > = direita (default)
** m -> numero maximo de campos (se exceder estoura)
** n -> indica precisao para
** reais -> numero de casas decimais
** inteiros -> numero minimo de digitos
** string -> nao se aplica
*/
static char *buildformat (char *e, lua_Object o)
{
static char buffer[512];
static char f[80];
char *string = &buffer[255];
char t, j='r';
int m=0, n=0, l;
while (isspace(*e)) e++;
t = *e++;
if (*e == '<' || *e == '|' || *e == '>') j = *e++;
while (isdigit(*e))
m = m*10 + (*e++ - '0');
e++; /* skip point */
while (isdigit(*e))
n = n*10 + (*e++ - '0');
sprintf(f,"%%");
if (j == '<' || j == '|') sprintf(strchr(f,0),"-");
if (m != 0) sprintf(strchr(f,0),"%d", m);
if (n != 0) sprintf(strchr(f,0),".%d", n);
sprintf(strchr(f,0), "%c", t);
switch (tolower(t))
{
case 'i': t = 'i';
sprintf (string, f, (long int)lua_getnumber(o));
break;
case 'f': case 'g': case 'e': t = 'f';
sprintf (string, f, (float)lua_getnumber(o));
break;
case 's': t = 's';
sprintf (string, f, lua_getstring(o));
break;
default: return "";
}
l = strlen(string);
if (m!=0 && l>m)
{
int i;
for (i=0; i<m; i++)
string[i] = '*';
string[i] = 0;
}
else if (m!=0 && j=='|')
{
int i=l-1;
while (isspace(string[i])) i--;
string -= (m-i) / 2;
i=0;
while (string[i]==0) string[i++] = ' ';
string[l] = 0;
}
return string;
}
static void io_write (void)
{
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (o1 == NULL) /* new line */
{
fprintf (out, "\n");
lua_pushnumber(1);
}
else if (o2 == NULL) /* free format */
{
int status=0;
if (lua_isnumber(o1))
status = fprintf (out, "%g", lua_getnumber(o1));
else if (lua_isstring(o1))
status = fprintf (out, "%s", lua_getstring(o1));
lua_pushnumber(status);
}
else /* formated */
{
if (!lua_isstring(o2))
{
lua_error ("incorrect format to function `write'");
lua_pushnumber(0);
return;
}
lua_pushnumber(fprintf (out, "%s", buildformat(lua_getstring(o2),o1)));
}
int arg = 1;
int status = 1;
char *s;
while ((s = lua_opt_string(arg++, NULL, "write")) != NULL)
status = status && (fputs(s, lua_outfile) != EOF);
pushresult(status);
}
/*
** Execute a executable program using "system".
** Return the result of execution.
*/
void io_execute (void)
static void io_execute (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
int res = system(lua_getstring(o));
lua_pushnumber (res);
}
return;
lua_pushnumber(system(lua_check_string(1, "execute")));
}
/*
** Remove a file.
** On error put 0 on stack, otherwise put 1.
*/
void io_remove (void)
static void io_remove (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
if (remove(lua_getstring(o)) == 0)
lua_pushnumber (1);
pushresult(remove(lua_check_string(1, "remove")) == 0);
}
static void io_rename (void)
{
pushresult(rename(lua_check_string(1, "rename"),
lua_check_string(2, "rename")) == 0);
}
static void io_tmpname (void)
{
lua_pushstring(tmpnam(NULL));
}
static void io_getenv (void)
{
lua_pushstring(getenv(lua_check_string(1, "getenv"))); /* if NULL push nil */
}
static void io_date (void)
{
time_t t;
struct tm *tm;
char *s = lua_opt_string(1, "%c", "date");
char b[BUFSIZ];
time(&t); tm = localtime(&t);
if (strftime(b,sizeof(b),s,tm))
lua_pushstring(b);
else
lua_pushnumber (0);
}
return;
lua_error("invalid `date' format");
}
static void io_exit (void)
{
lua_Object o = lua_getparam(1);
exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
}
/*
** Open io library
*/
static void io_debug (void)
{
while (1) {
char buffer[250];
fprintf(stderr, "lua_debug> ");
if (fgets(buffer, sizeof(buffer), stdin) == 0) return;
if (strcmp(buffer, "cont\n") == 0) return;
lua_dostring(buffer);
}
}
static void lua_printstack (FILE *f)
{
int level = 0;
lua_Object func;
fprintf(f, "Active Stack:\n");
while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
char *name;
int currentline;
fprintf(f, "\t");
switch (*lua_getobjname(func, &name)) {
case 'g':
fprintf(f, "function %s", name);
break;
case 'f':
fprintf(f, "`%s' fallback", name);
break;
default: {
char *filename;
int linedefined;
lua_funcinfo(func, &filename, &linedefined);
if (linedefined == 0)
fprintf(f, "main of %s", filename);
else if (linedefined < 0)
fprintf(f, "%s", filename);
else
fprintf(f, "function (%s:%d)", filename, linedefined);
}
}
if ((currentline = lua_currentline(func)) > 0)
fprintf(f, " at line %d", currentline);
fprintf(f, "\n");
}
}
static void errorfb (void)
{
char *s = lua_opt_string(1, "(no messsage)", NULL);
fprintf(stderr, "lua: %s\n", s);
lua_printstack(stderr);
}
static struct lua_reg iolib[] = {
{"readfrom", io_readfrom},
{"writeto", io_writeto},
{"appendto", io_appendto},
{"read", io_read},
{"write", io_write},
{"execute", io_execute},
{"remove", io_remove},
{"rename", io_rename},
{"tmpname", io_tmpname},
{"getenv", io_getenv},
{"date", io_date},
{"exit", io_exit},
{"debug", io_debug},
{"print_stack", errorfb}
};
void iolib_open (void)
{
lua_register ("readfrom", io_readfrom);
lua_register ("writeto", io_writeto);
lua_register ("appendto", io_appendto);
lua_register ("read", io_read);
lua_register ("write", io_write);
lua_register ("execute", io_execute);
lua_register ("remove", io_remove);
lua_infile=stdin; lua_outfile=stdout;
luaI_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
lua_setfallback("error", errorfb);
}

312
lex.c
View File

@@ -1,50 +1,48 @@
char *rcs_lex = "$Id: lex.c,v 1.3 1993/12/28 16:42:29 roberto Exp celes $";
/*$Log: lex.c,v $
* Revision 1.3 1993/12/28 16:42:29 roberto
* "include"s de string.h e stdlib.h para evitar warnings
*
* Revision 1.2 1993/12/22 21:39:15 celes
* Tratamento do token $debug e $nodebug
*
* Revision 1.1 1993/12/22 21:15:16 roberto
* Initial revision
**/
char *rcs_lex = "$Id: lex.c,v 2.38 1996/11/08 12:49:35 roberto Exp roberto $";
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "mem.h"
#include "tree.h"
#include "table.h"
#include "y.tab.h"
#include "lex.h"
#include "inout.h"
#include "luadebug.h"
#include "parser.h"
#define next() { current = input(); }
#define save(x) { *yytextLast++ = (x); }
#define save_and_next() { save(current); next(); }
#define MINBUFF 260
static int current;
static char yytext[256];
static char *yytextLast;
#define next() (current = input())
#define save(x) (yytext[tokensize++] = (x))
#define save_and_next() (save(current), next())
static int current; /* look ahead character */
static Input input; /* input function */
static Input input;
void lua_setinput (Input fn)
{
current = ' ';
current = '\n';
lua_linenumber = 0;
input = fn;
}
char *lua_lasttext (void)
void luaI_syntaxerror (char *s)
{
*yytextLast = 0;
return yytext;
char msg[256];
char *token = luaI_buffer(1);
if (token[0] == 0)
token = "<eof>";
sprintf (msg,"%s;\n> last token read: \"%s\" at line %d in file %s",
s, token, lua_linenumber, lua_parsedfile);
lua_error (msg);
}
static struct
static struct
{
char *name;
int token;
@@ -66,74 +64,142 @@ static struct
{"until", UNTIL},
{"while", WHILE} };
#define RESERVEDSIZE (sizeof(reserved)/sizeof(reserved[0]))
int findReserved (char *name)
void luaI_addReserved (void)
{
int l = 0;
int h = RESERVEDSIZE - 1;
while (l <= h)
int i;
for (i=0; i<RESERVEDSIZE; i++)
{
int m = (l+h)/2;
int comp = strcmp(name, reserved[m].name);
if (comp < 0)
h = m-1;
else if (comp == 0)
return reserved[m].token;
else
l = m+1;
TaggedString *ts = lua_createstring(reserved[i].name);
ts->marked = reserved[i].token; /* reserved word (always > 255) */
}
return 0;
}
int yylex ()
static int inclinenumber (int pragma_allowed)
{
++lua_linenumber;
if (pragma_allowed && current == '$') { /* is a pragma? */
char *buff = luaI_buffer(MINBUFF+1);
int i = 0;
next(); /* skip $ */
while (isalnum(current)) {
if (i >= MINBUFF) luaI_syntaxerror("pragma too long");
buff[i++] = current;
next();
}
buff[i] = 0;
if (strcmp(buff, "debug") == 0)
lua_debug = 1;
else if (strcmp(buff, "nodebug") == 0)
lua_debug = 0;
else luaI_syntaxerror("invalid pragma");
}
return lua_linenumber;
}
static int read_long_string (char *yytext, int buffsize)
{
int cont = 0;
int tokensize = 2; /* '[[' already stored */
while (1)
{
yytextLast = yytext;
if (buffsize-tokensize <= 2) /* may read more than 1 char in one cicle */
yytext = luaI_buffer(buffsize *= 2);
switch (current)
{
case '\n': lua_linenumber++;
case ' ':
case '\t':
case 0:
save(0);
return WRONGTOKEN;
case '[':
save_and_next();
if (current == '[')
{
cont++;
save_and_next();
}
continue;
case ']':
save_and_next();
if (current == ']')
{
if (cont == 0) goto endloop;
cont--;
save_and_next();
}
continue;
case '\n':
save_and_next();
inclinenumber(0);
continue;
default:
save_and_next();
}
} endloop:
save_and_next(); /* pass the second ']' */
yytext[tokensize-2] = 0; /* erases ']]' */
luaY_lval.vWord = luaI_findconstantbyname(yytext+2);
yytext[tokensize-2] = ']'; /* restores ']]' */
save(0);
return STRING;
}
int luaY_lex (void)
{
static int linelasttoken = 0;
double a;
int buffsize = MINBUFF;
char *yytext = luaI_buffer(buffsize);
yytext[1] = yytext[2] = yytext[3] = 0;
if (lua_debug)
luaI_codedebugline(linelasttoken);
linelasttoken = lua_linenumber;
while (1)
{
int tokensize = 0;
switch (current)
{
case '\n':
next();
linelasttoken = inclinenumber(1);
continue;
case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
next();
continue;
case '$':
next();
while (isalnum(current) || current == '_')
save_and_next();
*yytextLast = 0;
if (strcmp(yytext, "debug") == 0)
{
yylval.vInt = 1;
return DEBUG;
}
else if (strcmp(yytext, "nodebug") == 0)
{
yylval.vInt = 0;
return DEBUG;
}
return WRONGTOKEN;
case '-':
save_and_next();
if (current != '-') return '-';
do { next(); } while (current != '\n' && current != 0);
continue;
case '[':
save_and_next();
if (current != '[') return '[';
else
{
save_and_next(); /* pass the second '[' */
return read_long_string(yytext, buffsize);
}
case '=':
save_and_next();
if (current != '=') return '=';
else { save_and_next(); return EQ; }
case '<':
save_and_next();
if (current != '=') return '<';
else { save_and_next(); return LE; }
case '>':
save_and_next();
if (current != '=') return '>';
else { save_and_next(); return GE; }
case '~':
save_and_next();
if (current != '=') return '~';
@@ -143,13 +209,16 @@ int yylex ()
case '\'':
{
int del = current;
next(); /* skip the delimiter */
while (current != del)
save_and_next();
while (current != del)
{
if (buffsize-tokensize <= 2) /* may read more than 1 char in one cicle */
yytext = luaI_buffer(buffsize *= 2);
switch (current)
{
case 0:
case '\n':
case 0:
case '\n':
save(0);
return WRONGTOKEN;
case '\\':
next(); /* do not save the '\' */
@@ -158,16 +227,19 @@ int yylex ()
case 'n': save('\n'); next(); break;
case 't': save('\t'); next(); break;
case 'r': save('\r'); next(); break;
default : save('\\'); break;
case '\n': save_and_next(); inclinenumber(0); break;
default : save_and_next(); break;
}
break;
default:
default:
save_and_next();
}
}
next(); /* skip the delimiter */
*yytextLast = 0;
yylval.vWord = lua_findconstant (yytext);
next(); /* skip delimiter */
save(0);
luaY_lval.vWord = luaI_findconstantbyname(yytext+1);
tokensize--;
save(del); save(0); /* restore delimiter */
return STRING;
}
@@ -185,49 +257,85 @@ int yylex ()
case 'Z':
case '_':
{
int res;
TaggedString *ts;
do { save_and_next(); } while (isalnum(current) || current == '_');
*yytextLast = 0;
res = findReserved(yytext);
if (res) return res;
yylval.pChar = yytext;
save(0);
ts = lua_createstring(yytext);
if (ts->marked > 2)
return ts->marked; /* reserved word */
luaY_lval.pTStr = ts;
ts->marked = 2; /* avoid GC */
return NAME;
}
case '.':
save_and_next();
if (current == '.')
{
save_and_next();
return CONC;
if (current == '.')
{
save_and_next();
if (current == '.')
{
save_and_next();
return DOTS; /* ... */
}
else return CONC; /* .. */
}
else if (!isdigit(current)) return '.';
/* current is a digit: goes through to number */
a=0.0;
goto fraction;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
do { save_and_next(); } while (isdigit(current));
if (current == '.') save_and_next();
fraction: while (isdigit(current)) save_and_next();
if (current == 'e' || current == 'E')
{
a=0.0;
do {
a=10.0*a+(current-'0');
save_and_next();
if (current == '+' || current == '-') save_and_next();
if (!isdigit(current)) return WRONGTOKEN;
do { save_and_next(); } while (isdigit(current));
} while (isdigit(current));
if (current == '.') {
save_and_next();
if (current == '.')
luaI_syntaxerror(
"ambiguous syntax (decimal point x string concatenation)");
}
fraction:
{ double da=0.1;
while (isdigit(current))
{
a+=(current-'0')*da;
da/=10.0;
save_and_next();
}
if (current == 'e' || current == 'E')
{
int e=0;
int neg;
double ea;
save_and_next();
neg=(current=='-');
if (current == '+' || current == '-') save_and_next();
if (!isdigit(current)) { save(0); return WRONGTOKEN; }
do {
e=10.0*e+(current-'0');
save_and_next();
} while (isdigit(current));
for (ea=neg?0.1:10.0; e>0; e>>=1)
{
if (e & 1) a*=ea;
ea*=ea;
}
}
luaY_lval.vFloat = a;
save(0);
return NUMBER;
}
*yytextLast = 0;
yylval.vFloat = atof(yytext);
return NUMBER;
default: /* also end of file */
default: /* also end of program (0) */
{
save_and_next();
return *yytext;
return yytext[0];
}
}
}
}

19
lex.h Normal file
View File

@@ -0,0 +1,19 @@
/*
** lex.h
** TecCGraf - PUC-Rio
** $Id: lex.h,v 1.2 1996/02/14 13:35:51 roberto Exp roberto $
*/
#ifndef lex_h
#define lex_h
typedef int (*Input) (void);
void lua_setinput (Input fn);
void luaI_syntaxerror (char *s);
int luaY_lex (void);
void luaI_addReserved (void);
#endif

70
lua.c
View File

@@ -3,29 +3,69 @@
** Linguagem para Usuarios de Aplicacao
*/
char *rcs_lua="$Id: $";
char *rcs_lua="$Id: lua.c,v 1.13 1996/07/06 20:20:35 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
#include "lua.h"
#include "lualib.h"
void main (int argc, char *argv[])
#ifdef _POSIX_SOURCE
#include <unistd.h>
#else
#define isatty(x) (x==0) /* assume stdin is a tty */
#endif
static void manual_input (void)
{
int i;
iolib_open ();
strlib_open ();
mathlib_open ();
if (argc < 2)
{
char buffer[250];
while (gets(buffer) != 0)
lua_dostring(buffer);
}
else
for (i=1; i<argc; i++)
lua_dofile (argv[i]);
if (isatty(0)) {
char buffer[250];
while (fgets(buffer, sizeof(buffer), stdin) != 0) {
lua_beginblock();
lua_dostring(buffer);
lua_endblock();
}
}
else
lua_dofile(NULL); /* executes stdin as a file */
}
int main (int argc, char *argv[])
{
int i;
int result = 0;
iolib_open ();
strlib_open ();
mathlib_open ();
if (argc < 2)
manual_input();
else for (i=1; i<argc; i++) {
if (strcmp(argv[i], "-") == 0)
manual_input();
else if (strcmp(argv[i], "-v") == 0)
printf("%s %s\n(written by %s)\n\n",
LUA_VERSION, LUA_COPYRIGHT, LUA_AUTHORS);
else if ((strcmp(argv[i], "-e") == 0 && i++) || strchr(argv[i], '=')) {
if (lua_dostring(argv[i]) != 0) {
fprintf(stderr, "lua: error running argument `%s'\n", argv[i]);
return 1;
}
}
else {
result = lua_dofile (argv[i]);
if (result) {
if (result == 2) {
fprintf(stderr, "lua: cannot execute file `%s' - ", argv[i]);
perror(NULL);
}
return 1;
}
}
}
return result;
}

112
lua.h
View File

@@ -2,53 +2,115 @@
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: $
** $Id: lua.h,v 3.31 1996/11/12 16:00:16 roberto Exp roberto $
*/
#ifndef lua_h
#define lua_h
#define LUA_VERSION "Lua 2.5.1"
#define LUA_COPYRIGHT "Copyright (C) 1994-1996 TeCGraf"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
/* Private Part */
typedef enum
{
LUA_T_NIL = -1,
LUA_T_NUMBER = -2,
LUA_T_STRING = -3,
LUA_T_ARRAY = -4,
LUA_T_FUNCTION = -5,
LUA_T_CFUNCTION= -6,
LUA_T_MARK = -7,
LUA_T_CMARK = -8,
LUA_T_LINE = -9,
LUA_T_USERDATA = 0
} lua_Type;
/* Public Part */
#define LUA_NOOBJECT 0
typedef void (*lua_CFunction) (void);
typedef struct Object *lua_Object;
typedef unsigned int lua_Object;
#define lua_register(n,f) (lua_pushcfunction(f), lua_storeglobal(n))
lua_Object lua_setfallback (char *name, lua_CFunction fallback);
void lua_errorfunction (void (*fn) (char *s));
void lua_error (char *s);
int lua_dofile (char *filename);
int lua_dostring (char *string);
int lua_call (char *functionname, int nparam);
int lua_callfunction (lua_Object function);
int lua_call (char *funcname);
void lua_beginblock (void);
void lua_endblock (void);
lua_Object lua_getparam (int number);
#define lua_getresult(_) lua_getparam(_)
#define lua_isnil(_) (lua_type(_)==LUA_T_NIL)
#define lua_istable(_) (lua_type(_)==LUA_T_ARRAY)
#define lua_isuserdata(_) (lua_type(_)>=LUA_T_USERDATA)
#define lua_iscfunction(_) (lua_type(_)==LUA_T_CFUNCTION)
int lua_isnumber (lua_Object object);
int lua_isstring (lua_Object object);
int lua_isfunction (lua_Object object);
float lua_getnumber (lua_Object object);
char *lua_getstring (lua_Object object);
char *lua_copystring (lua_Object object);
lua_CFunction lua_getcfunction (lua_Object object);
void *lua_getuserdata (lua_Object object);
lua_Object lua_getfield (lua_Object object, char *field);
lua_Object lua_getindexed (lua_Object object, float index);
void lua_pushnil (void);
void lua_pushnumber (float n);
void lua_pushstring (char *s);
void lua_pushcfunction (lua_CFunction fn);
void lua_pushusertag (void *u, int tag);
void lua_pushobject (lua_Object object);
lua_Object lua_getglobal (char *name);
void lua_storeglobal (char *name);
lua_Object lua_pop (void);
void lua_storesubscript (void);
lua_Object lua_getsubscript (void);
int lua_pushnil (void);
int lua_pushnumber (float n);
int lua_pushstring (char *s);
int lua_pushcfunction (lua_CFunction fn);
int lua_pushuserdata (void *u);
int lua_pushobject (lua_Object object);
int lua_type (lua_Object object);
int lua_storeglobal (char *name);
int lua_storefield (lua_Object object, char *field);
int lua_storeindexed (lua_Object object, float index);
int lua_isnil (lua_Object object);
int lua_isnumber (lua_Object object);
int lua_isstring (lua_Object object);
int lua_istable (lua_Object object);
int lua_iscfunction (lua_Object object);
int lua_isuserdata (lua_Object object);
int lua_ref (int lock);
lua_Object lua_getref (int ref);
void lua_pushref (int ref);
void lua_unref (int ref);
lua_Object lua_createtable (void);
/* some useful macros */
#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l))
#define lua_register(n,f) (lua_pushcfunction(f), lua_storeglobal(n))
#define lua_pushuserdata(u) lua_pushusertag(u, LUA_T_USERDATA)
/* for compatibility with old versions. Avoid using these macros */
#define lua_lockobject(o) lua_refobject(o,1)
#define lua_lock() lua_ref(1)
#define lua_getlocked lua_getref
#define lua_pushlocked lua_pushref
#define lua_unlock lua_unref
#define lua_pushliteral(o) lua_pushstring(o)
#define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_getsubscript())
#define lua_getfield(o,f) (lua_pushobject(o), lua_pushliteral(f), lua_getsubscript())
#define lua_copystring(o) (strdup(lua_getstring(o)))
#endif

85
lua.lex
View File

@@ -1,85 +0,0 @@
%{
char *rcs_lualex = "$Id: $";
#include <stdlib.h>
#include <string.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "y.tab.h"
#undef input
#undef unput
static Input input;
static Unput unput;
void lua_setinput (Input fn)
{
input = fn;
}
void lua_setunput (Unput fn)
{
unput = fn;
}
char *lua_lasttext (void)
{
return yytext;
}
%}
%%
[ \t]* ;
^"$debug" {yylval.vInt = 1; return DEBUG;}
^"$nodebug" {yylval.vInt = 0; return DEBUG;}
\n lua_linenumber++;
"--".* ;
"local" return LOCAL;
"if" return IF;
"then" return THEN;
"else" return ELSE;
"elseif" return ELSEIF;
"while" return WHILE;
"do" return DO;
"repeat" return REPEAT;
"until" return UNTIL;
"function" {
yylval.vWord = lua_nfile-1;
return FUNCTION;
}
"end" return END;
"return" return RETURN;
"local" return LOCAL;
"nil" return NIL;
"and" return AND;
"or" return OR;
"not" return NOT;
"~=" return NE;
"<=" return LE;
">=" return GE;
".." return CONC;
\"[^\"]*\" |
\'[^\']*\' {
yylval.vWord = lua_findenclosedconstant (yytext);
return STRING;
}
[0-9]+("."[0-9]*)? |
([0-9]+)?"."[0-9]+ |
[0-9]+("."[0-9]*)?[dDeEgG][+-]?[0-9]+ |
([0-9]+)?"."[0-9]+[dDeEgG][+-]?[0-9]+ {
yylval.vFloat = atof(yytext);
return NUMBER;
}
[a-zA-Z_][a-zA-Z0-9_]* {
yylval.vWord = lua_findsymbol (yytext);
return NAME;
}
. return *yytext;

1370
lua.stx

File diff suppressed because it is too large Load Diff

31
luadebug.h Normal file
View File

@@ -0,0 +1,31 @@
/*
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: luadebug.h,v 1.5 1996/02/08 17:03:20 roberto Exp roberto $
*/
#ifndef luadebug_h
#define luadebug_h
#include "lua.h"
typedef lua_Object lua_Function;
typedef void (*lua_LHFunction) (int line);
typedef void (*lua_CHFunction) (lua_Function func, char *file, int line);
lua_Function lua_stackedfunction (int level);
void lua_funcinfo (lua_Object func, char **filename, int *linedefined);
int lua_currentline (lua_Function func);
char *lua_getobjname (lua_Object o, char **name);
lua_Object lua_getlocal (lua_Function func, int local_number, char **name);
int lua_setlocal (lua_Function func, int local_number);
extern lua_LHFunction lua_linehook;
extern lua_CHFunction lua_callhook;
extern int lua_debug;
#endif

View File

@@ -2,15 +2,37 @@
** Libraries to be used in LUA programs
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: $
** $Id: lualib.h,v 1.9 1996/08/01 14:55:33 roberto Exp roberto $
*/
#ifndef lualib_h
#define lualib_h
#include "lua.h"
void iolib_open (void);
void strlib_open (void);
void mathlib_open (void);
/* auxiliar functions (private) */
struct lua_reg {
char *name;
lua_CFunction func;
};
void luaI_openlib (struct lua_reg *l, int n);
void lua_arg_check(int cond, char *funcname);
char *lua_check_string (int numArg, char *funcname);
char *lua_opt_string (int numArg, char *def, char *funcname);
double lua_check_number (int numArg, char *funcname);
long lua_opt_number (int numArg, long def, char *funcname);
char *luaI_addchar (int c);
void luaI_addquoted (char *s);
char *item_end (char *p);
int singlematch (int c, char *p);
#endif

58
luamem.c Normal file
View File

@@ -0,0 +1,58 @@
/*
** mem.c
** TecCGraf - PUC-Rio
*/
char *rcs_mem = "$Id: mem.c,v 1.12 1996/05/06 16:59:00 roberto Exp roberto $";
#include <stdlib.h>
#include "mem.h"
#include "lua.h"
void luaI_free (void *block)
{
if (block)
{
*((int *)block) = -1; /* to catch errors */
free(block);
}
}
void *luaI_realloc (void *oldblock, unsigned long size)
{
void *block;
size_t s = (size_t)size;
if (s != size)
lua_error("Allocation Error: Block too big");
block = oldblock ? realloc(oldblock, s) : malloc(s);
if (block == NULL)
lua_error(memEM);
return block;
}
int luaI_growvector (void **block, unsigned long nelems, int size,
char *errormsg, unsigned long limit)
{
if (nelems >= limit)
lua_error(errormsg);
nelems = (nelems == 0) ? 20 : nelems*2;
if (nelems > limit)
nelems = limit;
*block = luaI_realloc(*block, nelems*size);
return (int)nelems;
}
void* luaI_buffer (unsigned long size)
{
static unsigned long buffsize = 0;
static char* buffer = NULL;
if (size > buffsize)
buffer = luaI_realloc(buffer, buffsize=size);
return buffer;
}

39
luamem.h Normal file
View File

@@ -0,0 +1,39 @@
/*
** mem.c
** memory manager for lua
** $Id: mem.h,v 1.7 1996/04/22 18:00:37 roberto Exp roberto $
*/
#ifndef mem_h
#define mem_h
#ifndef NULL
#define NULL 0
#endif
/* memory error messages */
#define codeEM "code size overflow"
#define symbolEM "symbol table overflow"
#define constantEM "constant table overflow"
#define stackEM "stack size overflow"
#define lexEM "lex buffer overflow"
#define refEM "reference table overflow"
#define tableEM "table overflow"
#define memEM "not enough memory"
void luaI_free (void *block);
void *luaI_realloc (void *oldblock, unsigned long size);
void *luaI_buffer (unsigned long size);
int luaI_growvector (void **block, unsigned long nelems, int size,
char *errormsg, unsigned long limit);
#define luaI_malloc(s) luaI_realloc(NULL, (s))
#define new(s) ((s *)luaI_malloc(sizeof(s)))
#define newvector(n,s) ((s *)luaI_malloc((n)*sizeof(s)))
#define growvector(old,n,s,e,l) \
(luaI_growvector((void**)old,n,sizeof(s),e,l))
#endif

107
makefile
View File

@@ -1,53 +1,98 @@
# $Id: makefile,v 1.5 1994/01/10 19:49:56 roberto Exp celes $
# $Id: makefile,v 1.27 1996/08/28 20:45:48 roberto Exp roberto $
#configuration
# define (undefine) POPEN if your system (does not) support piped I/O
# define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant
#define (undefine) NOSTRERROR if your system does NOT have function "strerror"
# (although this is ANSI, SunOS does not comply; so, add "-DNOSTRERROR" on SunOS)
CONFIG = -DPOPEN -D_POSIX_SOURCE
# Compilation parameters
CC = gcc
CFLAGS = -I/usr/5include -Wall -O2
CFLAGS = $(CONFIG) -Wall -Wmissing-prototypes -Wshadow -ansi -O2 -pedantic
#CC = acc
#CFLAGS = -fast -I/usr/5include
AR = ar
ARFLAGS = rvl
# Aplication modules
LUAMOD = \
y.tab \
lex \
opcode \
hash \
table \
inout \
tree
LUAOBJS = \
parser.o \
lex.o \
opcode.o \
hash.o \
table.o \
inout.o \
tree.o \
fallback.o \
mem.o \
func.o \
undump.o
LIBMOD = \
iolib \
strlib \
mathlib
LIBOBJS = \
iolib.o \
mathlib.o \
strlib.o
LUAOBJS = $(LUAMOD:%=%.o)
LIBOBJS = $(LIBMOD:%=%.o)
lua : lua.o liblua.a liblualib.a
$(CC) $(CFLAGS) -o $@ lua.o -L. -llua -llualib -lm
lua : lua.o lua.a lualib.a
$(CC) $(CFLAGS) -o $@ lua.c lua.a lualib.a -lm
lua.a : y.tab.c $(LUAOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib lua.a
lualib.a : $(LIBOBJS)
liblua.a : $(LUAOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib $@
.KEEP_STATE:
liblualib.a : $(LIBOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib $@
liblua.so.1.0 : lua.o
ld -o liblua.so.1.0 $(LUAOBJS)
%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
y.tab.c y.tab.h : lua.stx
yacc -d lua.stx
parser.c : y.tab.c
sed -e 's/yy/luaY_/g' -e 's/malloc\.h/stdlib\.h/g' y.tab.c > parser.c
parser.h : y.tab.h
sed -e 's/yy/luaY_/g' y.tab.h > parser.h
clear :
rcsclean
rm -f *.o
rm -f parser.c parser.h y.tab.c y.tab.h
co lua.h lualib.h luadebug.h
y.tab.c : lua.stx exscript
yacc -d lua.stx ; ex y.tab.c <exscript
% : RCS/%,v
%.h : RCS/%.h,v
co $@
%.c : RCS/%.c,v
co $@
fallback.o : fallback.c mem.h fallback.h lua.h opcode.h types.h tree.h func.h \
table.h
func.o : func.c luadebug.h lua.h table.h tree.h types.h opcode.h func.h mem.h
hash.o : hash.c mem.h opcode.h lua.h types.h tree.h func.h hash.h table.h
inout.o : inout.c lex.h opcode.h lua.h types.h tree.h func.h inout.h table.h \
mem.h
iolib.o : iolib.c lua.h luadebug.h lualib.h
lex.o : lex.c mem.h tree.h types.h table.h opcode.h lua.h func.h lex.h inout.h \
luadebug.h parser.h
lua.o : lua.c lua.h lualib.h
mathlib.o : mathlib.c lualib.h lua.h
mem.o : mem.c mem.h lua.h
opcode.o : opcode.c luadebug.h lua.h mem.h opcode.h types.h tree.h func.h hash.h \
inout.h table.h fallback.h undump.h
parser.o : parser.c luadebug.h lua.h mem.h lex.h opcode.h types.h tree.h func.h \
hash.h inout.h table.h
strlib.o : strlib.c lua.h lualib.h
table.o : table.c mem.h opcode.h lua.h types.h tree.h func.h hash.h table.h \
inout.h fallback.h luadebug.h
tree.o : tree.c mem.h lua.h tree.h types.h lex.h hash.h opcode.h func.h table.h
undump.o : undump.c opcode.h lua.h types.h tree.h func.h mem.h table.h undump.h

2363
manual.tex Normal file

File diff suppressed because it is too large Load Diff

247
mathlib.c
View File

@@ -3,25 +3,23 @@
** Mathematics library to LUA
*/
char *rcs_mathlib="$Id: $";
char *rcs_mathlib="$Id: mathlib.c,v 1.17 1996/04/30 21:13:55 roberto Exp roberto $";
#include <stdio.h> /* NULL */
#include <stdlib.h>
#include <math.h>
#include "lualib.h"
#include "lua.h"
#define TODEGREE(a) ((a)*180.0/3.14159)
#define TORAD(a) ((a)*3.14159/180.0)
#ifndef PI
#define PI 3.14159265358979323846
#endif
#define TODEGREE(a) ((a)*180.0/PI)
#define TORAD(a) ((a)*PI/180.0)
static void math_abs (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `abs'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `abs'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "abs");
if (d < 0) d = -d;
lua_pushnumber (d);
}
@@ -29,13 +27,7 @@ static void math_abs (void)
static void math_sin (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `sin'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `sin'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "sin");
lua_pushnumber (sin(TORAD(d)));
}
@@ -43,13 +35,7 @@ static void math_sin (void)
static void math_cos (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `cos'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `cos'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "cos");
lua_pushnumber (cos(TORAD(d)));
}
@@ -57,179 +43,188 @@ static void math_cos (void)
static void math_tan (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `tan'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `tan'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "tan");
lua_pushnumber (tan(TORAD(d)));
}
static void math_asin (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `asin'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `asin'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "asin");
lua_pushnumber (TODEGREE(asin(d)));
}
static void math_acos (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `acos'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `acos'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "acos");
lua_pushnumber (TODEGREE(acos(d)));
}
static void math_atan (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `atan'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `atan'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "atan");
lua_pushnumber (TODEGREE(atan(d)));
}
static void math_atan2 (void)
{
double d1 = lua_check_number(1, "atan2");
double d2 = lua_check_number(2, "atan2");
lua_pushnumber (TODEGREE(atan2(d1, d2)));
}
static void math_ceil (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `ceil'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `ceil'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "ceil");
lua_pushnumber (ceil(d));
}
static void math_floor (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `floor'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `floor'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "floor");
lua_pushnumber (floor(d));
}
static void math_mod (void)
{
int d1, d2;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (!lua_isnumber(o1) || !lua_isnumber(o2))
{ lua_error ("incorrect arguments to function `mod'"); return; }
d1 = (int) lua_getnumber(o1);
d2 = (int) lua_getnumber(o2);
lua_pushnumber (d1%d2);
float x = lua_check_number(1, "mod");
float y = lua_check_number(2, "mod");
lua_pushnumber(fmod(x, y));
}
static void math_sqrt (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `sqrt'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `sqrt'"); return; }
d = lua_getnumber(o);
double d = lua_check_number(1, "sqrt");
lua_pushnumber (sqrt(d));
}
static int old_pow;
static void math_pow (void)
{
double d1, d2;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (!lua_isnumber(o1) || !lua_isnumber(o2))
{ lua_error ("incorrect arguments to function `pow'"); return; }
d1 = lua_getnumber(o1);
d2 = lua_getnumber(o2);
lua_pushnumber (pow(d1,d2));
lua_Object op = lua_getparam(3);
if (!lua_isnumber(o1) || !lua_isnumber(o2) || *(lua_getstring(op)) != 'p')
{
lua_Object old = lua_getref(old_pow);
lua_pushobject(o1);
lua_pushobject(o2);
lua_pushobject(op);
if (lua_callfunction(old) != 0)
lua_error(NULL);
}
else
{
double d1 = lua_getnumber(o1);
double d2 = lua_getnumber(o2);
lua_pushnumber (pow(d1,d2));
}
}
static void math_min (void)
{
int i=1;
double d, dmin;
lua_Object o;
if ((o = lua_getparam(i++)) == NULL)
{ lua_error ("too few arguments to function `min'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `min'"); return; }
dmin = lua_getnumber (o);
while ((o = lua_getparam(i++)) != NULL)
double dmin = lua_check_number(i, "min");
while (lua_getparam(++i) != LUA_NOOBJECT)
{
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `min'"); return; }
d = lua_getnumber (o);
double d = lua_check_number(i, "min");
if (d < dmin) dmin = d;
}
lua_pushnumber (dmin);
}
static void math_max (void)
{
int i=1;
double d, dmax;
lua_Object o;
if ((o = lua_getparam(i++)) == NULL)
{ lua_error ("too few arguments to function `max'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `max'"); return; }
dmax = lua_getnumber (o);
while ((o = lua_getparam(i++)) != NULL)
double dmax = lua_check_number(i, "max");
while (lua_getparam(++i) != LUA_NOOBJECT)
{
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `max'"); return; }
d = lua_getnumber (o);
double d = lua_check_number(i, "max");
if (d > dmax) dmax = d;
}
lua_pushnumber (dmax);
}
static void math_log (void)
{
double d = lua_check_number(1, "log");
lua_pushnumber (log(d));
}
static void math_log10 (void)
{
double d = lua_check_number(1, "log10");
lua_pushnumber (log10(d));
}
static void math_exp (void)
{
double d = lua_check_number(1, "exp");
lua_pushnumber (exp(d));
}
static void math_deg (void)
{
float d = lua_check_number(1, "deg");
lua_pushnumber (d*180./PI);
}
static void math_rad (void)
{
float d = lua_check_number(1, "rad");
lua_pushnumber (d/180.*PI);
}
static void math_random (void)
{
lua_pushnumber((double)(rand()%RAND_MAX) / (double)RAND_MAX);
}
static void math_randomseed (void)
{
srand(lua_check_number(1, "randomseed"));
}
static struct lua_reg mathlib[] = {
{"abs", math_abs},
{"sin", math_sin},
{"cos", math_cos},
{"tan", math_tan},
{"asin", math_asin},
{"acos", math_acos},
{"atan", math_atan},
{"atan2", math_atan2},
{"ceil", math_ceil},
{"floor", math_floor},
{"mod", math_mod},
{"sqrt", math_sqrt},
{"min", math_min},
{"max", math_max},
{"log", math_log},
{"log10", math_log10},
{"exp", math_exp},
{"deg", math_deg},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed}
};
/*
** Open math library
*/
void mathlib_open (void)
{
lua_register ("abs", math_abs);
lua_register ("sin", math_sin);
lua_register ("cos", math_cos);
lua_register ("tan", math_tan);
lua_register ("asin", math_asin);
lua_register ("acos", math_acos);
lua_register ("atan", math_atan);
lua_register ("ceil", math_ceil);
lua_register ("floor", math_floor);
lua_register ("mod", math_mod);
lua_register ("sqrt", math_sqrt);
lua_register ("pow", math_pow);
lua_register ("min", math_min);
lua_register ("max", math_max);
luaI_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
old_pow = lua_refobject(lua_setfallback("arith", math_pow), 1);
}

39
mm.h
View File

@@ -1,39 +0,0 @@
/*
** mm.h
** Waldemar Celes Filho
** Sep 16, 1992
*/
#ifndef mm_h
#define mm_h
#include <stdlib.h>
#ifdef _MM_
/* switch off the debugger functions */
#define malloc(s) MmMalloc(s,__FILE__,__LINE__)
#define calloc(n,s) MmCalloc(n,s,__FILE__,__LINE__)
#define realloc(a,s) MmRealloc(a,s,__FILE__,__LINE__,#a)
#define free(a) MmFree(a,__FILE__,__LINE__,#a)
#define strdup(s) MmStrdup(s,__FILE__,__LINE__)
#endif
typedef void (*Ferror) (char *);
/* Exported functions */
void MmInit (Ferror f, Ferror w);
void *MmMalloc (unsigned size, char *file, int line);
void *MmCalloc (unsigned n, unsigned size, char *file, int line);
void MmFree (void *a, char *file, int line, char *var);
void *MmRealloc (void *old, unsigned size, char *file, int line, char *var);
char *MmStrdup (char *s, char *file, int line);
unsigned MmGetBytes (void);
void MmListAllocated (void);
void MmCheck (void);
void MmStatistics (void);
#endif

1914
opcode.c

File diff suppressed because it is too large Load Diff

212
opcode.h
View File

@@ -1,131 +1,123 @@
/*
** TeCGraf - PUC-Rio
** $Id: opcode.h,v 2.1 1994/04/20 22:07:57 celes Exp celes $
** $Id: opcode.h,v 3.23 1996/09/26 21:08:41 roberto Exp roberto $
*/
#ifndef opcode_h
#define opcode_h
#ifndef STACKGAP
#define STACKGAP 128
#endif
#include "lua.h"
#include "types.h"
#include "tree.h"
#include "func.h"
#ifndef real
#define real float
#endif
#define FIELDS_PER_FLUSH 40
typedef unsigned char Byte;
typedef unsigned short Word;
typedef enum {
/* name parm before after side effect
-----------------------------------------------------------------------------*/
typedef signed long Long;
PUSHNIL,/* - nil */
PUSH0,/* - 0.0 */
PUSH1,/* - 1.0 */
PUSH2,/* - 2.0 */
PUSHBYTE,/* b - (float)b */
PUSHWORD,/* w - (float)w */
PUSHFLOAT,/* f - f */
PUSHSTRING,/* w - STR[w] */
PUSHFUNCTION,/* p - FUN(p) */
PUSHLOCAL0,/* - LOC[0] */
PUSHLOCAL1,/* - LOC[1] */
PUSHLOCAL2,/* - LOC[2] */
PUSHLOCAL3,/* - LOC[3] */
PUSHLOCAL4,/* - LOC[4] */
PUSHLOCAL5,/* - LOC[5] */
PUSHLOCAL6,/* - LOC[6] */
PUSHLOCAL7,/* - LOC[7] */
PUSHLOCAL8,/* - LOC[8] */
PUSHLOCAL9,/* - LOC[9] */
PUSHLOCAL,/* w - LOC[w] */
PUSHGLOBAL,/* w - VAR[w] */
PUSHINDEXED,/* i t t[i] */
PUSHSELF,/* w t t t[STR[w]] */
STORELOCAL0,/* x - LOC[0]=x */
STORELOCAL1,/* x - LOC[1]=x */
STORELOCAL2,/* x - LOC[2]=x */
STORELOCAL3,/* x - LOC[3]=x */
STORELOCAL4,/* x - LOC[4]=x */
STORELOCAL5,/* x - LOC[5]=x */
STORELOCAL6,/* x - LOC[6]=x */
STORELOCAL7,/* x - LOC[7]=x */
STORELOCAL8,/* x - LOC[8]=x */
STORELOCAL9,/* x - LOC[9]=x */
STORELOCAL,/* w x - LOC[w]=x */
STOREGLOBAL,/* w x - VAR[w]=x */
STOREINDEXED0,/* v i t - t[i]=v */
STOREINDEXED,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
STORELIST0,/* w v_w...v_1 t - t[i]=v_i */
STORELIST,/* w n v_w...v_1 t - t[i+n*FPF]=v_i */
STORERECORD,/* n
w_n...w_1 v_n...v_1 t - t[STR[w_i]]=v_i */
ADJUST0,/* - - TOP=BASE */
ADJUST,/* b - - TOP=BASE+b */
CREATEARRAY,/* w - newarray(size = w) */
EQOP,/* y x (x==y)? 1 : nil */
LTOP,/* y x (x<y)? 1 : nil */
LEOP,/* y x (x<y)? 1 : nil */
GTOP,/* y x (x>y)? 1 : nil */
GEOP,/* y x (x>=y)? 1 : nil */
ADDOP,/* y x x+y */
SUBOP,/* y x x-y */
MULTOP,/* y x x*y */
DIVOP,/* y x x/y */
POWOP,/* y x x^y */
CONCOP,/* y x x..y */
MINUSOP,/* x -x */
NOTOP,/* x (x==nil)? 1 : nil */
ONTJMP,/* w x - (x!=nil)? PC+=w */
ONFJMP,/* w x - (x==nil)? PC+=w */
JMP,/* w - - PC+=w */
UPJMP,/* w - - PC-=w */
IFFJMP,/* w x - (x==nil)? PC+=w */
IFFUPJMP,/* w x - (x==nil)? PC-=w */
POP,/* x - */
CALLFUNC,/* n m v_n...v_1 f r_m...r_1 f(v1,...,v_n) */
RETCODE0,
RETCODE,/* b - - */
SETLINE,/* w - - LINE=w */
VARARGS/* b v_n...v_1 {v_1...v_n;n=n} */
typedef union
{
struct {char c1; char c2;} m;
Word w;
} CodeWord;
typedef union
{
struct {char c1; char c2; char c3; char c4;} m;
float f;
} CodeFloat;
typedef enum
{
PUSHNIL,
PUSH0, PUSH1, PUSH2,
PUSHBYTE,
PUSHWORD,
PUSHFLOAT,
PUSHSTRING,
PUSHLOCAL0, PUSHLOCAL1, PUSHLOCAL2, PUSHLOCAL3, PUSHLOCAL4,
PUSHLOCAL5, PUSHLOCAL6, PUSHLOCAL7, PUSHLOCAL8, PUSHLOCAL9,
PUSHLOCAL,
PUSHGLOBAL,
PUSHINDEXED,
PUSHMARK,
PUSHOBJECT,
STORELOCAL0, STORELOCAL1, STORELOCAL2, STORELOCAL3, STORELOCAL4,
STORELOCAL5, STORELOCAL6, STORELOCAL7, STORELOCAL8, STORELOCAL9,
STORELOCAL,
STOREGLOBAL,
STOREINDEXED0,
STOREINDEXED,
STORELIST0,
STORELIST,
STORERECORD,
ADJUST,
CREATEARRAY,
EQOP,
LTOP,
LEOP,
ADDOP,
SUBOP,
MULTOP,
DIVOP,
CONCOP,
MINUSOP,
NOTOP,
ONTJMP,
ONFJMP,
JMP,
UPJMP,
IFFJMP,
IFFUPJMP,
POP,
CALLFUNC,
RETCODE,
HALT,
SETFUNCTION,
SETLINE,
RESET
} OpCode;
typedef enum
{
T_MARK,
T_NIL,
T_NUMBER,
T_STRING,
T_ARRAY,
T_FUNCTION,
T_CFUNCTION,
T_USERDATA
} Type;
typedef void (*Cfunction) (void);
typedef int (*Input) (void);
#define MULT_RET 255
typedef union
{
Cfunction f;
real n;
char *s;
Byte *b;
lua_CFunction f;
real n;
TaggedString *ts;
TFunc *tf;
struct Hash *a;
void *u;
int i;
} Value;
typedef struct Object
{
Type tag;
lua_Type tag;
Value value;
} Object;
typedef struct
{
Object object;
} Symbol;
/* Macros to access structure members */
#define tag(o) ((o)->tag)
#define nvalue(o) ((o)->value.n)
#define svalue(o) ((o)->value.s)
#define bvalue(o) ((o)->value.b)
#define svalue(o) ((o)->value.ts->str)
#define tsvalue(o) ((o)->value.ts)
#define avalue(o) ((o)->value.a)
#define fvalue(o) ((o)->value.f)
#define uvalue(o) ((o)->value.u)
@@ -135,30 +127,24 @@ typedef struct
#define s_tag(i) (tag(&s_object(i)))
#define s_nvalue(i) (nvalue(&s_object(i)))
#define s_svalue(i) (svalue(&s_object(i)))
#define s_bvalue(i) (bvalue(&s_object(i)))
#define s_tsvalue(i) (tsvalue(&s_object(i)))
#define s_avalue(i) (avalue(&s_object(i)))
#define s_fvalue(i) (fvalue(&s_object(i)))
#define s_uvalue(i) (uvalue(&s_object(i)))
#define get_word(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;}
#define get_float(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\
code.m.c3 = *pc++; code.m.c4 = *pc++;}
#define get_word(code,pc) {memcpy(&code, pc, sizeof(Word)); pc+=sizeof(Word);}
#define get_float(code,pc){memcpy(&code, pc, sizeof(real)); pc+=sizeof(real);}
#define get_code(code,pc) {memcpy(&code, pc, sizeof(TFunc *)); \
pc+=sizeof(TFunc *);}
/* Exported functions */
int lua_execute (Byte *pc);
void lua_markstack (void);
char *lua_strdup (char *l);
void lua_setinput (Input fn); /* from "lex.c" module */
char *lua_lasttext (void); /* from "lex.c" module */
int lua_parse (void); /* from "lua.stx" module */
void lua_type (void);
void lua_obj2number (void);
void lua_print (void);
void lua_internaldofile (void);
void lua_internaldostring (void);
void lua_travstack (void (*fn)(Object *));
void lua_parse (TFunc *tf); /* from "lua.stx" module */
void luaI_codedebugline (int line); /* from "lua.stx" module */
void lua_travstack (int (*fn)(Object *));
Object *luaI_Address (lua_Object o);
void luaI_pushobject (Object *o);
void luaI_gcFB (Object *o);
int luaI_dorun (TFunc *tf);
#endif

612
strlib.c
View File

@@ -3,123 +3,565 @@
** String library to LUA
*/
char *rcs_strlib="$Id: strlib.c,v 1.1 1993/12/17 18:41:19 celes Exp celes $";
char *rcs_strlib="$Id: strlib.c,v 1.32 1996/11/07 20:26:19 roberto Exp roberto $";
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "mm.h"
#include "lua.h"
#include "lualib.h"
struct lbuff {
char *b;
size_t max;
size_t size;
};
static struct lbuff lbuffer = {NULL, 0, 0};
static char *lua_strbuffer (unsigned long size)
{
if (size > lbuffer.max) {
/* ANSI "realloc" doesn't need this test, but some machines (Sun!)
don't follow ANSI */
lbuffer.b = (lbuffer.b) ? realloc(lbuffer.b, lbuffer.max=size) :
malloc(lbuffer.max=size);
if (lbuffer.b == NULL)
lua_error("memory overflow");
}
return lbuffer.b;
}
static char *openspace (unsigned long size)
{
char *buff = lua_strbuffer(lbuffer.size+size);
return buff+lbuffer.size;
}
void lua_arg_check(int cond, char *funcname)
{
if (!cond) {
char buff[100];
sprintf(buff, "incorrect argument to function `%s'", funcname);
lua_error(buff);
}
}
char *lua_check_string (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
lua_arg_check(lua_isstring(o), funcname);
return lua_getstring(o);
}
char *lua_opt_string (int numArg, char *def, char *funcname)
{
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
lua_check_string(numArg, funcname);
}
double lua_check_number (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
lua_arg_check(lua_isnumber(o), funcname);
return lua_getnumber(o);
}
long lua_opt_number (int numArg, long def, char *funcname)
{
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
(long)lua_check_number(numArg, funcname);
}
char *luaI_addchar (int c)
{
if (lbuffer.size >= lbuffer.max)
lua_strbuffer(lbuffer.max == 0 ? 100 : lbuffer.max*2);
lbuffer.b[lbuffer.size++] = c;
if (c == 0)
lbuffer.size = 0; /* prepare for next string */
return lbuffer.b;
}
static void addnchar (char *s, int n)
{
char *b = openspace(n);
strncpy(b, s, n);
lbuffer.size += n;
}
static void addstr (char *s)
{
addnchar(s, strlen(s));
}
/*
** Return the position of the first caracter of a substring into a string
** LUA interface:
** n = strfind (string, substring)
** Interface to strtok
*/
static void str_find (void)
static void str_tok (void)
{
char *s1, *s2, *f;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (!lua_isstring(o1) || !lua_isstring(o2))
{ lua_error ("incorrect arguments to function `strfind'"); return; }
s1 = lua_getstring(o1);
s2 = lua_getstring(o2);
f = strstr(s1,s2);
if (f != NULL)
lua_pushnumber (f-s1+1);
else
lua_pushnil();
char *s1 = lua_check_string(1, "strtok");
char *del = lua_check_string(2, "strtok");
lua_Object t = lua_createtable();
int i = 1;
/* As strtok changes s1, and s1 is "constant", make a copy of it */
s1 = strcpy(lua_strbuffer(strlen(s1+1)), s1);
while ((s1 = strtok(s1, del)) != NULL) {
lua_pushobject(t);
lua_pushnumber(i++);
lua_pushstring(s1);
lua_storesubscript();
s1 = NULL; /* prepare for next strtok */
}
lua_pushobject(t);
lua_pushnumber(i-1); /* total number of tokens */
}
/*
** Return the string length
** LUA interface:
** n = strlen (string)
*/
static void str_len (void)
{
lua_Object o = lua_getparam (1);
if (!lua_isstring(o))
{ lua_error ("incorrect arguments to function `strlen'"); return; }
lua_pushnumber(strlen(lua_getstring(o)));
lua_pushnumber(strlen(lua_check_string(1, "strlen")));
}
/*
** Return the substring of a string, from start to end
** LUA interface:
** substring = strsub (string, start, end)
** Return the substring of a string
*/
static void str_sub (void)
{
int start, end;
char *s;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
lua_Object o3 = lua_getparam (3);
if (!lua_isstring(o1) || !lua_isnumber(o2))
{ lua_error ("incorrect arguments to function `strsub'"); return; }
if (o3 != NULL && !lua_isnumber(o3))
{ lua_error ("incorrect third argument to function `strsub'"); return; }
s = lua_copystring(o1);
start = lua_getnumber (o2);
end = o3 == NULL ? strlen(s) : lua_getnumber (o3);
if (end < start || start < 1 || end > strlen(s))
lua_pushstring("");
else
{
s[end] = 0;
lua_pushstring (&s[start-1]);
}
free (s);
char *s = lua_check_string(1, "strsub");
long start = (long)lua_check_number(2, "strsub");
long end = lua_opt_number(3, strlen(s), "strsub");
if (1 <= start && start <= end && end <= strlen(s)) {
luaI_addchar(0);
addnchar(s+start-1, end-start+1);
lua_pushstring(luaI_addchar(0));
}
else lua_pushliteral("");
}
/*
** Convert a string to lower case.
** LUA interface:
** lowercase = strlower (string)
*/
static void str_lower (void)
{
char *s, *c;
lua_Object o = lua_getparam (1);
if (!lua_isstring(o))
{ lua_error ("incorrect arguments to function `strlower'"); return; }
c = s = strdup(lua_getstring(o));
while (*c != 0)
{
*c = tolower(*c);
c++;
}
lua_pushstring(s);
free(s);
}
char *s = lua_check_string(1, "strlower");
luaI_addchar(0);
while (*s)
luaI_addchar(tolower(*s++));
lua_pushstring(luaI_addchar(0));
}
/*
** Convert a string to upper case.
** LUA interface:
** uppercase = strupper (string)
*/
static void str_upper (void)
{
char *s, *c;
lua_Object o = lua_getparam (1);
if (!lua_isstring(o))
{ lua_error ("incorrect arguments to function `strlower'"); return; }
c = s = strdup(lua_getstring(o));
while (*c != 0)
{
*c = toupper(*c);
c++;
}
lua_pushstring(s);
free(s);
}
char *s = lua_check_string(1, "strupper");
luaI_addchar(0);
while (*s)
luaI_addchar(toupper(*s++));
lua_pushstring(luaI_addchar(0));
}
static void str_rep (void)
{
char *s = lua_check_string(1, "strrep");
int n = (int)lua_check_number(2, "strrep");
luaI_addchar(0);
while (n-- > 0)
addstr(s);
lua_pushstring(luaI_addchar(0));
}
/*
** get ascii value of a character in a string
*/
static void str_ascii (void)
{
char *s = lua_check_string(1, "ascii");
long pos = lua_opt_number(2, 1, "ascii") - 1;
lua_arg_check(0<=pos && pos<strlen(s), "ascii");
lua_pushnumber((unsigned char)s[pos]);
}
/* pattern matching */
#define ESC '%'
#define SPECIALS "^$*?.([%"
static char *bracket_end (char *p)
{
return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']');
}
char *item_end (char *p)
{
switch (*p++) {
case '\0': return p-1;
case ESC:
if (*p == 0) lua_error("incorrect pattern");
return p+1;
case '[': {
char *end = bracket_end(p);
if (end == NULL) lua_error("incorrect pattern");
return end+1;
}
default:
return p;
}
}
static int matchclass (int c, int cl)
{
int res;
switch (tolower(cl)) {
case 'a' : res = isalpha(c); break;
case 'c' : res = iscntrl(c); break;
case 'd' : res = isdigit(c); break;
case 'l' : res = islower(c); break;
case 'p' : res = ispunct(c); break;
case 's' : res = isspace(c); break;
case 'u' : res = isupper(c); break;
case 'w' : res = isalnum(c); break;
default: return (cl == c);
}
return (islower(cl) ? res : !res);
}
int singlematch (int c, char *p)
{
if (c == 0) return 0;
switch (*p) {
case '.': return 1;
case ESC: return matchclass(c, *(p+1));
case '[': {
char *end = bracket_end(p+1);
int sig = *(p+1) == '^' ? (p++, 0) : 1;
while (++p < end) {
if (*p == ESC) {
if (((p+1) < end) && matchclass(c, *++p)) return sig;
}
else if ((*(p+1) == '-') && (p+2 < end)) {
p+=2;
if (*(p-2) <= c && c <= *p) return sig;
}
else if (*p == c) return sig;
}
return !sig;
}
default: return (*p == c);
}
}
#define MAX_CAPT 9
static struct {
char *init;
int len; /* -1 signals unfinished capture */
} capture[MAX_CAPT];
static int num_captures; /* only valid after a sucessful call to match */
static void push_captures (void)
{
int i;
for (i=0; i<num_captures; i++) {
int l = capture[i].len;
char *buff = openspace(l+1);
if (l == -1) lua_error("unfinished capture");
strncpy(buff, capture[i].init, l);
buff[l] = 0;
lua_pushstring(buff);
}
}
static int check_cap (int l, int level)
{
l -= '1';
if (!(0 <= l && l < level && capture[l].len != -1))
lua_error("invalid capture index");
return l;
}
static int capture_to_close (int level)
{
for (level--; level>=0; level--)
if (capture[level].len == -1) return level;
lua_error("invalid pattern capture");
return 0; /* to avoid warnings */
}
static char *matchbalance (char *s, int b, int e)
{
if (*s != b) return NULL;
else {
int cont = 1;
while (*(++s)) {
if (*s == e) {
if (--cont == 0) return s+1;
}
else if (*s == b) cont++;
}
}
return NULL; /* string ends out of balance */
}
static char *match (char *s, char *p, int level)
{
init: /* using goto's to optimize tail recursion */
switch (*p) {
case '(': /* start capture */
if (level >= MAX_CAPT) lua_error("too many captures");
capture[level].init = s;
capture[level].len = -1;
level++; p++; goto init; /* return match(s, p+1, level); */
case ')': { /* end capture */
int l = capture_to_close(level);
char *res;
capture[l].len = s - capture[l].init; /* close capture */
if ((res = match(s, p+1, level)) == NULL) /* match failed? */
capture[l].len = -1; /* undo capture */
return res;
}
case ESC:
if (isdigit(*(p+1))) { /* capture */
int l = check_cap(*(p+1), level);
if (strncmp(capture[l].init, s, capture[l].len) == 0) {
/* return match(p+2, s+capture[l].len, level); */
p+=2; s+=capture[l].len; goto init;
}
else return NULL;
}
else if (*(p+1) == 'b') { /* balanced string */
if (*(p+2) == 0 || *(p+3) == 0)
lua_error("bad balanced pattern specification");
s = matchbalance(s, *(p+2), *(p+3));
if (s == NULL) return NULL;
else { /* return match(p+4, s, level); */
p+=4; goto init;
}
}
else goto dflt;
case '\0': case '$': /* (possibly) end of pattern */
if (*p == 0 || (*(p+1) == 0 && *s == 0)) {
num_captures = level;
return s;
}
else goto dflt;
default: dflt: { /* it is a pattern item */
int m = singlematch(*s, p);
char *ep = item_end(p); /* get what is next */
switch (*ep) {
case '*': { /* repetition */
char *res;
if (m && (res = match(s+1, p, level)))
return res;
p=ep+1; goto init; /* else return match(s, ep+1, level); */
}
case '?': { /* optional */
char *res;
if (m && (res = match(s+1, ep+1, level)))
return res;
p=ep+1; goto init; /* else return match(s, ep+1, level); */
}
default:
if (m) { s++; p=ep; goto init; } /* return match(s+1, ep, level); */
else return NULL;
}
}
}
}
static void str_find (void)
{
char *s = lua_check_string(1, "strfind");
char *p = lua_check_string(2, "strfind");
long init = lua_opt_number(3, 1, "strfind") - 1;
lua_arg_check(0 <= init && init <= strlen(s), "strfind");
if (lua_getparam(4) != LUA_NOOBJECT ||
strpbrk(p, SPECIALS) == NULL) { /* no special caracters? */
char *s2 = strstr(s+init, p);
if (s2) {
lua_pushnumber(s2-s+1);
lua_pushnumber(s2-s+strlen(p));
}
}
else {
int anchor = (*p == '^') ? (p++, 1) : 0;
char *s1=s+init;
do {
char *res;
if ((res=match(s1, p, 0)) != NULL) {
lua_pushnumber(s1-s+1); /* start */
lua_pushnumber(res-s); /* end */
push_captures();
return;
}
} while (*s1++ && !anchor);
}
}
static void add_s (lua_Object newp)
{
if (lua_isstring(newp)) {
char *news = lua_getstring(newp);
while (*news) {
if (*news != ESC || !isdigit(*++news))
luaI_addchar(*news++);
else {
int l = check_cap(*news++, num_captures);
addnchar(capture[l].init, capture[l].len);
}
}
}
else if (lua_isfunction(newp)) {
lua_Object res;
struct lbuff oldbuff;
lua_beginblock();
push_captures();
/* function may use lbuffer, so save it and create a new one */
oldbuff = lbuffer;
lbuffer.b = NULL; lbuffer.max = lbuffer.size = 0;
lua_callfunction(newp);
/* restore old buffer */
free(lbuffer.b);
lbuffer = oldbuff;
res = lua_getresult(1);
addstr(lua_isstring(res) ? lua_getstring(res) : "");
lua_endblock();
}
else lua_arg_check(0, "gsub");
}
static void str_gsub (void)
{
char *src = lua_check_string(1, "gsub");
char *p = lua_check_string(2, "gsub");
lua_Object newp = lua_getparam(3);
int max_s = lua_opt_number(4, strlen(src), "gsub");
int anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0;
luaI_addchar(0);
while (*src && n < max_s) {
char *e;
if ((e=match(src, p, 0)) == NULL)
luaI_addchar(*src++);
else {
if (e == src) lua_error("empty pattern in substitution");
add_s(newp);
src = e;
n++;
}
if (anchor) break;
}
addstr(src);
lua_pushstring(luaI_addchar(0));
lua_pushnumber(n); /* number of substitutions */
}
static void str_set (void)
{
char *item = lua_check_string(1, "strset");
int i;
lua_arg_check(*item_end(item) == 0, "strset");
luaI_addchar(0);
for (i=1; i<256; i++) /* 0 cannot be part of a set */
if (singlematch(i, item))
luaI_addchar(i);
lua_pushstring(luaI_addchar(0));
}
void luaI_addquoted (char *s)
{
luaI_addchar('"');
for (; *s; s++) {
if (strchr("\"\\\n", *s))
luaI_addchar('\\');
luaI_addchar(*s);
}
luaI_addchar('"');
}
#define MAX_FORMAT 200
static void str_format (void)
{
int arg = 1;
char *strfrmt = lua_check_string(arg++, "format");
luaI_addchar(0); /* initialize */
while (*strfrmt) {
if (*strfrmt != '%')
luaI_addchar(*strfrmt++);
else if (*++strfrmt == '%')
luaI_addchar(*strfrmt++); /* %% */
else { /* format item */
char form[MAX_FORMAT]; /* store the format ('%...') */
char *buff;
char *initf = strfrmt-1; /* -1 to include % */
strfrmt = match(strfrmt, "[-+ #]*(%d*)%.?(%d*)", 0);
if (capture[0].len > 3 || capture[1].len > 3) /* < 1000? */
lua_error("invalid format (width/precision too long)");
strncpy(form, initf, strfrmt-initf+1); /* +1 to include convertion */
form[strfrmt-initf+1] = 0;
buff = openspace(1000); /* to store the formated value */
switch (*strfrmt++) {
case 'q':
luaI_addquoted(lua_check_string(arg++, "format"));
continue;
case 's': {
char *s = lua_check_string(arg++, "format");
buff = openspace(strlen(s));
sprintf(buff, form, s);
break;
}
case 'c': case 'd': case 'i': case 'o':
case 'u': case 'x': case 'X':
sprintf(buff, form, (int)lua_check_number(arg++, "format"));
break;
case 'e': case 'E': case 'f': case 'g':
sprintf(buff, form, lua_check_number(arg++, "format"));
break;
default: /* also treat cases 'pnLlh' */
lua_error("invalid format option in function `format'");
}
lbuffer.size += strlen(buff);
}
}
lua_pushstring(luaI_addchar(0)); /* push the result */
}
void luaI_openlib (struct lua_reg *l, int n)
{
int i;
for (i=0; i<n; i++)
lua_register(l[i].name, l[i].func);
}
static struct lua_reg strlib[] = {
{"strtok", str_tok},
{"strlen", str_len},
{"strsub", str_sub},
{"strset", str_set},
{"strlower", str_lower},
{"strupper", str_upper},
{"strrep", str_rep},
{"ascii", str_ascii},
{"format", str_format},
{"strfind", str_find},
{"gsub", str_gsub}
};
/*
@@ -127,9 +569,5 @@ static void str_upper (void)
*/
void strlib_open (void)
{
lua_register ("strfind", str_find);
lua_register ("strlen", str_len);
lua_register ("strsub", str_sub);
lua_register ("strlower", str_lower);
lua_register ("strupper", str_upper);
luaI_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0])));
}

409
table.c
View File

@@ -3,198 +3,192 @@
** Module to control static tables
*/
char *rcs_table="$Id: table.c,v 2.1 1994/04/20 22:07:57 celes Exp celes $";
#include <stdlib.h>
#include <string.h>
#include "mm.h"
char *rcs_table="$Id: table.c,v 2.57 1996/07/12 20:00:26 roberto Exp roberto $";
#include "mem.h"
#include "opcode.h"
#include "tree.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "inout.h"
#include "lua.h"
#include "fallback.h"
#include "luadebug.h"
#define streq(s1,s2) (s1[0]==s2[0]&&strcmp(s1+1,s2+1)==0)
#define BUFFER_BLOCK 256
Symbol *lua_table;
static Word lua_ntable = 0;
static Word lua_maxsymbol = 0;
Symbol *lua_table = NULL;
Word lua_ntable = 0;
static Long lua_maxsymbol = 0;
char **lua_constant;
static Word lua_nconstant = 0;
static Word lua_maxconstant = 0;
TaggedString **lua_constant = NULL;
Word lua_nconstant = 0;
static Long lua_maxconstant = 0;
#define GARBAGE_BLOCK 50
#define MAXFILE 20
char *lua_file[MAXFILE];
int lua_nfile;
/* Variables to controll garbage collection */
#define GARBAGE_BLOCK 256
Word lua_block=GARBAGE_BLOCK; /* when garbage collector will be called */
Word lua_nentity; /* counter of new entities (strings and arrays) */
static void lua_nextvar (void);
/*
** Initialise symbol table with internal functions
** Internal functions
*/
static void lua_initsymbol (void)
static struct {
char *name;
lua_CFunction func;
} int_funcs[] = {
{"assert", luaI_assert},
{"call", luaI_call},
{"dofile", lua_internaldofile},
{"dostring", lua_internaldostring},
{"error", luaI_error},
{"getglobal", luaI_getglobal},
{"next", lua_next},
{"nextvar", lua_nextvar},
{"print", luaI_print},
{"setfallback", luaI_setfallback},
{"setglobal", luaI_setglobal},
{"tonumber", lua_obj2number},
{"tostring", luaI_tostring},
{"type", luaI_type}
};
#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0]))
void luaI_initsymbol (void)
{
int n;
lua_maxsymbol = BUFFER_BLOCK;
lua_table = (Symbol *) calloc(lua_maxsymbol, sizeof(Symbol));
if (lua_table == NULL)
{
lua_error ("symbol table: not enough memory");
return;
}
n = lua_findsymbol("type");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_type;
n = lua_findsymbol("tonumber");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_obj2number;
n = lua_findsymbol("next");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_next;
n = lua_findsymbol("nextvar");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_nextvar;
n = lua_findsymbol("print");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_print;
n = lua_findsymbol("dofile");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_internaldofile;
n = lua_findsymbol("dostring");
s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_internaldostring;
int i;
Word n;
lua_maxsymbol = BUFFER_BLOCK;
lua_table = newvector(lua_maxsymbol, Symbol);
for (i=0; i<INTFUNCSIZE; i++)
{
n = luaI_findsymbolbyname(int_funcs[i].name);
s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func;
}
n = luaI_findsymbolbyname("_VERSION_");
s_tag(n) = LUA_T_STRING; s_tsvalue(n) = lua_createstring(LUA_VERSION);
}
/*
** Initialise constant table with pre-defined constants
*/
void lua_initconstant (void)
void luaI_initconstant (void)
{
lua_maxconstant = BUFFER_BLOCK;
lua_constant = (char **) calloc(lua_maxconstant, sizeof(char *));
if (lua_constant == NULL)
{
lua_error ("constant table: not enough memory");
return;
}
lua_findconstant("mark");
lua_findconstant("nil");
lua_findconstant("number");
lua_findconstant("string");
lua_findconstant("table");
lua_findconstant("function");
lua_findconstant("cfunction");
lua_findconstant("userdata");
lua_constant = newvector(lua_maxconstant, TaggedString *);
/* pre-register mem error messages, to avoid loop when error arises */
luaI_findconstantbyname(tableEM);
luaI_findconstantbyname(memEM);
}
/*
** Given a name, search it at symbol table and return its index. If not
** found, allocate it.
** On error, return -1.
*/
int lua_findsymbol (char *s)
Word luaI_findsymbol (TaggedString *t)
{
char *n;
if (lua_table == NULL)
lua_initsymbol();
n = lua_varcreate(s);
if (n == NULL)
{
lua_error ("create symbol: not enough memory");
return -1;
}
if (indexstring(n) == UNMARKED_STRING)
if (t->varindex == NOT_USED)
{
if (lua_ntable == lua_maxsymbol)
{
lua_maxsymbol *= 2;
if (lua_maxsymbol > MAX_WORD)
{
lua_error("symbol table overflow");
return -1;
}
lua_table = (Symbol *)realloc(lua_table, lua_maxsymbol*sizeof(Symbol));
if (lua_table == NULL)
{
lua_error ("symbol table: not enough memory");
return -1;
}
}
indexstring(n) = lua_ntable;
s_tag(lua_ntable) = T_NIL;
lua_maxsymbol = growvector(&lua_table, lua_maxsymbol, Symbol,
symbolEM, MAX_WORD);
t->varindex = lua_ntable;
lua_table[lua_ntable].varname = t;
s_tag(lua_ntable) = LUA_T_NIL;
lua_ntable++;
}
return indexstring(n);
return t->varindex;
}
Word luaI_findsymbolbyname (char *name)
{
return luaI_findsymbol(luaI_createfixedstring(name));
}
/*
** Given a name, search it at constant table and return its index. If not
** found, allocate it.
** On error, return -1.
** Given a tree node, check it is has a correspondent constant index. If not,
** allocate it.
*/
int lua_findconstant (char *s)
Word luaI_findconstant (TaggedString *t)
{
char *n;
if (lua_constant == NULL)
lua_initconstant();
n = lua_constcreate(s);
if (n == NULL)
{
lua_error ("create constant: not enough memory");
return -1;
}
if (indexstring(n) == UNMARKED_STRING)
if (t->constindex == NOT_USED)
{
if (lua_nconstant == lua_maxconstant)
{
lua_maxconstant *= 2;
if (lua_maxconstant > MAX_WORD)
{
lua_error("constant table overflow");
return -1;
}
lua_constant = (char**)realloc(lua_constant,lua_maxconstant*sizeof(char*));
if (lua_constant == NULL)
{
lua_error ("constant table: not enough memory");
return -1;
}
}
indexstring(n) = lua_nconstant;
lua_constant[lua_nconstant] = n;
lua_maxconstant = growvector(&lua_constant, lua_maxconstant, TaggedString *,
constantEM, MAX_WORD);
t->constindex = lua_nconstant;
lua_constant[lua_nconstant] = t;
lua_nconstant++;
}
return indexstring(n);
return t->constindex;
}
Word luaI_findconstantbyname (char *name)
{
return luaI_findconstant(luaI_createfixedstring(name));
}
TaggedString *luaI_createfixedstring (char *name)
{
TaggedString *ts = lua_createstring(name);
if (!ts->marked)
ts->marked = 2; /* avoid GC */
return ts;
}
/*
** Traverse symbol table objects
*/
void lua_travsymbol (void (*fn)(Object *))
static char *lua_travsymbol (int (*fn)(Object *))
{
int i;
Word i;
for (i=0; i<lua_ntable; i++)
fn(&s_object(i));
if (fn(&s_object(i)))
return lua_table[i].varname->str;
return NULL;
}
/*
** Mark an object if it is a string or a unmarked array.
*/
void lua_markobject (Object *o)
int lua_markobject (Object *o)
{/* if already marked, does not change mark value */
if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked)
tsvalue(o)->marked = 1;
else if (tag(o) == LUA_T_ARRAY)
lua_hashmark (avalue(o));
else if ((o->tag == LUA_T_FUNCTION || o->tag == LUA_T_MARK)
&& !o->value.tf->marked)
o->value.tf->marked = 1;
return 0;
}
/*
* returns 0 if the object is going to be (garbage) collected
*/
int luaI_ismarked (Object *o)
{
if (tag(o) == T_STRING && indexstring(svalue(o)) == UNMARKED_STRING)
indexstring(svalue(o)) = MARKED_STRING;
else if (tag(o) == T_ARRAY)
lua_hashmark (avalue(o));
switch (o->tag)
{
case LUA_T_STRING:
return o->value.ts->marked;
case LUA_T_FUNCTION:
return o->value.tf->marked;
case LUA_T_ARRAY:
return o->value.a->mark;
default: /* nil, number, cfunction, or user data */
return 1;
}
}
@@ -202,108 +196,83 @@ void lua_markobject (Object *o)
** Garbage collection.
** Delete all unused strings and arrays.
*/
Long luaI_collectgarbage (void)
{
Long recovered = 0;
lua_travstack(lua_markobject); /* mark stack objects */
lua_travsymbol(lua_markobject); /* mark symbol table objects */
luaI_travlock(lua_markobject); /* mark locked objects */
luaI_travfallbacks(lua_markobject); /* mark fallbacks */
luaI_invalidaterefs();
recovered += lua_strcollector();
recovered += lua_hashcollector();
recovered += luaI_funccollector();
return recovered;
}
void lua_pack (void)
{
/* mark stack strings */
lua_travstack(lua_markobject);
/* mark symbol table strings */
lua_travsymbol(lua_markobject);
lua_strcollector();
lua_hashcollector();
lua_nentity = 0; /* reset counter */
static unsigned long block = GARBAGE_BLOCK;
static unsigned long nentity = 0; /* total of strings, arrays, etc */
unsigned long recovered = 0;
if (nentity++ < block) return;
recovered = luaI_collectgarbage();
block = 2*(block-recovered);
nentity -= recovered;
}
/*
** If the string isn't allocated, allocate a new string at string tree.
*/
char *lua_createstring (char *s)
{
if (s == NULL) return NULL;
if (lua_nentity == lua_block)
lua_pack ();
lua_nentity++;
return lua_strcreate(s);
}
/*
** Add a file name at file table, checking overflow. This function also set
** the external variable "lua_filename" with the function filename set.
** Return 0 on success or 1 on error.
*/
int lua_addfile (char *fn)
{
if (lua_nfile >= MAXFILE-1)
{
lua_error ("too many files");
return 1;
}
if ((lua_file[lua_nfile++] = strdup (fn)) == NULL)
{
lua_error ("not enough memory");
return 1;
}
return 0;
}
/*
** Delete a file from file stack
*/
int lua_delfile (void)
{
lua_nfile--;
return 1;
}
/*
** Return the last file name set.
*/
char *lua_filename (void)
{
return lua_file[lua_nfile-1];
}
/*
** Internal function: return next global variable
*/
void lua_nextvar (void)
static void lua_nextvar (void)
{
char *varname, *next;
Object *o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `nextvar'"); return; }
if (lua_getparam (2) != NULL)
{ lua_error ("too many arguments to function `nextvar'"); return; }
if (tag(o) == T_NIL)
Word next;
lua_Object o = lua_getparam(1);
if (o == LUA_NOOBJECT)
lua_error("too few arguments to function `nextvar'");
if (lua_getparam(2) != LUA_NOOBJECT)
lua_error("too many arguments to function `nextvar'");
if (lua_isnil(o))
next = 0;
else if (!lua_isstring(o))
{
varname = 0;
}
else if (tag(o) != T_STRING)
{
lua_error ("incorrect argument to function `nextvar'");
return;
lua_error("incorrect argument to function `nextvar'");
return; /* to avoid warnings */
}
else
next = luaI_findsymbolbyname(lua_getstring(o)) + 1;
while (next < lua_ntable && s_tag(next) == LUA_T_NIL) next++;
if (next < lua_ntable)
{
varname = svalue(o);
}
next = lua_varnext(varname);
if (next == NULL)
{
lua_pushnil();
lua_pushnil();
}
else
{
Object name;
tag(&name) = T_STRING;
svalue(&name) = next;
if (lua_pushobject (&name)) return;
if (lua_pushobject (&s_object(indexstring(next)))) return;
lua_pushstring(lua_table[next].varname->str);
luaI_pushobject(&s_object(next));
}
}
static Object *functofind;
static int checkfunc (Object *o)
{
if (o->tag == LUA_T_FUNCTION)
return
((functofind->tag == LUA_T_FUNCTION || functofind->tag == LUA_T_MARK)
&& (functofind->value.tf == o->value.tf));
if (o->tag == LUA_T_CFUNCTION)
return
((functofind->tag == LUA_T_CFUNCTION || functofind->tag == LUA_T_CMARK)
&& (functofind->value.f == o->value.f));
return 0;
}
char *lua_getobjname (lua_Object o, char **name)
{ /* try to find a name for given function */
functofind = luaI_Address(o);
if ((*name = luaI_travfallbacks(checkfunc)) != NULL)
return "fallback";
else if ((*name = lua_travsymbol(checkfunc)) != NULL)
return "global";
else return "";
}

44
table.h
View File

@@ -1,32 +1,38 @@
/*
** Module to control static tables
** TeCGraf - PUC-Rio
** $Id: table.h,v 2.1 1994/04/20 22:07:57 celes Exp celes $
** $Id: table.h,v 2.20 1996/03/14 15:57:19 roberto Exp roberto $
*/
#ifndef table_h
#define table_h
#include "tree.h"
#include "opcode.h"
typedef struct
{
Object object;
TaggedString *varname;
} Symbol;
extern Symbol *lua_table;
extern char **lua_constant;
extern Word lua_ntable;
extern TaggedString **lua_constant;
extern Word lua_nconstant;
extern char *lua_file[];
extern int lua_nfile;
extern Word lua_block;
extern Word lua_nentity;
void lua_initconstant (void);
int lua_findsymbol (char *s);
int lua_findconstant (char *s);
void lua_travsymbol (void (*fn)(Object *));
void lua_markobject (Object *o);
void luaI_initsymbol (void);
void luaI_initconstant (void);
Word luaI_findsymbolbyname (char *name);
Word luaI_findsymbol (TaggedString *t);
Word luaI_findconstant (TaggedString *t);
Word luaI_findconstantbyname (char *name);
TaggedString *luaI_createfixedstring (char *str);
int lua_markobject (Object *o);
int luaI_ismarked (Object *o);
Long luaI_collectgarbage (void);
void lua_pack (void);
char *lua_createstring (char *s);
int lua_addfile (char *fn);
int lua_delfile (void);
char *lua_filename (void);
void lua_nextvar (void);
#endif

289
tree.c
View File

@@ -3,208 +3,143 @@
** TecCGraf - PUC-Rio
*/
char *rcs_tree="$Id: $";
char *rcs_tree="$Id: tree.c,v 1.19 1996/02/22 20:34:33 roberto Exp $";
#include <stdlib.h>
#include <string.h>
#include "mem.h"
#include "lua.h"
#include "tree.h"
#include "lex.h"
#include "hash.h"
#include "table.h"
#define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b)))
#define NUM_HASHS 64
typedef struct {
int size;
int nuse; /* number of elements (including EMPTYs) */
TaggedString **hash;
} stringtable;
static int initialized = 0;
static stringtable string_root[NUM_HASHS];
static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 2, {0}};
typedef struct TreeNode
static unsigned long hash (char *str)
{
struct TreeNode *right;
struct TreeNode *left;
Word index;
char str[1]; /* \0 byte already reserved */
} TreeNode;
unsigned long h = 0;
while (*str)
h = ((h<<5)-h)^(unsigned char)*(str++);
return h;
}
static TreeNode *string_root = NULL;
static TreeNode *constant_root = NULL;
static TreeNode *variable_root = NULL;
/*
** Insert a new string/constant/variable at the tree.
*/
static char *tree_create (TreeNode **node, char *str)
static void initialize (void)
{
if (*node == NULL)
{
*node = (TreeNode *) malloc (sizeof(TreeNode)+strlen(str));
if (*node == NULL)
lua_error ("memoria insuficiente\n");
(*node)->left = (*node)->right = NULL;
strcpy((*node)->str, str);
(*node)->index = UNMARKED_STRING;
return (*node)->str;
}
else
{
int c = lua_strcmp(str, (*node)->str);
if (c < 0)
return tree_create(&(*node)->left, str);
else if (c > 0)
return tree_create(&(*node)->right, str);
initialized = 1;
luaI_addReserved();
luaI_initsymbol();
luaI_initconstant();
}
static void grow (stringtable *tb)
{
int newsize = luaI_redimension(tb->size);
TaggedString **newhash = newvector(newsize, TaggedString *);
int i;
for (i=0; i<newsize; i++)
newhash[i] = NULL;
/* rehash */
tb->nuse = 0;
for (i=0; i<tb->size; i++)
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
{
int h = tb->hash[i]->hash%newsize;
while (newhash[h])
h = (h+1)%newsize;
newhash[h] = tb->hash[i];
tb->nuse++;
}
luaI_free(tb->hash);
tb->size = newsize;
tb->hash = newhash;
}
static TaggedString *insert (char *str, stringtable *tb)
{
TaggedString *ts;
unsigned long h = hash(str);
int i;
int j = -1;
if ((Long)tb->nuse*3 >= (Long)tb->size*2)
{
if (!initialized)
initialize();
grow(tb);
}
i = h%tb->size;
while (tb->hash[i])
{
if (tb->hash[i] == &EMPTY)
j = i;
else if (strcmp(str, tb->hash[i]->str) == 0)
return tb->hash[i];
i = (i+1)%tb->size;
}
/* not found */
lua_pack();
if (j != -1) /* is there an EMPTY space? */
i = j;
else
return (*node)->str;
}
tb->nuse++;
ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(str));
strcpy(ts->str, str);
ts->marked = 0;
ts->hash = h;
ts->varindex = ts->constindex = NOT_USED;
return ts;
}
char *lua_strcreate (char *str)
TaggedString *lua_createstring (char *str)
{
return tree_create(&string_root, str);
}
char *lua_constcreate (char *str)
{
return tree_create(&constant_root, str);
}
char *lua_varcreate (char *str)
{
return tree_create(&variable_root, str);
}
/*
** Free a node of the tree
*/
static TreeNode *lua_strfree (TreeNode *parent)
{
if (parent->left == NULL && parent->right == NULL) /* no child */
{
free (parent);
return NULL;
}
else if (parent->left == NULL) /* only right child */
{
TreeNode *p = parent->right;
free (parent);
return p;
}
else if (parent->right == NULL) /* only left child */
{
TreeNode *p = parent->left;
free (parent);
return p;
}
else /* two children */
{
TreeNode *p = parent, *r = parent->right;
while (r->left != NULL)
{
p = r;
r = r->left;
}
if (p == parent)
{
r->left = parent->left;
parent->left = NULL;
parent->right = r->right;
r->right = lua_strfree(parent);
}
else
{
TreeNode *t = r->right;
r->left = parent->left;
r->right = parent->right;
parent->left = NULL;
parent->right = t;
p->left = lua_strfree(parent);
}
return r;
}
}
/*
** Traverse tree for garbage collection
*/
static TreeNode *lua_travcollector (TreeNode *r)
{
if (r == NULL) return NULL;
r->right = lua_travcollector(r->right);
r->left = lua_travcollector(r->left);
if (r->index == UNMARKED_STRING)
return lua_strfree(r);
else
{
r->index = UNMARKED_STRING;
return r;
}
return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]);
}
/*
** Garbage collection function.
** This function traverse the tree freening unindexed strings
** This function traverse the string list freeing unindexed strings
*/
void lua_strcollector (void)
Long lua_strcollector (void)
{
string_root = lua_travcollector(string_root);
}
/*
** Return next variable.
*/
static TreeNode *tree_next (TreeNode *node, char *str)
{
#if 0
if (node == NULL) return NULL;
if (str == NULL || lua_strcmp(str, node->str) < 0)
{
TreeNode *result = tree_next(node->left, str);
return result == NULL ? node : result;
}
else
{
return tree_next(node->right, str);
}
#else
if (node == NULL) return NULL;
else if (str == NULL) return node;
else
{
int c = lua_strcmp(str, node->str);
if (c == 0)
return node->left != NULL ? node->left : node->right;
else if (c < 0)
Long counter = 0;
int i;
for (i=0; i<NUM_HASHS; i++)
{
TreeNode *result = tree_next(node->left, str);
return result != NULL ? result : node->right;
stringtable *tb = &string_root[i];
int j;
for (j=0; j<tb->size; j++)
{
TaggedString *t = tb->hash[j];
if (t != NULL && t->marked <= 1)
{
if (t->marked)
t->marked = 0;
else
{
luaI_free(t);
tb->hash[j] = &EMPTY;
counter++;
}
}
}
}
else
return tree_next(node->right, str);
}
#endif
return counter;
}
char *lua_varnext (char *n)
{
TreeNode *result = tree_next(variable_root, n);
return result != NULL ? result->str : NULL;
}
/*
** Given an id, find the string with exaustive search
*/
static char *tree_name (TreeNode *node, Word index)
{
if (node == NULL) return NULL;
if (node->index == index) return node->str;
else
{
char *result = tree_name(node->left, index);
return result != NULL ? result : tree_name(node->right, index);
}
}
char *lua_varname (Word index)
{
return tree_name(variable_root, index);
}

29
tree.h
View File

@@ -1,27 +1,28 @@
/*
** tree.h
** TecCGraf - PUC-Rio
** $Id: $
** $Id: tree.h,v 1.13 1996/02/14 13:35:51 roberto Exp roberto $
*/
#ifndef tree_h
#define tree_h
#include "opcode.h"
#include "types.h"
#define NOT_USED 0xFFFE
#define UNMARKED_STRING 0xFFFF
#define MARKED_STRING 0xFFFE
#define MAX_WORD 0xFFFD
typedef struct TaggedString
{
Word varindex; /* != NOT_USED if this is a symbol */
Word constindex; /* != NOT_USED if this is a constant */
unsigned long hash; /* 0 if not initialized */
int marked; /* for garbage collection; never collect (nor change) if > 1 */
char str[1]; /* \0 byte already reserved */
} TaggedString;
#define indexstring(s) (*(((Word *)s)-1))
char *lua_strcreate (char *str);
char *lua_constcreate (char *str);
char *lua_varcreate (char *str);
void lua_strcollector (void);
char *lua_varnext (char *n);
char *lua_varname (Word index);
TaggedString *lua_createstring (char *str);
Long lua_strcollector (void);
#endif

29
types.h Normal file
View File

@@ -0,0 +1,29 @@
/*
** TeCGraf - PUC-Rio
** $Id: types.h,v 1.3 1995/02/06 19:32:43 roberto Exp roberto $
*/
#ifndef types_h
#define types_h
#include <limits.h>
#ifndef real
#define real float
#endif
#define Byte lua_Byte /* some systems have Byte as a predefined type */
typedef unsigned char Byte; /* unsigned 8 bits */
#define Word lua_Word /* some systems have Word as a predefined type */
typedef unsigned short Word; /* unsigned 16 bits */
#define MAX_WORD (USHRT_MAX-2) /* maximum value of a word (-2 for safety) */
#define MAX_INT (INT_MAX-2) /* maximum value of a int (-2 for safety) */
#define Long lua_Long /* some systems have Long as a predefined type */
typedef signed long Long; /* 32 bits */
typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */
#endif

333
undump.c Normal file
View File

@@ -0,0 +1,333 @@
/*
** undump.c
** load bytecodes from files
*/
char* rcs_undump="$Id: undump.c,v 1.20 1996/11/16 20:14:23 lhf Exp lhf $";
#include <stdio.h>
#include <string.h>
#include "opcode.h"
#include "mem.h"
#include "table.h"
#include "undump.h"
static int swapword=0;
static int swapfloat=0;
static TFunc* Main=NULL; /* functions in a chunk */
static TFunc* lastF=NULL;
static void warn(char* s) /* TODO: remove */
{
#if 0
fprintf(stderr,"undump: %s\n",s);
#endif
}
static void FixCode(Byte* code, Byte* end) /* swap words */
{
Byte* p;
for (p=code; p!=end;)
{
OpCode op=(OpCode)*p;
switch (op)
{
case PUSHNIL:
case PUSH0:
case PUSH1:
case PUSH2:
case PUSHLOCAL0:
case PUSHLOCAL1:
case PUSHLOCAL2:
case PUSHLOCAL3:
case PUSHLOCAL4:
case PUSHLOCAL5:
case PUSHLOCAL6:
case PUSHLOCAL7:
case PUSHLOCAL8:
case PUSHLOCAL9:
case PUSHINDEXED:
case STORELOCAL0:
case STORELOCAL1:
case STORELOCAL2:
case STORELOCAL3:
case STORELOCAL4:
case STORELOCAL5:
case STORELOCAL6:
case STORELOCAL7:
case STORELOCAL8:
case STORELOCAL9:
case STOREINDEXED0:
case ADJUST0:
case EQOP:
case LTOP:
case LEOP:
case GTOP:
case GEOP:
case ADDOP:
case SUBOP:
case MULTOP:
case DIVOP:
case POWOP:
case CONCOP:
case MINUSOP:
case NOTOP:
case POP:
case RETCODE0:
p++;
break;
case PUSHBYTE:
case PUSHLOCAL:
case STORELOCAL:
case STOREINDEXED:
case STORELIST0:
case ADJUST:
case RETCODE:
p+=2;
break;
case STORELIST:
case CALLFUNC:
p+=3;
break;
case PUSHFUNCTION:
p+=5; /* TODO: use sizeof(TFunc*) or old? */
break;
case PUSHWORD:
case PUSHSELF:
case CREATEARRAY:
case ONTJMP:
case ONFJMP:
case JMP:
case UPJMP:
case IFFJMP:
case IFFUPJMP:
case SETLINE:
case PUSHSTRING:
case PUSHGLOBAL:
case STOREGLOBAL:
{
Byte t;
t=p[1]; p[1]=p[2]; p[2]=t;
p+=3;
break;
}
case PUSHFLOAT: /* assumes sizeof(float)==4 */
{
Byte t;
t=p[1]; p[1]=p[4]; p[4]=t;
t=p[2]; p[2]=p[3]; p[3]=t;
p+=5;
break;
}
case STORERECORD:
{
int n=*++p;
p++;
while (n--)
{
Byte t;
t=p[0]; p[0]=p[1]; p[1]=t;
p+=2;
}
break;
}
default:
lua_error("corrupt binary file");
break;
}
}
}
static void Unthread(Byte* code, int i, int v)
{
while (i!=0)
{
Word w;
Byte* p=code+i;
memcpy(&w,p,sizeof(w));
i=w; w=v;
memcpy(p,&w,sizeof(w));
}
}
static int LoadWord(FILE* D)
{
Word w;
fread(&w,sizeof(w),1,D);
if (swapword)
{
Byte* p=(Byte*)&w; /* TODO: need union? */
Byte t;
t=p[0]; p[0]=p[1]; p[1]=t;
}
return w;
}
static int LoadSize(FILE* D)
{
Word hi=LoadWord(D);
Word lo=LoadWord(D);
int s=(hi<<16)|lo;
if ((Word)s != s) lua_error("code too long");
return s;
}
static void* LoadBlock(int size, FILE* D)
{
void* b=luaI_malloc(size);
fread(b,size,1,D);
return b;
}
static char* LoadString(FILE* D)
{
int size=LoadWord(D);
char *b=luaI_buffer(size);
fread(b,size,1,D);
return b;
}
static char* LoadNewString(FILE* D)
{
return LoadBlock(LoadWord(D),D);
}
static void LoadFunction(FILE* D)
{
TFunc* tf=new(TFunc);
tf->next=NULL;
tf->locvars=NULL;
tf->size=LoadSize(D);
tf->lineDefined=LoadWord(D);
if (IsMain(tf)) /* new main */
{
tf->fileName=LoadNewString(D);
Main=lastF=tf;
}
else /* fix PUSHFUNCTION */
{
tf->marked=LoadWord(D);
tf->fileName=Main->fileName;
memcpy(Main->code+tf->marked,&tf,sizeof(tf));
lastF=lastF->next=tf;
}
tf->code=LoadBlock(tf->size,D);
if (swapword || swapfloat) FixCode(tf->code,tf->code+tf->size);
while (1) /* unthread */
{
int c=getc(D);
if (c==ID_VAR) /* global var */
{
int i=LoadWord(D);
char* s=LoadString(D);
int v=luaI_findsymbolbyname(s);
Unthread(tf->code,i,v);
}
else if (c==ID_STR) /* constant string */
{
int i=LoadWord(D);
char* s=LoadString(D);
int v=luaI_findconstantbyname(s);
Unthread(tf->code,i,v);
}
else
{
ungetc(c,D);
break;
}
}
}
static void LoadSignature(FILE* D)
{
char* s=SIGNATURE;
while (*s!=0 && getc(D)==*s)
++s;
if (*s!=0) lua_error("bad signature");
}
static void LoadHeader(FILE* D) /* TODO: error handling */
{
Word w,tw=TEST_WORD;
float f,tf=TEST_FLOAT;
int version;
LoadSignature(D);
version=getc(D);
if (version>0x23) /* after 2.5 */
{
int oldsizeofW=getc(D);
int oldsizeofF=getc(D);
int oldsizeofP=getc(D);
if (oldsizeofW!=2)
lua_error("cannot load binary file created on machine with sizeof(Word)!=2");
if (oldsizeofF!=4)
lua_error("cannot load binary file created on machine with sizeof(float)!=4. not an IEEE machine?");
if (oldsizeofP!=sizeof(TFunc*)) /* TODO: pack */
lua_error("cannot load binary file: different pointer sizes");
}
fread(&w,sizeof(w),1,D); /* test word */
if (w!=tw)
{
swapword=1;
warn("different byte order");
}
fread(&f,sizeof(f),1,D); /* test float */
if (f!=tf)
{
Byte* p=(Byte*)&f; /* TODO: need union? */
Byte t;
swapfloat=1;
t=p[0]; p[0]=p[3]; p[3]=t;
t=p[1]; p[1]=p[2]; p[2]=t;
if (f!=tf) /* TODO: try another perm? */
lua_error("different float representation");
else
warn("different byte order in floats");
}
}
static void LoadChunk(FILE* D)
{
LoadHeader(D);
while (1)
{
int c=getc(D);
if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; }
}
}
/*
** load one chunk from a file.
** return list of functions found, headed by main, or NULL at EOF.
*/
TFunc* luaI_undump1(FILE* D)
{
while (1)
{
int c=getc(D);
if (c==ID_CHUNK)
{
LoadChunk(D);
return Main;
}
else if (c==EOF)
return NULL;
else
lua_error("not a lua binary file");
}
}
/*
** load and run all chunks in a file
*/
int luaI_undump(FILE* D)
{
TFunc* m;
while ((m=luaI_undump1(D)))
{
int status=luaI_dorun(m);
luaI_freefunc(m);
if (status!=0) return status;
}
return 0;
}

23
undump.h Normal file
View File

@@ -0,0 +1,23 @@
/*
** undump.h
** definitions for lua decompiler
** $Id: undump.h,v 1.2 1996/03/11 21:59:41 lhf Exp lhf $
*/
#include "func.h"
#define IsMain(f) (f->lineDefined==0)
/* definitions for chunk headers */
#define ID_CHUNK 27 /* ESC */
#define ID_FUN 'F'
#define ID_VAR 'V'
#define ID_STR 'S'
#define SIGNATURE "Lua"
#define VERSION 0x25 /* 2.5 */
#define TEST_WORD 0x1234 /* a word for testing byte ordering */
#define TEST_FLOAT 0.123456789e-23 /* a float for testing representation */
TFunc* luaI_undump1(FILE* D); /* load one chunk */
int luaI_undump(FILE* D); /* load all chunks */