Compare commits

...

54 Commits
v2.1 ... v2.2

Author SHA1 Message Date
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
24 changed files with 3141 additions and 1219 deletions

View File

@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio ** TecCGraf - PUC-Rio
*/ */
char *rcs_fallback="$Id: fallback.c,v 1.10 1994/12/20 21:20:36 roberto Exp $"; char *rcs_fallback="$Id: fallback.c,v 1.16 1995/10/17 11:52:38 roberto Exp roberto $";
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -11,7 +11,6 @@ char *rcs_fallback="$Id: fallback.c,v 1.10 1994/12/20 21:20:36 roberto Exp $";
#include "mem.h" #include "mem.h"
#include "fallback.h" #include "fallback.h"
#include "opcode.h" #include "opcode.h"
#include "inout.h"
#include "lua.h" #include "lua.h"
@@ -29,15 +28,16 @@ static void funcFB (void);
** Warning: This list must be in the same order as the #define's ** Warning: This list must be in the same order as the #define's
*/ */
struct FB luaI_fallBacks[] = { struct FB luaI_fallBacks[] = {
{"error", {LUA_T_CFUNCTION, errorFB}}, {"error", {LUA_T_CFUNCTION, {errorFB}}, 1, 0},
{"index", {LUA_T_CFUNCTION, indexFB}}, {"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1},
{"gettable", {LUA_T_CFUNCTION, gettableFB}}, {"gettable", {LUA_T_CFUNCTION, {gettableFB}}, 2, 1},
{"arith", {LUA_T_CFUNCTION, arithFB}}, {"arith", {LUA_T_CFUNCTION, {arithFB}}, 3, 1},
{"order", {LUA_T_CFUNCTION, orderFB}}, {"order", {LUA_T_CFUNCTION, {orderFB}}, 3, 1},
{"concat", {LUA_T_CFUNCTION, concatFB}}, {"concat", {LUA_T_CFUNCTION, {concatFB}}, 2, 1},
{"settable", {LUA_T_CFUNCTION, gettableFB}}, {"settable", {LUA_T_CFUNCTION, {gettableFB}}, 3, 0},
{"gc", {LUA_T_CFUNCTION, GDFB}}, {"gc", {LUA_T_CFUNCTION, {GDFB}}, 1, 0},
{"function", {LUA_T_CFUNCTION, funcFB}} {"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1}
/* no fixed number of params or results */
}; };
#define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB)) #define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB))
@@ -48,10 +48,7 @@ void luaI_setfallback (void)
char *name = lua_getstring(lua_getparam(1)); char *name = lua_getstring(lua_getparam(1));
lua_Object func = lua_getparam(2); lua_Object func = lua_getparam(2);
if (name == NULL || !(lua_isfunction(func) || lua_iscfunction(func))) if (name == NULL || !(lua_isfunction(func) || lua_iscfunction(func)))
{ lua_error("incorrect argument to function `setfallback'");
lua_pushnil();
return;
}
for (i=0; i<N_FB; i++) for (i=0; i<N_FB; i++)
{ {
if (strcmp(luaI_fallBacks[i].kind, name) == 0) if (strcmp(luaI_fallBacks[i].kind, name) == 0)
@@ -62,7 +59,7 @@ void luaI_setfallback (void)
} }
} }
/* name not found */ /* name not found */
lua_pushnil(); lua_error("incorrect argument to function `setfallback'");
} }
@@ -84,31 +81,31 @@ static void indexFB (void)
static void gettableFB (void) static void gettableFB (void)
{ {
lua_reportbug("indexed expression not a table"); lua_error("indexed expression not a table");
} }
static void arithFB (void) static void arithFB (void)
{ {
lua_reportbug("unexpected type at conversion to number"); lua_error("unexpected type at conversion to number");
} }
static void concatFB (void) static void concatFB (void)
{ {
lua_reportbug("unexpected type at conversion to string"); lua_error("unexpected type at conversion to string");
} }
static void orderFB (void) static void orderFB (void)
{ {
lua_reportbug("unexpected type at comparison"); lua_error("unexpected type at comparison");
} }
static void GDFB (void) { } static void GDFB (void) { }
static void funcFB (void) static void funcFB (void)
{ {
lua_reportbug("call expression not a function"); lua_error("call expression not a function");
} }
@@ -162,10 +159,19 @@ Object *luaI_getlocked (int ref)
} }
void luaI_travlock (void (*fn)(Object *)) void luaI_travlock (int (*fn)(Object *))
{ {
Word i; Word i;
for (i=0; i<lockSize; i++) for (i=0; i<lockSize; i++)
fn(&lockArray[i]); fn(&lockArray[i]);
} }
char *luaI_travfallbacks (int (*fn)(Object *))
{
Word i;
for (i=0; i<N_FB; i++)
if (fn(&luaI_fallBacks[i].function))
return luaI_fallBacks[i].kind;
return NULL;
}

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: fallback.h,v 1.6 1994/11/21 13:30:15 roberto Exp roberto $ ** $Id: fallback.h,v 1.9 1995/10/09 13:14:29 roberto Exp roberto $
*/ */
#ifndef fallback_h #ifndef fallback_h
@@ -10,6 +10,8 @@
extern struct FB { extern struct FB {
char *kind; char *kind;
Object function; Object function;
int nParams;
int nResults;
} luaI_fallBacks[]; } luaI_fallBacks[];
#define FB_ERROR 0 #define FB_ERROR 0
@@ -25,7 +27,8 @@ extern struct FB {
void luaI_setfallback (void); void luaI_setfallback (void);
int luaI_lock (Object *object); int luaI_lock (Object *object);
Object *luaI_getlocked (int ref); Object *luaI_getlocked (int ref);
void luaI_travlock (void (*fn)(Object *)); void luaI_travlock (int (*fn)(Object *));
char *luaI_travfallbacks (int (*fn)(Object *));
#endif #endif

79
func.c Normal file
View File

@@ -0,0 +1,79 @@
#include <stdio.h>
#include "luadebug.h"
#include "table.h"
#include "mem.h"
#include "func.h"
#include "opcode.h"
static TFunc *function_root = 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
*/
static void freefunc (TFunc *f)
{
luaI_free (f->code);
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;
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;
}
}

24
func.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef func_h
#define func_h
#include "types.h"
#include "lua.h"
/*
** Header para funcoes.
*/
typedef struct TFunc
{
struct TFunc *next;
char marked;
int size;
Byte *code;
int lineDefined;
char *fileName;
} TFunc;
Long luaI_funccollector (void);
void luaI_insertfunction (TFunc *f);
#endif

9
hash.c
View File

@@ -3,14 +3,13 @@
** hash manager for lua ** hash manager for lua
*/ */
char *rcs_hash="$Id: hash.c,v 2.23 1995/01/12 14:19:04 roberto Exp $"; char *rcs_hash="$Id: hash.c,v 2.25 1995/05/02 18:43:03 roberto Exp $";
#include <string.h> #include <string.h>
#include "mem.h" #include "mem.h"
#include "opcode.h" #include "opcode.h"
#include "hash.h" #include "hash.h"
#include "inout.h"
#include "table.h" #include "table.h"
#include "lua.h" #include "lua.h"
@@ -54,7 +53,7 @@ static Word hashindex (Hash *t, Object *ref) /* hash function */
switch (tag(ref)) switch (tag(ref))
{ {
case LUA_T_NIL: case LUA_T_NIL:
lua_reportbug ("unexpected type to index table"); lua_error ("unexpected type to index table");
return -1; /* UNREACHEABLE */ return -1; /* UNREACHEABLE */
case LUA_T_NUMBER: case LUA_T_NUMBER:
return (((Word)nvalue(ref))%nhash(t)); return (((Word)nvalue(ref))%nhash(t));
@@ -71,7 +70,7 @@ static Word hashindex (Hash *t, Object *ref) /* hash function */
return (Word)h%nhash(t); /* make it a valid index */ return (Word)h%nhash(t); /* make it a valid index */
} }
case LUA_T_FUNCTION: case LUA_T_FUNCTION:
return (((IntPoint)bvalue(ref))%nhash(t)); return (((IntPoint)ref->value.tf)%nhash(t));
case LUA_T_CFUNCTION: case LUA_T_CFUNCTION:
return (((IntPoint)fvalue(ref))%nhash(t)); return (((IntPoint)fvalue(ref))%nhash(t));
case LUA_T_ARRAY: case LUA_T_ARRAY:
@@ -90,7 +89,7 @@ Bool lua_equalObj (Object *t1, Object *t2)
case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
case LUA_T_STRING: return streq(svalue(t1), svalue(t2)); case LUA_T_STRING: return streq(svalue(t1), svalue(t2));
case LUA_T_ARRAY: return avalue(t1) == avalue(t2); case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
case LUA_T_FUNCTION: return bvalue(t1) == bvalue(t2); case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf;
case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2); case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2);
default: return uvalue(t1) == uvalue(t2); default: return uvalue(t1) == uvalue(t2);
} }

140
inout.c
View File

@@ -5,7 +5,7 @@
** Also provides some predefined lua functions. ** Also provides some predefined lua functions.
*/ */
char *rcs_inout="$Id: inout.c,v 2.15 1994/12/16 15:55:04 roberto Exp roberto $"; char *rcs_inout="$Id: inout.c,v 2.24 1995/10/23 13:54:11 roberto Exp roberto $";
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -19,27 +19,19 @@ char *rcs_inout="$Id: inout.c,v 2.15 1994/12/16 15:55:04 roberto Exp roberto $";
#include "tree.h" #include "tree.h"
#include "lua.h" #include "lua.h"
/* Exported variables */
Word lua_linenumber;
Bool lua_debug;
Word lua_debugline = 0;
/* Internal variables */
#ifndef MAXFUNCSTACK #ifndef MAXFUNCSTACK
#define MAXFUNCSTACK 100 #define MAXFUNCSTACK 100
#endif #endif
typedef struct FuncStackNode { #define MAXMESSAGE MAXFUNCSTACK*80
struct FuncStackNode *next;
char *file;
Word function; /* Exported variables */
Word line; Word lua_linenumber;
} FuncStackNode; Bool lua_debug = 0;
char *lua_parsedfile;
static FuncStackNode *funcStack = NULL;
static Word nfuncstack=0;
static FILE *fp; static FILE *fp;
static char *st; static char *st;
@@ -66,16 +58,23 @@ static int stringinput (void)
*/ */
char *lua_openfile (char *fn) char *lua_openfile (char *fn)
{ {
lua_linenumber = 1;
lua_setinput (fileinput); lua_setinput (fileinput);
fp = fopen (fn, "r"); if (fn == NULL)
{
fp = stdin;
fn = "(stdin)";
}
else
fp = fopen (fn, "r");
if (fp == NULL) if (fp == NULL)
{ {
static char buff[32]; static char buff[255];
sprintf(buff, "unable to open file %.10s", fn); sprintf(buff, "unable to open file `%.200s'", fn);
return buff; return buff;
} }
return lua_addfile (fn); lua_linenumber = 1;
lua_parsedfile = lua_constcreate(fn)->ts.str;
return NULL;
} }
/* /*
@@ -83,9 +82,8 @@ char *lua_openfile (char *fn)
*/ */
void lua_closefile (void) void lua_closefile (void)
{ {
if (fp != NULL) if (fp != NULL && fp != stdin)
{ {
lua_delfile();
fclose (fp); fclose (fp);
fp = NULL; fp = NULL;
} }
@@ -94,16 +92,12 @@ void lua_closefile (void)
/* /*
** Function to open a string to be input unit ** Function to open a string to be input unit
*/ */
char *lua_openstring (char *s) void lua_openstring (char *s)
{ {
lua_linenumber = 1;
lua_setinput (stringinput); lua_setinput (stringinput);
st = s; st = s;
{ lua_linenumber = 1;
char sn[64]; lua_parsedfile = lua_constcreate("(string)")->ts.str;
sprintf (sn, "String: %10.10s...", s);
return lua_addfile (sn);
}
} }
/* /*
@@ -111,75 +105,6 @@ char *lua_openstring (char *s)
*/ */
void lua_closestring (void) void lua_closestring (void)
{ {
lua_delfile();
}
/*
** Called to execute SETFUNCTION opcode, this function pushs a function into
** function stack.
*/
void lua_pushfunction (char *file, Word function)
{
FuncStackNode *newNode;
if (nfuncstack++ >= MAXFUNCSTACK)
{
lua_reportbug("function stack overflow");
}
newNode = new(FuncStackNode);
newNode->function = function;
newNode->file = file;
newNode->line= lua_debugline;
newNode->next = funcStack;
funcStack = newNode;
}
/*
** Called to execute RESET opcode, this function pops a function from
** function stack.
*/
void lua_popfunction (void)
{
FuncStackNode *temp = funcStack;
if (temp == NULL) return;
--nfuncstack;
lua_debugline = temp->line;
funcStack = temp->next;
luaI_free(temp);
}
/*
** Report bug building a message and sending it to lua_error function.
*/
void lua_reportbug (char *s)
{
char msg[MAXFUNCSTACK*80];
strcpy (msg, s);
if (lua_debugline != 0)
{
if (funcStack)
{
FuncStackNode *func = funcStack;
int line = lua_debugline;
sprintf (strchr(msg,0), "\n\tactive stack:\n");
do
{
sprintf (strchr(msg,0),
"\t-> function \"%s\" at file \"%s\":%u\n",
lua_constant[func->function]->str, func->file, line);
line = func->line;
func = func->next;
lua_popfunction();
} while (func);
}
else
{
sprintf (strchr(msg,0),
"\n\tin statement begining at line %u of file \"%s\"",
lua_debugline, lua_filename());
}
}
lua_error (msg);
} }
@@ -218,7 +143,7 @@ void lua_print (void)
{ {
if (lua_isnumber(obj)) printf("%g\n",lua_getnumber(obj)); if (lua_isnumber(obj)) printf("%g\n",lua_getnumber(obj));
else if (lua_isstring(obj)) printf("%s\n",lua_getstring(obj)); else if (lua_isstring(obj)) printf("%s\n",lua_getstring(obj));
else if (lua_isfunction(obj)) printf("function: %p\n",bvalue(luaI_Address(obj))); else if (lua_isfunction(obj)) printf("function: %p\n",(luaI_Address(obj))->value.tf);
else if (lua_iscfunction(obj)) printf("cfunction: %p\n",lua_getcfunction(obj) else if (lua_iscfunction(obj)) printf("cfunction: %p\n",lua_getcfunction(obj)
); );
else if (lua_isuserdata(obj)) printf("userdata: %p\n",lua_getuserdata(obj)); else if (lua_isuserdata(obj)) printf("userdata: %p\n",lua_getuserdata(obj));
@@ -235,9 +160,11 @@ void lua_print (void)
void luaI_type (void) void luaI_type (void)
{ {
lua_Object o = lua_getparam(1); lua_Object o = lua_getparam(1);
int t;
if (o == LUA_NOOBJECT) if (o == LUA_NOOBJECT)
lua_error("no parameter to function 'type'"); lua_error("no parameter to function 'type'");
switch (lua_type(o)) t = lua_type(o);
switch (t)
{ {
case LUA_T_NIL : case LUA_T_NIL :
lua_pushliteral("nil"); lua_pushliteral("nil");
@@ -252,15 +179,14 @@ void luaI_type (void)
lua_pushliteral("table"); lua_pushliteral("table");
break; break;
case LUA_T_FUNCTION : case LUA_T_FUNCTION :
lua_pushliteral("function");
break;
case LUA_T_CFUNCTION : case LUA_T_CFUNCTION :
lua_pushliteral("cfunction"); lua_pushliteral("function");
break; break;
default : default :
lua_pushliteral("userdata"); lua_pushliteral("userdata");
break; break;
} }
lua_pushnumber(t);
} }
/* /*
@@ -289,6 +215,6 @@ void luaI_error (void)
{ {
char *s = lua_getstring(lua_getparam(1)); char *s = lua_getstring(lua_getparam(1));
if (s == NULL) s = "(no message)"; if (s == NULL) s = "(no message)";
lua_reportbug(s); lua_error(s);
} }

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: inout.h,v 1.6 1994/11/21 21:41:09 roberto Stab roberto $ ** $Id: inout.h,v 1.9 1995/05/16 17:23:58 roberto Exp roberto $
*/ */
@@ -8,17 +8,16 @@
#include "types.h" #include "types.h"
extern Word lua_linenumber; extern Word lua_linenumber;
extern Bool lua_debug; extern Bool lua_debug;
extern Word lua_debugline; extern Word lua_debugline;
extern char *lua_parsedfile;
char *lua_openfile (char *fn); char *lua_openfile (char *fn);
void lua_closefile (void); void lua_closefile (void);
char *lua_openstring (char *s); void lua_openstring (char *s);
void lua_closestring (void); void lua_closestring (void);
void lua_pushfunction (char *file, Word function);
void lua_popfunction (void);
void lua_reportbug (char *s);
void lua_internaldofile (void); void lua_internaldofile (void);
void lua_internaldostring (void); void lua_internaldostring (void);

713
iolib.c
View File

@@ -3,7 +3,7 @@
** Input/output library to LUA ** Input/output library to LUA
*/ */
char *rcs_iolib="$Id: iolib.c,v 1.20 1995/02/02 18:54:58 roberto Exp roberto $"; char *rcs_iolib="$Id: iolib.c,v 1.28 1995/11/10 17:55:48 roberto Exp roberto $";
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
@@ -14,51 +14,68 @@ char *rcs_iolib="$Id: iolib.c,v 1.20 1995/02/02 18:54:58 roberto Exp roberto $";
#include <stdlib.h> #include <stdlib.h>
#include "lua.h" #include "lua.h"
#include "luadebug.h"
#include "lualib.h" #include "lualib.h"
static FILE *in=stdin, *out=stdout; static FILE *in=stdin, *out=stdout;
#ifdef POPEN
FILE *popen();
int pclose();
#else
#define popen(x,y) NULL /* that is, popen always fails */
#define pclose(x) (-1)
#endif
static void closeread (void)
{
if (in != stdin)
{
if (pclose(in) == -1)
fclose(in);
in = stdin;
}
}
static void closewrite (void)
{
if (out != stdout)
{
if (pclose(out) == -1)
fclose(out);
out = stdout;
}
}
/* /*
** Open a file to read. ** Open a file to read.
** LUA interface: ** LUA interface:
** status = readfrom (filename) ** status = readfrom (filename)
** where: ** where:
** status = 1 -> success ** status = 1 -> success
** status = 0 -> error ** status = nil -> error
*/ */
static void io_readfrom (void) static void io_readfrom (void)
{ {
lua_Object o = lua_getparam (1); if (lua_getparam (1) == LUA_NOOBJECT)
if (o == LUA_NOOBJECT) /* restore standart input */ { /* restore standart input */
{ closeread();
if (in != stdin)
{
fclose (in);
in = stdin;
}
lua_pushnumber (1); lua_pushnumber (1);
} }
else else
{ {
if (!lua_isstring (o)) char *s = lua_check_string(1, "readfrom");
{ FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
lua_error ("incorrect argument to function 'readfrom`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"r");
if (fp == NULL) if (fp == NULL)
{ lua_pushnil();
lua_pushnumber (0);
}
else else
{ {
if (in != stdin) fclose (in); closeread();
in = fp; in = fp;
lua_pushnumber (1); lua_pushnumber (1);
} }
}
} }
} }
@@ -69,41 +86,27 @@ static void io_readfrom (void)
** status = writeto (filename) ** status = writeto (filename)
** where: ** where:
** status = 1 -> success ** status = 1 -> success
** status = 0 -> error ** status = nil -> error
*/ */
static void io_writeto (void) static void io_writeto (void)
{ {
lua_Object o = lua_getparam (1); if (lua_getparam (1) == LUA_NOOBJECT) /* restore standart output */
if (o == LUA_NOOBJECT) /* restore standart output */
{ {
if (out != stdout) closewrite();
{
fclose (out);
out = stdout;
}
lua_pushnumber (1); lua_pushnumber (1);
} }
else else
{ {
if (!lua_isstring (o)) char *s = lua_check_string(1, "writeto");
{ FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
lua_error ("incorrect argument to function 'writeto`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"w");
if (fp == NULL) if (fp == NULL)
{ lua_pushnil();
lua_pushnumber (0);
}
else else
{ {
if (out != stdout) fclose (out); closewrite();
out = fp; out = fp;
lua_pushnumber (1); lua_pushnumber (1);
} }
}
} }
} }
@@ -115,50 +118,90 @@ static void io_writeto (void)
** where: ** where:
** status = 2 -> success (already exist) ** status = 2 -> success (already exist)
** status = 1 -> success (new file) ** status = 1 -> success (new file)
** status = 0 -> error ** status = nil -> error
*/ */
static void io_appendto (void) static void io_appendto (void)
{ {
lua_Object o = lua_getparam (1); char *s = lua_check_string(1, "appendto");
if (o == LUA_NOOBJECT) /* restore standart output */ struct stat st;
{ int r = (stat(s, &st) == -1) ? 1 : 2;
if (out != stdout) FILE *fp = fopen (s, "a");
{ if (fp == NULL)
fclose (out); lua_pushnil();
out = stdout;
}
lua_pushnumber (1);
}
else else
{ {
if (!lua_isstring (o)) if (out != stdout) fclose (out);
{ out = fp;
lua_error ("incorrect argument to function 'appendto`"); lua_pushnumber (r);
lua_pushnumber (0);
}
else
{
int r;
FILE *fp;
struct stat st;
if (stat(lua_getstring(o), &st) == -1) r = 1;
else r = 2;
fp = fopen (lua_getstring(o),"a");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (out != stdout) fclose (out);
out = fp;
lua_pushnumber (r);
}
}
} }
} }
static char getformat (char *f, int *just, int *m, int *n)
{
int t;
switch (*f++)
{
case 's': case 'S':
t = 's';
break;
case 'f': case 'F': case 'g': case 'G': case 'e': case 'E':
t = 'f';
break;
case 'i': case 'I':
t = 'i';
break;
default:
t = 0; /* to avoid compiler warnings */
lua_arg_error("read/write (format)");
}
*just = (*f == '<' || *f == '>' || *f == '|') ? *f++ : '>';
if (isdigit(*f))
{
*m = 0;
while (isdigit(*f))
*m = *m*10 + (*f++ - '0');
}
else
*m = -1;
if (*f == '.')
{
f++; /* skip point */
*n = 0;
while (isdigit(*f))
*n = *n*10 + (*f++ - '0');
}
else
*n = -1;
return t;
}
static char *add_char (int c)
{
static char *buff = NULL;
static int max = 0;
static int n = 0;
if (n >= max)
{
if (max == 0)
{
max = 100;
buff = (char *)malloc(max);
}
else
{
max *= 2;
buff = (char *)realloc(buff, max);
}
if (buff == NULL)
lua_error("memory overflow");
}
buff[n++] = c;
if (c == 0)
n = 0; /* prepare for next string */
return buff;
}
/* /*
** Read a variable. On error put nil on stack. ** Read a variable. On error put nil on stack.
@@ -174,138 +217,105 @@ static void io_appendto (void)
** Estes especificadores podem vir seguidos de numero que representa ** Estes especificadores podem vir seguidos de numero que representa
** o numero de campos a serem lidos. ** o numero de campos a serem lidos.
*/ */
static void io_read (void)
static int read_until_char (int del)
{
int c;
while((c = fgetc(in)) != EOF && c != del)
add_char(c);
return c;
}
static int read_until_blank (void)
{
int c;
while((c = fgetc(in)) != EOF && !isspace(c))
add_char(c);
return c;
}
static void read_m (int m)
{
int c;
while (m-- && (c = fgetc(in)) != EOF)
add_char(c);
}
static void read_free (void)
{ {
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT || !lua_isstring(o)) /* free format */
{
int c; int c;
char s[256];
while (isspace(c=fgetc(in))) while (isspace(c=fgetc(in)))
; ;
if (c == '\"') if (c == EOF)
{ {
int n=0;
while((c = fgetc(in)) != '\"')
{
if (c == EOF)
{
lua_pushnil ();
return;
}
s[n++] = c;
}
s[n] = 0;
}
else if (c == '\'')
{
int n=0;
while((c = fgetc(in)) != '\'')
{
if (c == EOF)
{
lua_pushnil ();
return;
}
s[n++] = c;
}
s[n] = 0;
}
else
{
double d;
ungetc (c, in);
if (fscanf (in, "%s", s) != 1)
{
lua_pushnil ();
return;
}
if (sscanf(s, "%lf %*c", &d) == 1)
{
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(); lua_pushnil();
return; return;
} }
else if (c == '\"' || c == '\'')
{ { /* string */
if (s[strlen(s)-1] == '\n') c = read_until_char(c);
s[strlen(s)-1] = 0; if (c == EOF)
}
switch (tolower(t))
{
case 'i':
{ {
long int l; add_char(0); /* to be ready for next time */
sscanf (s, "%ld", &l); lua_pushnil();
lua_pushnumber(l);
} }
break; else
case 'f': case 'g': case 'e': lua_pushstring(add_char(0));
{
float fl;
sscanf (s, "%f", &fl);
lua_pushnumber(fl);
}
break;
default:
lua_pushstring(s);
break;
}
} }
else else
{ {
switch (tolower(t)) double d;
{ char dummy;
case 'i': char *s;
{ add_char(c);
long int l; read_until_blank();
if (fscanf (in, "%ld", &l) == EOF) s = add_char(0);
lua_pushnil(); if (sscanf(s, "%lf %c", &d, &dummy) == 1)
else lua_pushnumber(l); lua_pushnumber(d);
} else
break; lua_pushstring(s);
case 'f': case 'g': case 'e': }
{ }
float f;
if (fscanf (in, "%f", &f) == EOF) static void io_read (void)
lua_pushnil(); {
else lua_pushnumber(f); lua_Object o = lua_getparam (1);
} if (o == LUA_NOOBJECT) /* free format */
break; read_free();
default: else /* formatted */
{ {
char s[256]; int m, dummy1, dummy2;
if (fscanf (in, "%s", s) == EOF) switch (getformat(lua_check_string(1, "read"), &dummy1, &m, &dummy2))
lua_pushnil(); {
else lua_pushstring(s); case 's':
} if (m < 0)
break; read_until_blank();
} else
read_m(m);
lua_pushstring(add_char(0));
break;
case 'i': /* can read as float, since it makes no difference to Lua */
case 'f':
{
double d;
int result;
if (m < 0)
result = fscanf(in, "%lf", &d);
else
{
read_m(m);
result = sscanf(add_char(0), "%lf", &d);
}
if (result == 1)
lua_pushnumber(d);
else
lua_pushnil();
break;
}
}
} }
}
} }
@@ -314,33 +324,13 @@ static void io_read (void)
*/ */
static void io_readuntil (void) static void io_readuntil (void)
{ {
int n=255,m=0; int del = *lua_check_string(1, "readuntil");
int c,d; int c = read_until_char(del);
char *s;
lua_Object lo = lua_getparam(1);
if (!lua_isstring(lo))
d = EOF;
else
d = *lua_getstring(lo);
s = (char *)malloc(n+1);
while((c = fgetc(in)) != EOF && c != d)
{
if (m==n)
{
n *= 2;
s = (char *)realloc(s, n+1);
}
s[m++] = c;
}
if (c != EOF) ungetc(c,in); if (c != EOF) ungetc(c,in);
s[m] = 0; lua_pushstring(add_char(0));
lua_pushstring(s);
free(s);
} }
/* /*
** Write a variable. On error put 0 on stack, otherwise put 1. ** Write a variable. On error put 0 on stack, otherwise put 1.
** LUA interface: ** LUA interface:
@@ -367,106 +357,100 @@ static void io_readuntil (void)
** inteiros -> numero minimo de digitos ** inteiros -> numero minimo de digitos
** string -> nao se aplica ** string -> nao se aplica
*/ */
static char *buildformat (char *e, lua_Object o)
{
static char buffer[2048];
static char f[80];
char *string = &buffer[255];
char *fstart=e, *fspace, *send;
char t, j='r';
int m=0, n=-1, l;
while (isspace(*e)) e++;
fspace = e;
t = *e++;
if (*e == '<' || *e == '|' || *e == '>') j = *e++;
while (isdigit(*e))
m = m*10 + (*e++ - '0');
if (*e == '.') e++; /* skip point */
while (isdigit(*e))
if (n < 0) n = (*e++ - '0');
else n = n*10 + (*e++ - '0');
sprintf(f,"%%"); static int write_fill (int n, int c)
if (j == '<' || j == '|') sprintf(strchr(f,0),"-"); {
if (m > 0) sprintf(strchr(f,0),"%d", m); while (n--)
if (n >= 0) sprintf(strchr(f,0),".%d", n); if (fputc(c, out) == EOF)
switch (t) return 0;
{ return 1;
case 'i': case 'I': t = 'd';
sprintf(strchr(f,0), "%c", t);
sprintf (string, f, (long int)lua_getnumber(o));
break;
case 'f': case 'g': case 'e': case 'G': case 'E':
sprintf(strchr(f,0), "%c", t);
sprintf (string, f, (float)lua_getnumber(o));
break;
case 'F': t = 'f';
sprintf(strchr(f,0), "%c", t);
sprintf (string, f, (float)lua_getnumber(o));
break;
case 's': case 'S': t = 's';
sprintf(strchr(f,0), "%c", t);
sprintf (string, f, lua_getstring(o));
break;
default: return "";
}
l = strlen(string);
send = string+l;
if (m!=0 && l>m)
{
int i;
for (i=0; i<m; i++)
string[i] = '*';
string[i] = 0;
}
else if (m!=0 && j=='|')
{
int k;
int i=l-1;
while (isspace(string[i]) || string[i]==0) i--;
string -= (m-i)/2;
for(k=0; k<(m-i)/2; k++)
string[k] = ' ';
}
/* add space characteres */
while (fspace != fstart)
{
string--;
fspace--;
*string = *fspace;
}
while (isspace(*e)) *send++ = *e++;
*send = 0;
return string;
} }
static int write_string (char *s, int just, int m)
{
int status;
int l = strlen(s);
int pre; /* number of blanks before string */
if (m < 0) m = l;
else if (l > m)
{
write_fill(m, '*');
return 0;
}
pre = (just == '<') ? 0 : (just == '>') ? m-l : (m-l)/2;
status = write_fill(pre, ' ');
status = status && fprintf(out, "%s", s) >= 0;
status = status && write_fill(m-(l+pre), ' ');
return status;
}
static int write_float (int just, int m, int n)
{
char buffer[100];
lua_Object p = lua_getparam(1);
float number;
if (!lua_isnumber(p)) return 0;
number = lua_getnumber(p);
if (n >= 0)
sprintf(buffer, "%.*f", n, number);
else
sprintf(buffer, "%g", number);
return write_string(buffer, just, m);
}
static int write_int (int just, int m, int n)
{
char buffer[100];
lua_Object p = lua_getparam(1);
int number;
if (!lua_isnumber(p)) return 0;
number = (int)lua_getnumber(p);
if (n >= 0)
sprintf(buffer, "%.*d", n, number);
else
sprintf(buffer, "%d", number);
return write_string(buffer, just, m);
}
static void io_write (void) static void io_write (void)
{ {
lua_Object o1 = lua_getparam (1); int status = 0;
lua_Object o2 = lua_getparam (2); if (lua_getparam (2) == LUA_NOOBJECT) /* free format */
if (o1 == LUA_NOOBJECT) /* new line */ {
{ lua_Object o1 = lua_getparam(1);
fprintf (out, "\n"); if (lua_isnumber(o1))
lua_pushnumber(1); status = fprintf (out, "%g", lua_getnumber(o1)) >= 0;
} else if (lua_isstring(o1))
else if (o2 == LUA_NOOBJECT) /* free format */ status = fprintf (out, "%s", lua_getstring(o1)) >= 0;
{
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))); else /* formated */
} {
int just, m, n;
switch (getformat (lua_check_string(2, "write"), &just, &m, &n))
{
case 's':
{
lua_Object p = lua_getparam(1);
if (lua_isstring(p))
status = write_string(lua_getstring(p), just, m);
else
status = 0;
break;
}
case 'f':
status = write_float(just, m, n);
break;
case 'i':
status = write_int(just, m, n);
break;
}
}
if (status)
lua_pushnumber(status);
else
lua_pushnil();
} }
/* /*
@@ -475,40 +459,18 @@ static void io_write (void)
*/ */
static void io_execute (void) static void io_execute (void)
{ {
lua_Object o = lua_getparam (1); lua_pushnumber(system(lua_check_string(1, "execute")));
if (o == LUA_NOOBJECT || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
int res = system(lua_getstring(o));
lua_pushnumber (res);
}
return;
} }
/* /*
** Remove a file. ** Remove a file. On error return nil.
** On error put 0 on stack, otherwise put 1.
*/ */
static void io_remove (void) static void io_remove (void)
{ {
lua_Object o = lua_getparam (1); if (remove(lua_check_string(1, "remove")) == 0)
if (o == LUA_NOOBJECT || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
if (remove(lua_getstring(o)) == 0)
lua_pushnumber (1); lua_pushnumber (1);
else else
lua_pushnumber (0); lua_pushnil();
}
return;
} }
@@ -517,15 +479,9 @@ static void io_remove (void)
*/ */
static void io_getenv (void) static void io_getenv (void)
{ {
lua_Object s = lua_getparam(1); char *env = getenv(lua_check_string(1, "getenv"));
if (!lua_isstring(s)) if (env == NULL) lua_pushnil();
lua_pushnil(); else lua_pushstring(env);
else
{
char *env = getenv(lua_getstring(s));
if (env == NULL) lua_pushnil();
else lua_pushstring(env);
}
} }
/* /*
@@ -573,7 +529,7 @@ static void io_exit (void)
{ {
lua_Object o = lua_getparam(1); lua_Object o = lua_getparam(1);
if (lua_isstring(o)) if (lua_isstring(o))
printf("%s\n", lua_getstring(o)); fprintf(stderr, "%s\n", lua_getstring(o));
exit(1); exit(1);
} }
@@ -593,6 +549,54 @@ static void io_debug (void)
} }
} }
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 (*getobjname(func, &name))
{
case 'g':
fprintf(f, "function %s", name);
break;
case 'f':
fprintf(f, "fallback %s", 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)
{
lua_Object o = lua_getparam(1);
char *s = lua_isstring(o) ? lua_getstring(o) : "(no messsage)";
fprintf(stderr, "lua: %s\n", s);
lua_printstack(stderr);
}
/* /*
** Open io library ** Open io library
*/ */
@@ -612,4 +616,7 @@ void iolib_open (void)
lua_register ("beep", io_beep); lua_register ("beep", io_beep);
lua_register ("exit", io_exit); lua_register ("exit", io_exit);
lua_register ("debug", io_debug); lua_register ("debug", io_debug);
lua_register ("print_stack", errorfb);
lua_setfallback("error", errorfb);
} }

98
lex.c
View File

@@ -1,12 +1,12 @@
char *rcs_lex = "$Id: lex.c,v 2.13 1994/12/20 21:20:36 roberto Exp celes $"; char *rcs_lex = "$Id: lex.c,v 2.20 1995/10/25 13:05:51 roberto Exp roberto $";
#include <ctype.h> #include <ctype.h>
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "mem.h"
#include "tree.h" #include "tree.h"
#include "table.h" #include "table.h"
#include "opcode.h" #include "opcode.h"
@@ -14,6 +14,8 @@ char *rcs_lex = "$Id: lex.c,v 2.13 1994/12/20 21:20:36 roberto Exp celes $";
#include "parser.h" #include "parser.h"
#include "ugly.h" #include "ugly.h"
#define MINBUFF 260
#define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b))) #define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b)))
#define next() { current = input(); } #define next() { current = input(); }
@@ -21,7 +23,8 @@ char *rcs_lex = "$Id: lex.c,v 2.13 1994/12/20 21:20:36 roberto Exp celes $";
#define save_and_next() { save(current); next(); } #define save_and_next() { save(current); next(); }
static int current; static int current;
static char yytext[256]; static char *yytext = NULL;
static int textsize = 0;
static char *yytextLast; static char *yytextLast;
static Input input; static Input input;
@@ -30,6 +33,11 @@ void lua_setinput (Input fn)
{ {
current = ' '; current = ' ';
input = fn; input = fn;
if (yytext == NULL)
{
textsize = MINBUFF;
yytext = newvector(textsize, char);
}
} }
char *lua_lasttext (void) char *lua_lasttext (void)
@@ -85,9 +93,64 @@ static int findReserved (char *name)
} }
static void growtext (void)
{
int size = yytextLast - yytext;
textsize *= 2;
yytext = growvector(yytext, textsize, char);
yytextLast = yytext + size;
}
static int read_long_string (void)
{
int cont = 0;
int spaceleft = textsize - (yytextLast - yytext);
while (1)
{
if (spaceleft <= 2) /* may read more than 1 char in one cicle */
{
growtext();
spaceleft = textsize - (yytextLast - yytext);
}
switch (current)
{
case EOF:
case 0:
return WRONGTOKEN;
case '[':
save_and_next(); spaceleft--;
if (current == '[')
{
cont++;
save_and_next(); spaceleft--;
}
continue;
case ']':
save_and_next(); spaceleft--;
if (current == ']')
{
if (cont == 0) return STRING;
cont--;
save_and_next(); spaceleft--;
}
continue;
case '\n':
lua_linenumber++; /* goes through */
default:
save_and_next(); spaceleft--;
}
}
}
int yylex (void) int yylex (void)
{ {
float a; float a;
static int linelasttoken = 0;
if (lua_debug)
luaI_codedebugline(linelasttoken);
linelasttoken = lua_linenumber;
while (1) while (1)
{ {
yytextLast = yytext; yytextLast = yytext;
@@ -99,8 +162,9 @@ int yylex (void)
case EOF: case EOF:
case 0: case 0:
return 0; return 0;
case '\n': lua_linenumber++; case '\n': linelasttoken = ++lua_linenumber;
case ' ': case ' ':
case '\r': /* CR: to avoid problems with DOS/Windows */
case '\t': case '\t':
next(); next();
continue; continue;
@@ -124,10 +188,25 @@ int yylex (void)
case '-': case '-':
save_and_next(); save_and_next();
if (current != '-') return '-'; if (current != '-') return '-'; /* else goes through */
case '#':
do { next(); } while (current != '\n' && current != 0); do { next(); } while (current != '\n' && current != 0);
continue; continue;
case '[':
save_and_next();
if (current != '[') return '[';
else
{
save_and_next(); /* pass the second '[' */
if (read_long_string() == WRONGTOKEN)
return WRONGTOKEN;
save_and_next(); /* pass the second ']' */
*(yytextLast-2) = 0; /* erases ']]' */
yylval.vWord = luaI_findconstantbyname(yytext+2);
return STRING;
}
case '=': case '=':
save_and_next(); save_and_next();
if (current != '=') return '='; if (current != '=') return '=';
@@ -152,9 +231,16 @@ int yylex (void)
case '\'': case '\'':
{ {
int del = current; int del = current;
int spaceleft = textsize - (yytextLast - yytext);
next(); /* skip the delimiter */ next(); /* skip the delimiter */
while (current != del) while (current != del)
{ {
if (spaceleft <= 2) /* may read more than 1 char in one cicle */
{
growtext();
spaceleft = textsize - (yytextLast - yytext);
}
spaceleft--;
switch (current) switch (current)
{ {
case EOF: case EOF:
@@ -177,7 +263,7 @@ int yylex (void)
} }
next(); /* skip the delimiter */ next(); /* skip the delimiter */
*yytextLast = 0; *yytextLast = 0;
yylval.vWord = luaI_findconstant(lua_constcreate(yytext)); yylval.vWord = luaI_findconstantbyname(yytext);
return STRING; return STRING;
} }

34
lua.c
View File

@@ -3,7 +3,7 @@
** Linguagem para Usuarios de Aplicacao ** Linguagem para Usuarios de Aplicacao
*/ */
char *rcs_lua="$Id: lua.c,v 1.3 1994/12/14 19:58:20 celes Exp $"; char *rcs_lua="$Id: lua.c,v 1.6 1995/10/23 13:54:11 roberto Exp roberto $";
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -14,6 +14,12 @@ char *rcs_lua="$Id: lua.c,v 1.3 1994/12/14 19:58:20 celes Exp $";
static int lua_argc; static int lua_argc;
static char **lua_argv; static char **lua_argv;
/*
** although this function is POSIX, there is no standard header file that
** defines it
*/
int isatty (int fd);
/* /*
%F Allow Lua code to access argv strings. %F Allow Lua code to access argv strings.
%i Receive from Lua the argument number (starting with 1). %i Receive from Lua the argument number (starting with 1).
@@ -33,6 +39,19 @@ static void lua_getargv (void)
} }
static void manual_input (void)
{
if (isatty(fileno(stdin)))
{
char buffer[250];
while (gets(buffer) != 0)
lua_dostring(buffer);
}
else
lua_dofile(NULL); /* executes stdin as a file */
}
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
int i; int i;
@@ -44,26 +63,25 @@ int main (int argc, char *argv[])
lua_register("argv", lua_getargv); lua_register("argv", lua_getargv);
if (argc < 2) if (argc < 2)
{ manual_input();
char buffer[250];
while (gets(buffer) != 0)
result = lua_dostring(buffer);
}
else else
{ {
for (i=1; i<argc; i++) for (i=1; i<argc; i++)
{
if (strcmp(argv[i], "--") == 0) if (strcmp(argv[i], "--") == 0)
{ {
lua_argc = argc-i-1; lua_argc = argc-i-1;
lua_argv = argv+i; lua_argv = argv+i;
break; break;
} }
}
for (i=1; i<argc; i++) for (i=1; i<argc; i++)
{ {
if (strcmp(argv[i], "--") == 0) if (strcmp(argv[i], "--") == 0)
break; break;
else 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 else
result = lua_dofile (argv[i]); result = lua_dofile (argv[i]);
} }

10
lua.h
View File

@@ -2,13 +2,18 @@
** LUA - Linguagem para Usuarios de Aplicacao ** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica ** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio ** TeCGraf - PUC-Rio
** $Id: lua.h,v 3.15 1995/01/18 20:15:05 celes Exp celes $ ** $Id: lua.h,v 3.20 1995/10/31 16:41:53 roberto Exp roberto $
*/ */
#ifndef lua_h #ifndef lua_h
#define lua_h #define lua_h
#define LUA_VERSION "Lua 2.2"
#define LUA_COPYRIGHT "Copyright (C) 1994, 1995 TeCGraf"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
/* Private Part */ /* Private Part */
typedef enum typedef enum
@@ -19,6 +24,9 @@ typedef enum
LUA_T_ARRAY = -4, LUA_T_ARRAY = -4,
LUA_T_FUNCTION = -5, LUA_T_FUNCTION = -5,
LUA_T_CFUNCTION= -6, LUA_T_CFUNCTION= -6,
LUA_T_MARK = -7,
LUA_T_CMARK = -8,
LUA_T_LINE = -9,
LUA_T_USERDATA = 0 LUA_T_USERDATA = 0
} lua_Type; } lua_Type;

398
lua.stx
View File

@@ -1,6 +1,6 @@
%{ %{
char *rcs_luastx = "$Id: lua.stx,v 3.16 1994/12/27 20:41:11 celes Exp roberto $"; char *rcs_luastx = "$Id: lua.stx,v 3.24 1995/10/26 14:21:56 roberto Exp roberto $";
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -13,6 +13,7 @@ char *rcs_luastx = "$Id: lua.stx,v 3.16 1994/12/27 20:41:11 celes Exp roberto $"
#include "tree.h" #include "tree.h"
#include "table.h" #include "table.h"
#include "lua.h" #include "lua.h"
#include "func.h"
/* to avoid warnings generated by yacc */ /* to avoid warnings generated by yacc */
int yyparse (void); int yyparse (void);
@@ -36,12 +37,14 @@ static Byte *basepc;
static int maincode; static int maincode;
static int pc; static int pc;
#define MAXVAR 32 #define MAXVAR 32
static Long varbuffer[MAXVAR]; /* variables in an assignment list; static Long varbuffer[MAXVAR]; /* variables in an assignment list;
it's long to store negative Word values */ it's long to store negative Word values */
static int nvarbuffer=0; /* number of variables at a list */ static int nvarbuffer=0; /* number of variables at a list */
static Word localvar[STACKGAP]; /* store local variable names */ #define MAXLOCALS 32
static Word localvar[MAXLOCALS]; /* store local variable names */
static int nlocalvar=0; /* number of local variables */ static int nlocalvar=0; /* number of local variables */
#define MAXFIELDS FIELDS_PER_FLUSH*2 #define MAXFIELDS FIELDS_PER_FLUSH*2
@@ -51,6 +54,14 @@ static int nfields=0;
/* Internal functions */ /* Internal functions */
static void yyerror (char *s)
{
static char msg[256];
sprintf (msg,"%s near \"%s\" at line %d in file `%s'",
s, lua_lasttext (), lua_linenumber, lua_parsedfile);
lua_error (msg);
}
static void code_byte (Byte c) static void code_byte (Byte c)
{ {
if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */ if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */
@@ -83,10 +94,10 @@ static void code_float (float n)
code_byte(code.m.c4); code_byte(code.m.c4);
} }
static void code_code (Byte *b) static void code_code (TFunc *tf)
{ {
CodeCode code; CodeCode code;
code.b = b; code.tf = tf;
code_byte(code.m.c1); code_byte(code.m.c1);
code_byte(code.m.c2); code_byte(code.m.c2);
code_byte(code.m.c3); code_byte(code.m.c3);
@@ -103,10 +114,10 @@ static void code_word_at (Byte *p, Word n)
static void push_field (Word name) static void push_field (Word name)
{ {
if (nfields < STACKGAP-1) if (nfields < MAXFIELDS)
fields[nfields++] = name; fields[nfields++] = name;
else else
lua_error ("too many fields in a constructor"); lua_error ("too many fields in nested constructors");
} }
static void flush_record (int n) static void flush_record (int n)
@@ -135,18 +146,26 @@ static void flush_list (int m, int n)
code_byte(n); code_byte(n);
} }
static void add_nlocalvar (int n) static void add_localvar (Word name)
{ {
if (MAX_TEMPS+nlocalvar+MAXVAR+n < STACKGAP) if (nlocalvar < MAXLOCALS)
nlocalvar += n; localvar[nlocalvar++] = name;
else else
lua_error ("too many local variables"); lua_error ("too many local variables");
} }
static void incr_nvarbuffer (void) static void store_localvar (Word name, int n)
{ {
if (nvarbuffer < MAXVAR-1) if (nlocalvar+n < MAXLOCALS)
nvarbuffer++; localvar[nlocalvar+n] = name;
else
lua_error ("too many local variables");
}
static void add_varbuffer (Long var)
{
if (nvarbuffer < MAXVAR)
varbuffer[nvarbuffer++] = var;
else else
lua_error ("variable buffer overflow"); lua_error ("variable buffer overflow");
} }
@@ -225,26 +244,35 @@ static void lua_codeadjust (int n)
} }
} }
static void init_function (TreeNode *func) static void change2main (void)
{ {
if (funcCode == NULL) /* first function */ /* (re)store main values */
{ pc=maincode; basepc=*initcode; maxcurr=maxmain;
funcCode = newvector(CODE_BLOCK, Byte); nlocalvar=0;
maxcode = CODE_BLOCK; }
}
pc=0; basepc=funcCode; maxcurr=maxcode; static void savemain (void)
nlocalvar=0; {
if (lua_debug) /* save main values */
maincode=pc; *initcode=basepc; maxmain=maxcurr;
}
static void init_func (void)
{
if (funcCode == NULL) /* first function */
{ {
code_byte(SETFUNCTION); funcCode = newvector(CODE_BLOCK, Byte);
code_code((Byte *)luaI_strdup(lua_file[lua_nfile-1])); maxcode = CODE_BLOCK;
code_word(luaI_findconstant(func));
} }
savemain(); /* save main values */
/* set func values */
pc=0; basepc=funcCode; maxcurr=maxcode;
nlocalvar = 0;
luaI_codedebugline(lua_linenumber);
} }
static void codereturn (void) static void codereturn (void)
{ {
if (lua_debug) code_byte(RESET);
if (nlocalvar == 0) if (nlocalvar == 0)
code_byte(RETCODE0); code_byte(RETCODE0);
else else
@@ -254,49 +282,71 @@ static void codereturn (void)
} }
} }
static void codedebugline (void) void luaI_codedebugline (int line)
{ {
if (lua_debug) static int lastline = 0;
if (lua_debug && line != lastline)
{ {
code_byte(SETLINE); code_byte(SETLINE);
code_word(lua_linenumber); code_word(line);
lastline = line;
} }
} }
static void adjust_mult_assign (int vars, int exps, int temps) static int adjust_functioncall (Long exp, int i)
{ {
if (exps < 0) if (exp <= 0)
return -exp; /* exp is -list length */
else
{ {
int r = vars - (-exps-1); int temp = basepc[exp];
if (r >= 0) basepc[exp] = i;
code_byte(r); return temp+i;
}
}
static void adjust_mult_assign (int vars, Long exps, int temps)
{
if (exps > 0)
{ /* must correct function call */
int diff = vars - basepc[exps];
if (diff >= 0)
adjust_functioncall(exps, diff);
else else
{ {
code_byte(0); adjust_functioncall(exps, 0);
lua_codeadjust(temps); lua_codeadjust(temps);
} }
} }
else if (vars != exps) else if (vars != -exps)
lua_codeadjust(temps); lua_codeadjust(temps);
} }
static void storesinglevar (Long v)
{
if (v > 0) /* global var */
{
code_byte(STOREGLOBAL);
code_word(v-1);
}
else if (v < 0) /* local var */
{
int number = (-v) - 1;
if (number < 10) code_byte(STORELOCAL0 + number);
else
{
code_byte(STORELOCAL);
code_byte(number);
}
}
else
code_byte(STOREINDEXED0);
}
static void lua_codestore (int i) static void lua_codestore (int i)
{ {
if (varbuffer[i] > 0) /* global var */ if (varbuffer[i] != 0) /* global or local var */
{ storesinglevar(varbuffer[i]);
code_byte(STOREGLOBAL);
code_word(varbuffer[i]-1);
}
else if (varbuffer[i] < 0) /* local var */
{
int number = (-varbuffer[i]) - 1;
if (number < 10) code_byte(STORELOCAL0 + number);
else
{
code_byte(STORELOCAL);
code_byte(number);
}
}
else /* indexed var */ else /* indexed var */
{ {
int j; int j;
@@ -332,26 +382,22 @@ static void codeIf (Long thenAdd, Long elseAdd)
code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1)); code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1));
} }
static void yyerror (char *s)
{
static char msg[256];
sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"",
s, lua_lasttext (), lua_linenumber, lua_filename());
lua_error (msg);
}
/* /*
** Parse LUA code. ** Parse LUA code.
*/ */
void lua_parse (Byte **code) void lua_parse (TFunc *tf)
{ {
initcode = code; lua_debug = 0;
initcode = &(tf->code);
*initcode = newvector(CODE_BLOCK, Byte); *initcode = newvector(CODE_BLOCK, Byte);
maincode = 0; maincode = 0;
maxmain = CODE_BLOCK; maxmain = CODE_BLOCK;
change2main();
if (yyparse ()) lua_error("parse error"); if (yyparse ()) lua_error("parse error");
savemain();
(*initcode)[maincode++] = RETCODE0; (*initcode)[maincode++] = RETCODE0;
tf->size = maincode;
#if LISTING #if LISTING
{ static void PrintCode (Byte *c, Byte *end); { static void PrintCode (Byte *c, Byte *end);
PrintCode(*initcode,*initcode+maincode); } PrintCode(*initcode,*initcode+maincode); }
@@ -369,7 +415,7 @@ void lua_parse (Byte **code)
char *pChar; char *pChar;
Word vWord; Word vWord;
Long vLong; Long vLong;
Byte *pByte; TFunc *pFunc;
TreeNode *pNode; TreeNode *pNode;
} }
@@ -387,12 +433,17 @@ void lua_parse (Byte **code)
%token <vInt> DEBUG %token <vInt> DEBUG
%type <vLong> PrepJump %type <vLong> PrepJump
%type <vInt> expr, exprlist, exprlist1, varlist1, funcParams, funcvalue %type <vLong> exprlist, exprlist1 /* if > 0, points to function return
counter (which has list length); if <= 0, -list lenght */
%type <vLong> functioncall, expr /* if != 0, points to function return
counter */
%type <vInt> varlist1, funcParams, funcvalue
%type <vInt> fieldlist, localdeclist, decinit %type <vInt> fieldlist, localdeclist, decinit
%type <vInt> ffieldlist1 %type <vInt> ffieldlist, ffieldlist1, semicolonpart
%type <vInt> lfieldlist1 %type <vInt> lfieldlist, lfieldlist1
%type <vLong> var, singlevar %type <vInt> parlist
%type <pByte> body %type <vLong> var, singlevar, funcname
%type <pFunc> body
%left AND OR %left AND OR
%left EQ NE '>' '<' LE GE %left EQ NE '>' '<' LE GE
@@ -407,62 +458,48 @@ void lua_parse (Byte **code)
functionlist : /* empty */ functionlist : /* empty */
| functionlist | functionlist globalstat
{
pc=maincode; basepc=*initcode; maxcurr=maxmain;
nlocalvar=0;
}
stat sc
{
maincode=pc; *initcode=basepc; maxmain=maxcurr;
}
| functionlist function | functionlist function
| functionlist method
| functionlist setdebug
; ;
function : FUNCTION NAME globalstat : stat sc
{ | setdebug
init_function($2); ;
}
body function : FUNCTION funcname body
{ {
Word func = luaI_findsymbol($2); code_byte(PUSHFUNCTION);
s_tag(func) = LUA_T_FUNCTION; code_code($3);
s_bvalue(func) = $4; storesinglevar($2);
} }
; ;
method : FUNCTION NAME ':' NAME funcname : var { $$ =$1; init_func(); }
{ | varexp ':' NAME
init_function($4); {
localvar[nlocalvar]=luaI_findsymbolbyname("self"); code_byte(PUSHSTRING);
add_nlocalvar(1); code_word(luaI_findconstant($3));
} $$ = 0; /* indexed variable */
body init_func();
{ add_localvar(luaI_findsymbolbyname("self"));
/* assign function to table field */ }
pc=maincode; basepc=*initcode; maxcurr=maxmain; ;
nlocalvar=0;
lua_pushvar(luaI_findsymbol($2)+1);
code_byte(PUSHSTRING);
code_word(luaI_findconstant($4));
code_byte(PUSHFUNCTION);
code_code($6);
code_byte(STOREINDEXED0);
maincode=pc; *initcode=basepc; maxmain=maxcurr;
}
;
body : '(' parlist ')' block END body : '(' parlist ')' block END
{ {
codereturn(); codereturn();
$$ = newvector(pc, Byte); $$ = new(TFunc);
memcpy($$, basepc, pc*sizeof(Byte)); $$->size = pc;
$$->code = newvector(pc, Byte);
$$->fileName = lua_parsedfile;
$$->lineDefined = $2;
memcpy($$->code, basepc, pc*sizeof(Byte));
/* save func values */
funcCode = basepc; maxcode=maxcurr; funcCode = basepc; maxcode=maxcurr;
#if LISTING #if LISTING
PrintCode(funcCode,funcCode+pc); PrintCode(funcCode,funcCode+pc);
#endif #endif
change2main(); /* change back to main code */
} }
; ;
@@ -472,11 +509,7 @@ statlist : /* empty */
sc : /* empty */ | ';' ; sc : /* empty */ | ';' ;
stat : { codedebugline(); } stat1 ; stat : IF expr1 THEN PrepJump block PrepJump elsepart END
cond : { codedebugline(); } expr1 ;
stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
{ codeIf($4, $6); } { codeIf($4, $6); }
| WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END | WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END
@@ -487,7 +520,7 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
code_word_at(basepc+$7+1, pc - ($<vLong>2)); code_word_at(basepc+$7+1, pc - ($<vLong>2));
} }
| REPEAT {$<vLong>$=pc;} block UNTIL cond PrepJump | REPEAT {$<vLong>$=pc;} block UNTIL expr1 PrepJump
{ {
basepc[$6] = IFFUPJMP; basepc[$6] = IFFUPJMP;
code_word_at(basepc+$6+1, pc - ($<vLong>2)); code_word_at(basepc+$6+1, pc - ($<vLong>2));
@@ -504,16 +537,16 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
lua_codeadjust (0); lua_codeadjust (0);
} }
} }
| functioncall { code_byte(0); } | functioncall
| LOCAL localdeclist decinit | LOCAL localdeclist decinit
{ add_nlocalvar($2); { nlocalvar += $2;
adjust_mult_assign($2, $3, 0); adjust_mult_assign($2, $3, 0);
} }
; ;
elsepart : /* empty */ elsepart : /* empty */
| ELSE block | ELSE block
| ELSEIF cond THEN PrepJump block PrepJump elsepart | ELSEIF expr1 THEN PrepJump block PrepJump elsepart
{ codeIf($4, $6); } { codeIf($4, $6); }
; ;
@@ -528,9 +561,9 @@ block : {$<vInt>$ = nlocalvar;} statlist ret
; ;
ret : /* empty */ ret : /* empty */
| RETURN { codedebugline(); } exprlist sc | RETURN exprlist sc
{ {
if ($3 < 0) code_byte(MULT_RET); adjust_functioncall($2, MULT_RET);
codereturn(); codereturn();
} }
; ;
@@ -542,46 +575,46 @@ PrepJump : /* empty */
code_word (0); code_word (0);
} }
expr1 : expr { if ($1 == 0) code_byte(1); } expr1 : expr { adjust_functioncall($1, 1); }
; ;
expr : '(' expr ')' { $$ = $2; } expr : '(' expr ')' { $$ = $2; }
| expr1 EQ expr1 { code_byte(EQOP); $$ = 1; } | expr1 EQ expr1 { code_byte(EQOP); $$ = 0; }
| expr1 '<' expr1 { code_byte(LTOP); $$ = 1; } | expr1 '<' expr1 { code_byte(LTOP); $$ = 0; }
| expr1 '>' expr1 { code_byte(GTOP); $$ = 1; } | expr1 '>' expr1 { code_byte(GTOP); $$ = 0; }
| expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; } | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 0; }
| expr1 LE expr1 { code_byte(LEOP); $$ = 1; } | expr1 LE expr1 { code_byte(LEOP); $$ = 0; }
| expr1 GE expr1 { code_byte(GEOP); $$ = 1; } | expr1 GE expr1 { code_byte(GEOP); $$ = 0; }
| expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; } | expr1 '+' expr1 { code_byte(ADDOP); $$ = 0; }
| expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; } | expr1 '-' expr1 { code_byte(SUBOP); $$ = 0; }
| expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; } | expr1 '*' expr1 { code_byte(MULTOP); $$ = 0; }
| expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; } | expr1 '/' expr1 { code_byte(DIVOP); $$ = 0; }
| expr1 '^' expr1 { code_byte(POWOP); $$ = 1; } | expr1 '^' expr1 { code_byte(POWOP); $$ = 0; }
| expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; } | expr1 CONC expr1 { code_byte(CONCOP); $$ = 0; }
| '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;} | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 0;}
| table { $$ = 1; } | table { $$ = 0; }
| varexp { $$ = 1;} | varexp { $$ = 0;}
| NUMBER { code_number($1); $$ = 1; } | NUMBER { code_number($1); $$ = 0; }
| STRING | STRING
{ {
code_byte(PUSHSTRING); code_byte(PUSHSTRING);
code_word($1); code_word($1);
$$ = 1; $$ = 0;
} }
| NIL {code_byte(PUSHNIL); $$ = 1; } | NIL {code_byte(PUSHNIL); $$ = 0; }
| functioncall { $$ = 0; } | functioncall { $$ = $1; }
| NOT expr1 { code_byte(NOTOP); $$ = 1;} | NOT expr1 { code_byte(NOTOP); $$ = 0;}
| expr1 AND PrepJump {code_byte(POP); } expr1 | expr1 AND PrepJump {code_byte(POP); } expr1
{ {
basepc[$3] = ONFJMP; basepc[$3] = ONFJMP;
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
$$ = 1; $$ = 0;
} }
| expr1 OR PrepJump {code_byte(POP); } expr1 | expr1 OR PrepJump {code_byte(POP); } expr1
{ {
basepc[$3] = ONTJMP; basepc[$3] = ONTJMP;
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
$$ = 1; $$ = 0;
} }
; ;
@@ -597,7 +630,12 @@ table :
; ;
functioncall : funcvalue funcParams functioncall : funcvalue funcParams
{ code_byte(CALLFUNC); code_byte($1+$2); } {
code_byte(CALLFUNC);
code_byte($1+$2);
$$ = pc;
code_byte(0); /* may be modified by other rules */
}
; ;
funcvalue : varexp { $$ = 0; } funcvalue : varexp { $$ = 0; }
@@ -610,7 +648,7 @@ funcvalue : varexp { $$ = 0; }
; ;
funcParams : '(' exprlist ')' funcParams : '(' exprlist ')'
{ if ($2<0) { code_byte(1); $$ = -$2; } else $$ = $2; } { $$ = adjust_functioncall($2, 1); }
| table { $$ = 1; } | table { $$ = 1; }
; ;
@@ -618,45 +656,54 @@ exprlist : /* empty */ { $$ = 0; }
| exprlist1 { $$ = $1; } | exprlist1 { $$ = $1; }
; ;
exprlist1 : expr { if ($1 == 0) $$ = -1; else $$ = 1; } exprlist1 : expr { if ($1 != 0) $$ = $1; else $$ = -1; }
| exprlist1 ',' { if ($1 < 0) code_byte(1); } expr | exprlist1 ',' { $<vLong>$ = adjust_functioncall($1, 1); } expr
{ {
int r = $1 < 0 ? -$1 : $1; if ($4 == 0) $$ = -($<vLong>3 + 1); /* -length */
$$ = ($4 == 0) ? -(r+1) : r+1; else
{
adjust_functioncall($4, $<vLong>3);
$$ = $4;
}
} }
; ;
parlist : /* empty */ { lua_codeadjust(0); } parlist : /* empty */ { lua_codeadjust(0); $$ = lua_linenumber; }
| parlist1 { lua_codeadjust(0); } | parlist1 { lua_codeadjust(0); $$ = lua_linenumber; }
; ;
parlist1 : NAME parlist1 : NAME
{ {
localvar[nlocalvar]=luaI_findsymbol($1); add_localvar(luaI_findsymbol($1));
add_nlocalvar(1);
} }
| parlist1 ',' NAME | parlist1 ',' NAME
{ {
localvar[nlocalvar]=luaI_findsymbol($3); add_localvar(luaI_findsymbol($3));
add_nlocalvar(1);
} }
; ;
fieldlist : /* empty */ { $$ = 0; } fieldlist : lfieldlist
| lfieldlist1 lastcomma { flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); }
{ $$ = $1; flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); } semicolonpart
{ $$ = $1+$3; }
| ffieldlist1 lastcomma | ffieldlist1 lastcomma
{ $$ = $1; flush_record($1%FIELDS_PER_FLUSH); } { $$ = $1; flush_record($1%FIELDS_PER_FLUSH); }
| lfieldlist1 ';'
{ flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); }
ffieldlist1 lastcomma
{ $$ = $1+$4; flush_record($4%FIELDS_PER_FLUSH); }
; ;
semicolonpart : /* empty */
{ $$ = 0; }
| ';' ffieldlist
{ $$ = $2; flush_record($2%FIELDS_PER_FLUSH); }
;
lastcomma : /* empty */ lastcomma : /* empty */
| ',' | ','
; ;
ffieldlist : /* empty */ { $$ = 0; }
| ffieldlist1 lastcomma { $$ = $1; }
;
ffieldlist1 : ffield {$$=1;} ffieldlist1 : ffield {$$=1;}
| ffieldlist1 ',' ffield | ffieldlist1 ',' ffield
{ {
@@ -671,6 +718,10 @@ ffield : NAME '=' expr1
} }
; ;
lfieldlist : /* empty */ { $$ = 0; }
| lfieldlist1 lastcomma { $$ = $1; }
;
lfieldlist1 : expr1 {$$=1;} lfieldlist1 : expr1 {$$=1;}
| lfieldlist1 ',' expr1 | lfieldlist1 ',' expr1
{ {
@@ -683,12 +734,12 @@ lfieldlist1 : expr1 {$$=1;}
varlist1 : var varlist1 : var
{ {
nvarbuffer = 0; nvarbuffer = 0;
varbuffer[nvarbuffer] = $1; incr_nvarbuffer(); add_varbuffer($1);
$$ = ($1 == 0) ? 1 : 0; $$ = ($1 == 0) ? 1 : 0;
} }
| varlist1 ',' var | varlist1 ',' var
{ {
varbuffer[nvarbuffer] = $3; incr_nvarbuffer(); add_varbuffer($3);
$$ = ($3 == 0) ? $1 + 1 : $1; $$ = ($3 == 0) ? $1 + 1 : $1;
} }
; ;
@@ -720,10 +771,10 @@ singlevar : NAME
varexp : var { lua_pushvar($1); } varexp : var { lua_pushvar($1); }
; ;
localdeclist : NAME {localvar[nlocalvar]=luaI_findsymbol($1); $$ = 1;} localdeclist : NAME {store_localvar(luaI_findsymbol($1), 0); $$ = 1;}
| localdeclist ',' NAME | localdeclist ',' NAME
{ {
localvar[nlocalvar+$1]=luaI_findsymbol($3); store_localvar(luaI_findsymbol($3), $1);
$$ = $1+1; $$ = $1+1;
} }
; ;
@@ -732,7 +783,8 @@ decinit : /* empty */ { $$ = 0; }
| '=' exprlist1 { $$ = $2; } | '=' exprlist1 { $$ = $2; }
; ;
setdebug : DEBUG {lua_debug = $1;} setdebug : DEBUG { lua_debug = $1; }
;
%% %%
@@ -788,7 +840,7 @@ static void PrintCode (Byte *code, Byte *end)
int n = p-code; int n = p-code;
p++; p++;
get_code(c,p); get_code(c,p);
printf ("%d PUSHFUNCTION %p\n", n, c.b); printf ("%d PUSHFUNCTION %p\n", n, c.tf);
} }
break; break;
@@ -944,17 +996,6 @@ static void PrintCode (Byte *code, Byte *end)
printf ("%d RETCODE %d\n", p-code, *(++p)); printf ("%d RETCODE %d\n", p-code, *(++p));
p++; p++;
break; break;
case SETFUNCTION:
{
CodeCode c1;
CodeWord c2;
int n = p-code;
p++;
get_code(c1,p);
get_word(c2,p);
printf ("%d SETFUNCTION %s %d\n", n, (char *)c1.b, c2.w);
}
break;
case SETLINE: case SETLINE:
{ {
CodeWord c; CodeWord c;
@@ -965,7 +1006,6 @@ static void PrintCode (Byte *code, Byte *end)
} }
break; break;
case RESET: printf ("%d RESET\n", (p++)-code); break;
default: printf ("%d Cannot happen: code %d\n", (p++)-code, *(p-1)); break; default: printf ("%d Cannot happen: code %d\n", (p++)-code, *(p-1)); break;
} }
} }

20
luadebug.h Normal file
View File

@@ -0,0 +1,20 @@
/*
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: luadebug.h,v 1.1 1995/10/17 14:12:45 roberto Exp roberto $
*/
#ifndef luadebug_h
#define luadebug_h
#include "lua.h"
lua_Object lua_stackedfunction(int level);
void lua_funcinfo (lua_Object func, char **filename, int *linedefined);
int lua_currentline (lua_Object func);
char *getobjname (lua_Object o, char **name);
#endif

View File

@@ -2,7 +2,7 @@
** Libraries to be used in LUA programs ** Libraries to be used in LUA programs
** Grupo de Tecnologia em Computacao Grafica ** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio ** TeCGraf - PUC-Rio
** $Id: lualib.h,v 1.2 1994/08/24 15:29:02 celes Stab roberto $ ** $Id: lualib.h,v 1.3 1994/12/13 15:59:16 roberto Exp roberto $
*/ */
#ifndef lualib_h #ifndef lualib_h
@@ -12,5 +12,11 @@ void iolib_open (void);
void strlib_open (void); void strlib_open (void);
void mathlib_open (void); void mathlib_open (void);
/* auxiliar functions (private) */
void lua_arg_error(char *funcname);
char *lua_check_string (int numArg, char *funcname);
float lua_check_number (int numArg, char *funcname);
#endif #endif

View File

@@ -1,7 +1,12 @@
# $Id: makefile,v 1.12 1995/02/02 19:02:03 roberto Exp $ # $Id: makefile,v 1.15 1995/10/17 18:16:58 roberto Exp roberto $
#configuration
# define (undefine) POPEN if your system (does not) support piped I/O
CONFIG = -DPOPEN
# Compilation parameters # Compilation parameters
CC = gcc CC = gcc
CFLAGS = -I/usr/5include -Wall -Wmissing-prototypes -Wshadow -ansi -O2 CFLAGS = $(CONFIG) -I/usr/5include -Wall -Wmissing-prototypes -Wshadow -ansi -O2
#CC = acc #CC = acc
#CFLAGS = -fast -I/usr/5include #CFLAGS = -fast -I/usr/5include
@@ -10,30 +15,28 @@ AR = ar
ARFLAGS = rvl ARFLAGS = rvl
# Aplication modules # Aplication modules
LUAMOD = \ LUAOBJS = \
parser \ parser.o \
lex \ lex.o \
opcode \ opcode.o \
hash \ hash.o \
table \ table.o \
inout \ inout.o \
tree \ tree.o \
fallback\ fallback.o \
mem mem.o \
func.o
LIBMOD = \ LIBOBJS = \
iolib \ iolib.o \
strlib \ mathlib.o \
mathlib strlib.o
LUAOBJS = $(LUAMOD:%=%.o)
LIBOBJS = $(LIBMOD:%=%.o)
lua : lua.o lua.a lualib.a lua : lua.o lua.a lualib.a
$(CC) $(CFLAGS) -o $@ lua.c lua.a lualib.a -lm $(CC) $(CFLAGS) -o $@ lua.o lua.a lualib.a -lm
lua.a : parser.c $(LUAOBJS) lua.a : parser.o $(LUAOBJS)
$(AR) $(ARFLAGS) $@ $? $(AR) $(ARFLAGS) $@ $?
ranlib lua.a ranlib lua.a
@@ -44,9 +47,6 @@ lualib.a : $(LIBOBJS)
liblua.so.1.0 : lua.o liblua.so.1.0 : lua.o
ld -o liblua.so.1.0 $(LUAOBJS) ld -o liblua.so.1.0 $(LUAOBJS)
%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
parser.c : lua.stx parser.c : lua.stx
yacc++ -d lua.stx ; mv -f y.tab.c parser.c ; mv -f y.tab.h parser.h yacc++ -d lua.stx ; mv -f y.tab.c parser.c ; mv -f y.tab.h parser.h
@@ -55,24 +55,28 @@ clear :
rcsclean rcsclean
rm -f *.o rm -f *.o
rm -f parser.c parser.h rm -f parser.c parser.h
co lua.h lualib.h co lua.h lualib.h luadebug.h
% : RCS/%,v % : RCS/%,v
co $@ co $@
fallback.o : fallback.c mem.h fallback.h opcode.h lua.h types.h tree.h inout.h fallback.o : fallback.c mem.h fallback.h opcode.h lua.h types.h tree.h func.h
hash.o : hash.c mem.h opcode.h lua.h types.h tree.h hash.h inout.h table.h func.o : func.c table.h tree.h types.h opcode.h lua.h func.h mem.h
inout.o : inout.c mem.h opcode.h lua.h types.h tree.h hash.h inout.h table.h hash.o : hash.c mem.h opcode.h lua.h types.h tree.h func.h hash.h table.h
iolib.o : iolib.c mem.h lua.h lualib.h inout.o : inout.c mem.h opcode.h lua.h types.h tree.h func.h hash.h inout.h \
lex.o : lex.c tree.h types.h table.h opcode.h lua.h inout.h parser.h ugly.h table.h
iolib.o : iolib.c lua.h lualib.h luadebug.h
lex.o : lex.c mem.h tree.h types.h table.h opcode.h lua.h func.h inout.h parser.h \
ugly.h
lua.o : lua.c lua.h lualib.h lua.o : lua.c lua.h lualib.h
mathlib.o : mathlib.c lualib.h lua.h mathlib.o : mathlib.c lualib.h lua.h
mem.o : mem.c mem.h lua.h mem.o : mem.c mem.h lua.h
opcode.o : opcode.c mem.h opcode.h lua.h types.h tree.h hash.h inout.h table.h \ opcode.o : opcode.c mem.h opcode.h lua.h types.h tree.h func.h hash.h inout.h \
fallback.h table.h fallback.h luadebug.h
strlib.o : strlib.c mem.h lua.h lualib.h parser.o : parser.c mem.h opcode.h lua.h types.h tree.h func.h hash.h inout.h \
table.o : table.c mem.h opcode.h lua.h types.h tree.h hash.h inout.h table.h \ table.h
fallback.h strlib.o : strlib.c lua.h lualib.h
tree.o : tree.c mem.h lua.h tree.h types.h table.h opcode.h table.o : table.c mem.h opcode.h lua.h types.h tree.h func.h hash.h table.h \
parser.o : parser.c mem.h opcode.h lua.h types.h tree.h hash.h inout.h table.h inout.h fallback.h
tree.o : tree.c mem.h lua.h tree.h types.h table.h opcode.h func.h

1741
manual.tex Normal file

File diff suppressed because it is too large Load Diff

173
mathlib.c
View File

@@ -3,7 +3,7 @@
** Mathematics library to LUA ** Mathematics library to LUA
*/ */
char *rcs_mathlib="$Id: mathlib.c,v 1.8 1995/01/04 18:49:54 roberto Exp $"; char *rcs_mathlib="$Id: mathlib.c,v 1.12 1995/10/09 12:48:38 roberto Exp roberto $";
#include <stdio.h> /* NULL */ #include <stdio.h> /* NULL */
#include <math.h> #include <math.h>
@@ -11,19 +11,15 @@ char *rcs_mathlib="$Id: mathlib.c,v 1.8 1995/01/04 18:49:54 roberto Exp $";
#include "lualib.h" #include "lualib.h"
#include "lua.h" #include "lua.h"
#ifndef PI
#define PI 3.14159265358979323846 #define PI 3.14159265358979323846
#endif
#define TODEGREE(a) ((a)*180.0/PI) #define TODEGREE(a) ((a)*180.0/PI)
#define TORAD(a) ((a)*PI/180.0) #define TORAD(a) ((a)*PI/180.0)
static void math_abs (void) static void math_abs (void)
{ {
double d; double d = lua_check_number(1, "abs");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `abs'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `abs'");
d = lua_getnumber(o);
if (d < 0) d = -d; if (d < 0) d = -d;
lua_pushnumber (d); lua_pushnumber (d);
} }
@@ -31,13 +27,7 @@ static void math_abs (void)
static void math_sin (void) static void math_sin (void)
{ {
double d; double d = lua_check_number(1, "sin");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `sin'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `sin'");
d = lua_getnumber(o);
lua_pushnumber (sin(TORAD(d))); lua_pushnumber (sin(TORAD(d)));
} }
@@ -45,13 +35,7 @@ static void math_sin (void)
static void math_cos (void) static void math_cos (void)
{ {
double d; double d = lua_check_number(1, "cos");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `cos'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `cos'");
d = lua_getnumber(o);
lua_pushnumber (cos(TORAD(d))); lua_pushnumber (cos(TORAD(d)));
} }
@@ -59,104 +43,64 @@ static void math_cos (void)
static void math_tan (void) static void math_tan (void)
{ {
double d; double d = lua_check_number(1, "tan");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `tan'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `tan'");
d = lua_getnumber(o);
lua_pushnumber (tan(TORAD(d))); lua_pushnumber (tan(TORAD(d)));
} }
static void math_asin (void) static void math_asin (void)
{ {
double d; double d = lua_check_number(1, "asin");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `asin'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `asin'");
d = lua_getnumber(o);
lua_pushnumber (TODEGREE(asin(d))); lua_pushnumber (TODEGREE(asin(d)));
} }
static void math_acos (void) static void math_acos (void)
{ {
double d; double d = lua_check_number(1, "acos");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `acos'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `acos'");
d = lua_getnumber(o);
lua_pushnumber (TODEGREE(acos(d))); lua_pushnumber (TODEGREE(acos(d)));
} }
static void math_atan (void) static void math_atan (void)
{ {
double d; double d = lua_check_number(1, "atan");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `atan'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `atan'");
d = lua_getnumber(o);
lua_pushnumber (TODEGREE(atan(d))); 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) static void math_ceil (void)
{ {
double d; double d = lua_check_number(1, "ceil");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `ceil'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `ceil'");
d = lua_getnumber(o);
lua_pushnumber (ceil(d)); lua_pushnumber (ceil(d));
} }
static void math_floor (void) static void math_floor (void)
{ {
double d; double d = lua_check_number(1, "floor");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `floor'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `floor'");
d = lua_getnumber(o);
lua_pushnumber (floor(d)); lua_pushnumber (floor(d));
} }
static void math_mod (void) static void math_mod (void)
{ {
int d1, d2; int d1 = (int)lua_check_number(1, "mod");
lua_Object o1 = lua_getparam (1); int d2 = (int)lua_check_number(2, "mod");
lua_Object o2 = lua_getparam (2);
if (!lua_isnumber(o1) || !lua_isnumber(o2))
lua_error ("incorrect arguments to function `mod'");
d1 = (int) lua_getnumber(o1);
d2 = (int) lua_getnumber(o2);
lua_pushnumber (d1%d2); lua_pushnumber (d1%d2);
} }
static void math_sqrt (void) static void math_sqrt (void)
{ {
double d; double d = lua_check_number(1, "sqrt");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `sqrt'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `sqrt'");
d = lua_getnumber(o);
lua_pushnumber (sqrt(d)); lua_pushnumber (sqrt(d));
} }
@@ -187,104 +131,56 @@ static void math_pow (void)
static void math_min (void) static void math_min (void)
{ {
int i=1; int i=1;
double d, dmin; double dmin = lua_check_number(i, "min");
lua_Object o; while (lua_getparam(++i) != LUA_NOOBJECT)
if ((o = lua_getparam(i++)) == LUA_NOOBJECT)
lua_error ("too few arguments to function `min'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `min'");
dmin = lua_getnumber (o);
while ((o = lua_getparam(i++)) != LUA_NOOBJECT)
{ {
if (!lua_isnumber(o)) double d = lua_check_number(i, "min");
lua_error ("incorrect arguments to function `min'");
d = lua_getnumber (o);
if (d < dmin) dmin = d; if (d < dmin) dmin = d;
} }
lua_pushnumber (dmin); lua_pushnumber (dmin);
} }
static void math_max (void) static void math_max (void)
{ {
int i=1; int i=1;
double d, dmax; double dmax = lua_check_number(i, "max");
lua_Object o; while (lua_getparam(++i) != LUA_NOOBJECT)
if ((o = lua_getparam(i++)) == LUA_NOOBJECT)
lua_error ("too few arguments to function `max'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `max'");
dmax = lua_getnumber (o);
while ((o = lua_getparam(i++)) != LUA_NOOBJECT)
{ {
if (!lua_isnumber(o)) double d = lua_check_number(i, "max");
lua_error ("incorrect arguments to function `max'");
d = lua_getnumber (o);
if (d > dmax) dmax = d; if (d > dmax) dmax = d;
} }
lua_pushnumber (dmax); lua_pushnumber (dmax);
} }
static void math_log (void) static void math_log (void)
{ {
double d; double d = lua_check_number(1, "log");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `log'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `log'");
d = lua_getnumber(o);
lua_pushnumber (log(d)); lua_pushnumber (log(d));
} }
static void math_log10 (void) static void math_log10 (void)
{ {
double d; double d = lua_check_number(1, "log10");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `log10'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `log10'");
d = lua_getnumber(o);
lua_pushnumber (log10(d)); lua_pushnumber (log10(d));
} }
static void math_exp (void) static void math_exp (void)
{ {
double d; double d = lua_check_number(1, "exp");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `exp'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `exp'");
d = lua_getnumber(o);
lua_pushnumber (exp(d)); lua_pushnumber (exp(d));
} }
static void math_deg (void) static void math_deg (void)
{ {
float d; float d = lua_check_number(1, "deg");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `deg'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `deg'");
d = lua_getnumber(o);
lua_pushnumber (d*180./PI); lua_pushnumber (d*180./PI);
} }
static void math_rad (void) static void math_rad (void)
{ {
float d; float d = lua_check_number(1, "rad");
lua_Object o = lua_getparam (1);
if (o == LUA_NOOBJECT)
lua_error ("too few arguments to function `rad'");
if (!lua_isnumber(o))
lua_error ("incorrect arguments to function `rad'");
d = lua_getnumber(o);
lua_pushnumber (d/180.*PI); lua_pushnumber (d/180.*PI);
} }
@@ -300,6 +196,7 @@ void mathlib_open (void)
lua_register ("asin", math_asin); lua_register ("asin", math_asin);
lua_register ("acos", math_acos); lua_register ("acos", math_acos);
lua_register ("atan", math_atan); lua_register ("atan", math_atan);
lua_register ("atan2", math_atan2);
lua_register ("ceil", math_ceil); lua_register ("ceil", math_ceil);
lua_register ("floor", math_floor); lua_register ("floor", math_floor);
lua_register ("mod", math_mod); lua_register ("mod", math_mod);

396
opcode.c
View File

@@ -3,14 +3,14 @@
** TecCGraf - PUC-Rio ** TecCGraf - PUC-Rio
*/ */
char *rcs_opcode="$Id: opcode.c,v 3.33 1995/02/02 20:05:37 roberto Exp roberto $"; char *rcs_opcode="$Id: opcode.c,v 3.49 1995/11/10 14:12:02 roberto Exp roberto $";
#include <setjmp.h> #include <setjmp.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <math.h>
#include "luadebug.h"
#include "mem.h" #include "mem.h"
#include "opcode.h" #include "opcode.h"
#include "hash.h" #include "hash.h"
@@ -23,13 +23,15 @@ char *rcs_opcode="$Id: opcode.c,v 3.33 1995/02/02 20:05:37 roberto Exp roberto $
#define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) #define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0))
#define STACK_BUFFER (STACKGAP+128) #define STACK_SIZE 128
typedef int StkId; /* index to stack elements */ typedef int StkId; /* index to stack elements */
static Long maxstack = 0L; static Object initial_stack;
static Object *stack = NULL;
static Object *top = NULL; static Object *stackLimit = &initial_stack+1;
static Object *stack = &initial_stack;
static Object *top = &initial_stack;
/* macros to convert from lua_Object to (Object *) and back */ /* macros to convert from lua_Object to (Object *) and back */
@@ -38,6 +40,11 @@ static Object *top = NULL;
#define Ref(st) ((st)-stack+1) #define Ref(st) ((st)-stack+1)
/* macro to increment stack top. There must be always an empty slot in
* the stack
*/
#define incr_top if (++top >= stackLimit) growstack()
static StkId CBase = 0; /* when Lua calls C or C calls Lua, points to */ static StkId CBase = 0; /* when Lua calls C or C calls Lua, points to */
/* the first slot after the last parameter. */ /* the first slot after the last parameter. */
static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ static int CnResults = 0; /* when Lua calls C, has the number of parameters; */
@@ -47,7 +54,7 @@ static jmp_buf *errorJmp = NULL; /* current error recover point */
static StkId lua_execute (Byte *pc, StkId base); static StkId lua_execute (Byte *pc, StkId base);
static void do_call (Object *func, StkId base, int nResults, StkId whereRes); static void do_call (StkId base, int nResults);
@@ -57,61 +64,40 @@ Object *luaI_Address (lua_Object o)
} }
/*
** Error messages
*/
static void lua_message (char *s)
{
lua_pushstring(s);
do_call(&luaI_fallBacks[FB_ERROR].function, (top-stack)-1, 0, (top-stack)-1);
}
/*
** Reports an error, and jumps up to the available recover label
*/
void lua_error (char *s)
{
if (s) lua_message(s);
if (errorJmp)
longjmp(*errorJmp, 1);
else
{
fprintf (stderr, "lua: exit(1). Unable to recover\n");
exit(1);
}
}
/* /*
** Init stack ** Init stack
*/ */
static void lua_initstack (void) static void lua_initstack (void)
{ {
maxstack = STACK_BUFFER; Long maxstack = STACK_SIZE;
stack = newvector(maxstack, Object); stack = newvector(maxstack, Object);
stackLimit = stack+maxstack;
top = stack; top = stack;
*(top++) = initial_stack;
} }
/* /*
** Check stack overflow and, if necessary, realloc vector ** Check stack overflow and, if necessary, realloc vector
*/ */
#define lua_checkstack(n) if ((Long)(n) > maxstack) checkstack(n) #define lua_checkstack(nt) if ((nt) >= stackLimit) growstack()
static void checkstack (StkId n) static void growstack (void)
{ {
StkId t; if (stack == &initial_stack)
if (stack == NULL)
lua_initstack(); lua_initstack();
if (maxstack >= MAX_INT) else
lua_error("stack size overflow"); {
t = top-stack; StkId t = top-stack;
maxstack *= 2; Long maxstack = stackLimit - stack;
if (maxstack >= MAX_INT) maxstack *= 2;
maxstack = MAX_INT; stack = growvector(stack, maxstack, Object);
stack = growvector(stack, maxstack, Object); stackLimit = stack+maxstack;
top = stack + t; top = stack + t;
if (maxstack >= MAX_WORD/2)
lua_error("stack size overflow");
}
} }
@@ -184,15 +170,25 @@ static int lua_tostring (Object *obj)
*/ */
static void adjust_top (StkId newtop) static void adjust_top (StkId newtop)
{ {
Object *nt = stack+newtop; Object *nt;
lua_checkstack(stack+newtop);
nt = stack+newtop; /* warning: previous call may change stack */
while (top < nt) tag(top++) = LUA_T_NIL; while (top < nt) tag(top++) = LUA_T_NIL;
top = nt; /* top could be bigger than newtop */ top = nt; /* top could be bigger than newtop */
} }
#define adjustC(nParams) adjust_top(CBase+nParams)
static void adjustC (int nParams)
/*
** Open a hole below "nelems" from the top.
*/
static void open_stack (int nelems)
{ {
adjust_top(CBase+nParams); int i;
for (i=0; i<nelems; i++)
*(top-i) = *(top-i-1);
incr_top;
} }
@@ -217,50 +213,55 @@ static StkId callC (lua_CFunction func, StkId base)
} }
/* /*
** Call the fallback for invalid functions (see do_call) ** Call the specified fallback, putting it on the stack below its arguments
*/ */
static void call_funcFB (Object *func, StkId base, int nResults, StkId whereRes) static void callFB (int fb)
{ {
StkId i; int nParams = luaI_fallBacks[fb].nParams;
/* open space for first parameter (func) */ open_stack(nParams);
for (i=top-stack; i>base; i--) *(top-nParams-1) = luaI_fallBacks[fb].function;
stack[i] = stack[i-1]; do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults);
top++;
stack[base] = *func;
do_call(&luaI_fallBacks[FB_FUNCTION].function, base, nResults, whereRes);
} }
/* /*
** Call a function (C or Lua). The parameters must be on the stack, ** Call a function (C or Lua). The parameters must be on the stack,
** between [stack+base,top). When returns, the results are on the stack, ** between [stack+base,top). The function to be called is at stack+base-1.
** between [stack+whereRes,top). The number of results is nResults, unless ** When returns, the results are on the stack, between [stack+base-1,top).
** nResults=MULT_RET. ** The number of results is nResults, unless nResults=MULT_RET.
*/ */
static void do_call (Object *func, StkId base, int nResults, StkId whereRes) static void do_call (StkId base, int nResults)
{ {
StkId firstResult; StkId firstResult;
Object *func = stack+base-1;
int i;
if (tag(func) == LUA_T_CFUNCTION) if (tag(func) == LUA_T_CFUNCTION)
{
tag(func) = LUA_T_CMARK;
firstResult = callC(fvalue(func), base); firstResult = callC(fvalue(func), base);
}
else if (tag(func) == LUA_T_FUNCTION) else if (tag(func) == LUA_T_FUNCTION)
firstResult = lua_execute(bvalue(func), base); {
tag(func) = LUA_T_MARK;
firstResult = lua_execute(func->value.tf->code, base);
}
else else
{ /* func is not a function */ { /* func is not a function */
call_funcFB(func, base, nResults, whereRes); /* Call the fallback for invalid functions */
open_stack((top-stack)-(base-1));
stack[base-1] = luaI_fallBacks[FB_FUNCTION].function;
do_call(base, nResults);
return; return;
} }
/* adjust the number of results */ /* adjust the number of results */
if (nResults != MULT_RET && top - (stack+firstResult) != nResults) if (nResults != MULT_RET && top - (stack+firstResult) != nResults)
adjust_top(firstResult+nResults); adjust_top(firstResult+nResults);
/* move results to the given position */ /* move results to base-1 (to erase parameters and function) */
if (firstResult != whereRes) base--;
{ nResults = top - (stack+firstResult); /* actual number of results */
int i; for (i=0; i<nResults; i++)
nResults = top - (stack+firstResult); /* actual number of results */ *(stack+base+i) = *(stack+firstResult+i);
for (i=0; i<nResults; i++) top -= firstResult-base;
*(stack+whereRes+i) = *(stack+firstResult+i);
top -= firstResult-whereRes;
}
} }
@@ -271,12 +272,12 @@ static void do_call (Object *func, StkId base, int nResults, StkId whereRes)
static void pushsubscript (void) static void pushsubscript (void)
{ {
if (tag(top-2) != LUA_T_ARRAY) if (tag(top-2) != LUA_T_ARRAY)
do_call(&luaI_fallBacks[FB_GETTABLE].function, (top-stack)-2, 1, (top-stack)-2); callFB(FB_GETTABLE);
else else
{ {
Object *h = lua_hashget(avalue(top-2), top-1); Object *h = lua_hashget(avalue(top-2), top-1);
if (h == NULL || tag(h) == LUA_T_NIL) if (h == NULL || tag(h) == LUA_T_NIL)
do_call(&luaI_fallBacks[FB_INDEX].function, (top-stack)-2, 1, (top-stack)-2); callFB(FB_INDEX);
else else
{ {
--top; --top;
@@ -292,7 +293,7 @@ static void pushsubscript (void)
static void storesubscript (void) static void storesubscript (void)
{ {
if (tag(top-3) != LUA_T_ARRAY) if (tag(top-3) != LUA_T_ARRAY)
do_call(&luaI_fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); callFB(FB_SETTABLE);
else else
{ {
Object *h = lua_hashdefine (avalue(top-3), top-2); Object *h = lua_hashdefine (avalue(top-3), top-2);
@@ -305,19 +306,63 @@ static void storesubscript (void)
/* /*
** Traverse all objects on stack ** Traverse all objects on stack
*/ */
void lua_travstack (void (*fn)(Object *)) void lua_travstack (int (*fn)(Object *))
{ {
Object *o; Object *o;
for (o = top-1; o >= stack; o--) for (o = top-1; o >= stack; o--)
fn (o); fn (o);
} }
/* /*
** Execute a protected call. If function is null compiles the pre-set input. ** Error messages and debug functions
** Leave nResults on the stack.
*/ */
static int do_protectedrun (Object *function, int nResults)
static void lua_message (char *s)
{
lua_pushstring(s);
callFB(FB_ERROR);
}
/*
** Reports an error, and jumps up to the available recover label
*/
void lua_error (char *s)
{
if (s) lua_message(s);
if (errorJmp)
longjmp(*errorJmp, 1);
else
{
fprintf (stderr, "lua: exit(1). Unable to recover\n");
exit(1);
}
}
lua_Object lua_stackedfunction (int level)
{
Object *p = top;
while (--p >= stack)
if (p->tag == LUA_T_MARK || p->tag == LUA_T_CMARK)
if (level-- == 0)
return Ref(p);
return LUA_NOOBJECT;
}
int lua_currentline (lua_Object func)
{
Object *f = Address(func);
return (f+1 < top && (f+1)->tag == LUA_T_LINE) ? (f+1)->value.i : -1;
}
/*
** Execute a protected call. Assumes that function is at CBase and
** parameters are on top of it. Leave nResults on the stack.
*/
static int do_protectedrun (int nResults)
{ {
jmp_buf myErrorJmp; jmp_buf myErrorJmp;
int status; int status;
@@ -326,13 +371,13 @@ static int do_protectedrun (Object *function, int nResults)
errorJmp = &myErrorJmp; errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp) == 0) if (setjmp(myErrorJmp) == 0)
{ {
do_call(function, CBase, nResults, CBase); do_call(CBase+1, nResults);
CnResults = (top-stack) - CBase; /* number of results */ CnResults = (top-stack) - CBase; /* number of results */
CBase += CnResults; /* incorporate results on the stack */ CBase += CnResults; /* incorporate results on the stack */
status = 0; status = 0;
} }
else else
{ { /* an error occurred: restore CBase and top */
CBase = oldCBase; CBase = oldCBase;
top = stack+CBase; top = stack+CBase;
status = 1; status = 1;
@@ -344,27 +389,30 @@ static int do_protectedrun (Object *function, int nResults)
static int do_protectedmain (void) static int do_protectedmain (void)
{ {
Byte *code = NULL; TFunc tf;
int status; int status;
StkId oldCBase = CBase;
jmp_buf myErrorJmp; jmp_buf myErrorJmp;
jmp_buf *oldErr = errorJmp; jmp_buf *oldErr = errorJmp;
errorJmp = &myErrorJmp; errorJmp = &myErrorJmp;
adjustC(1); /* one slot for the pseudo-function */
stack[CBase].tag = LUA_T_FUNCTION;
stack[CBase].value.tf = &tf;
tf.lineDefined = 0;
tf.fileName = lua_parsedfile;
tf.code = NULL;
if (setjmp(myErrorJmp) == 0) if (setjmp(myErrorJmp) == 0)
{ {
Object f; lua_parse(&tf);
lua_parse(&code); status = do_protectedrun(0);
tag(&f) = LUA_T_FUNCTION; bvalue(&f) = code;
do_call(&f, CBase, 0, CBase);
status = 0;
} }
else else
{
status = 1; status = 1;
if (code) adjustC(0); /* erase extra slot */
luaI_free(code); }
errorJmp = oldErr; errorJmp = oldErr;
CBase = oldCBase; if (tf.code)
top = stack+CBase; luaI_free(tf.code);
return status; return status;
} }
@@ -377,14 +425,20 @@ int lua_callfunction (lua_Object function)
if (function == LUA_NOOBJECT) if (function == LUA_NOOBJECT)
return 1; return 1;
else else
return do_protectedrun (Address(function), MULT_RET); {
open_stack((top-stack)-CBase);
stack[CBase] = *Address(function);
return do_protectedrun (MULT_RET);
}
} }
int lua_call (char *funcname) int lua_call (char *funcname)
{ {
Word n = luaI_findsymbolbyname(funcname); Word n = luaI_findsymbolbyname(funcname);
return do_protectedrun(&s_object(n), MULT_RET); open_stack((top-stack)-CBase);
stack[CBase] = s_object(n);
return do_protectedrun(MULT_RET);
} }
@@ -413,12 +467,7 @@ int lua_dofile (char *filename)
int lua_dostring (char *string) int lua_dostring (char *string)
{ {
int status; int status;
char *message = lua_openstring(string); lua_openstring(string);
if (message)
{
lua_message(message);
return 1;
}
status = do_protectedmain(); status = do_protectedmain();
lua_closestring(); lua_closestring();
return status; return status;
@@ -430,12 +479,15 @@ int lua_dostring (char *string)
*/ */
lua_Object lua_setfallback (char *name, lua_CFunction fallback) lua_Object lua_setfallback (char *name, lua_CFunction fallback)
{ {
static Object func = {LUA_T_CFUNCTION, luaI_setfallback}; adjustC(1); /* one slot for the pseudo-function */
adjustC(0); stack[CBase].tag = LUA_T_CFUNCTION;
stack[CBase].value.f = luaI_setfallback;
lua_pushstring(name); lua_pushstring(name);
lua_pushcfunction(fallback); lua_pushcfunction(fallback);
do_protectedrun(&func, 1); if (do_protectedrun(1) == 0)
return (Ref(top-1)); return (Ref(top-1));
else
return LUA_NOOBJECT;
} }
@@ -497,7 +549,7 @@ lua_Object lua_createtable (void)
adjustC(0); adjustC(0);
avalue(top) = lua_createarray(0); avalue(top) = lua_createarray(0);
tag(top) = LUA_T_ARRAY; tag(top) = LUA_T_ARRAY;
top++; incr_top;
CBase++; /* incorporate object in the stack */ CBase++; /* incorporate object in the stack */
return Ref(top-1); return Ref(top-1);
} }
@@ -519,9 +571,9 @@ lua_Object lua_getparam (int number)
*/ */
real lua_getnumber (lua_Object object) real lua_getnumber (lua_Object object)
{ {
if (object == LUA_NOOBJECT || tag(Address(object)) == LUA_T_NIL) return 0.0; if (object == LUA_NOOBJECT) return 0.0;
if (tonumber (Address(object))) return 0.0; if (tonumber (Address(object))) return 0.0;
else return (nvalue(Address(object))); else return (nvalue(Address(object)));
} }
/* /*
@@ -529,7 +581,7 @@ real lua_getnumber (lua_Object object)
*/ */
char *lua_getstring (lua_Object object) char *lua_getstring (lua_Object object)
{ {
if (object == LUA_NOOBJECT || tag(Address(object)) == LUA_T_NIL) return NULL; if (object == LUA_NOOBJECT) return NULL;
if (tostring (Address(object))) return NULL; if (tostring (Address(object))) return NULL;
else return (svalue(Address(object))); else return (svalue(Address(object)));
} }
@@ -559,7 +611,7 @@ lua_Object lua_getlocked (int ref)
{ {
adjustC(0); adjustC(0);
*top = *luaI_getlocked(ref); *top = *luaI_getlocked(ref);
top++; incr_top;
CBase++; /* incorporate object in the stack */ CBase++; /* incorporate object in the stack */
return Ref(top-1); return Ref(top-1);
} }
@@ -567,9 +619,8 @@ lua_Object lua_getlocked (int ref)
void lua_pushlocked (int ref) void lua_pushlocked (int ref)
{ {
lua_checkstack(top-stack+1);
*top = *luaI_getlocked(ref); *top = *luaI_getlocked(ref);
top++; incr_top;
} }
@@ -580,15 +631,16 @@ int lua_lock (void)
} }
/* /*
** Get a global object. Return the object handle or NULL on error. ** Get a global object.
*/ */
lua_Object lua_getglobal (char *name) lua_Object lua_getglobal (char *name)
{ {
Word n = luaI_findsymbolbyname(name); Word n = luaI_findsymbolbyname(name);
adjustC(0); adjustC(0);
*top = s_object(n); *top = s_object(n);
top++; incr_top;
CBase++; /* incorporate object in the stack */ CBase++; /* incorporate object in the stack */
return Ref(top-1); return Ref(top-1);
} }
@@ -608,8 +660,8 @@ void lua_storeglobal (char *name)
*/ */
void lua_pushnil (void) void lua_pushnil (void)
{ {
lua_checkstack(top-stack+1); tag(top) = LUA_T_NIL;
tag(top++) = LUA_T_NIL; incr_top;
} }
/* /*
@@ -617,8 +669,8 @@ void lua_pushnil (void)
*/ */
void lua_pushnumber (real n) void lua_pushnumber (real n)
{ {
lua_checkstack(top-stack+1); tag(top) = LUA_T_NUMBER; nvalue(top) = n;
tag(top) = LUA_T_NUMBER; nvalue(top++) = n; incr_top;
} }
/* /*
@@ -626,10 +678,9 @@ void lua_pushnumber (real n)
*/ */
void lua_pushstring (char *s) void lua_pushstring (char *s)
{ {
lua_checkstack(top-stack+1);
tsvalue(top) = lua_createstring(s); tsvalue(top) = lua_createstring(s);
tag(top) = LUA_T_STRING; tag(top) = LUA_T_STRING;
top++; incr_top;
} }
/* /*
@@ -637,10 +688,9 @@ void lua_pushstring (char *s)
*/ */
void lua_pushliteral (char *s) void lua_pushliteral (char *s)
{ {
lua_checkstack(top-stack+1); tsvalue(top) = lua_constant[luaI_findconstantbyname(s)];
tsvalue(top) = lua_constant[luaI_findconstant(lua_constcreate(s))];
tag(top) = LUA_T_STRING; tag(top) = LUA_T_STRING;
top++; incr_top;
} }
/* /*
@@ -648,8 +698,8 @@ void lua_pushliteral (char *s)
*/ */
void lua_pushcfunction (lua_CFunction fn) void lua_pushcfunction (lua_CFunction fn)
{ {
lua_checkstack(top-stack+1); tag(top) = LUA_T_CFUNCTION; fvalue(top) = fn;
tag(top) = LUA_T_CFUNCTION; fvalue(top++) = fn; incr_top;
} }
/* /*
@@ -658,8 +708,8 @@ void lua_pushcfunction (lua_CFunction fn)
void lua_pushusertag (void *u, int tag) void lua_pushusertag (void *u, int tag)
{ {
if (tag < LUA_T_USERDATA) return; if (tag < LUA_T_USERDATA) return;
lua_checkstack(top-stack+1); tag(top) = tag; uvalue(top) = u;
tag(top) = tag; uvalue(top++) = u; incr_top;
} }
/* /*
@@ -667,8 +717,8 @@ void lua_pushusertag (void *u, int tag)
*/ */
void lua_pushobject (lua_Object o) void lua_pushobject (lua_Object o)
{ {
lua_checkstack(top-stack+1); *top = *Address(o);
*top++ = *Address(o); incr_top;
} }
/* /*
@@ -676,8 +726,8 @@ void lua_pushobject (lua_Object o)
*/ */
void luaI_pushobject (Object *o) void luaI_pushobject (Object *o)
{ {
lua_checkstack(top-stack+1); *top = *o;
*top++ = *o; incr_top;
} }
int lua_type (lua_Object o) int lua_type (lua_Object o)
@@ -691,15 +741,16 @@ int lua_type (lua_Object o)
void luaI_gcFB (Object *o) void luaI_gcFB (Object *o)
{ {
*(top++) = *o; *top = *o;
do_call(&luaI_fallBacks[FB_GC].function, (top-stack)-1, 0, (top-stack)-1); incr_top;
callFB(FB_GC);
} }
static void call_arith (char *op) static void call_arith (char *op)
{ {
lua_pushstring(op); lua_pushstring(op);
do_call(&luaI_fallBacks[FB_ARITH].function, (top-stack)-3, 1, (top-stack)-3); callFB(FB_ARITH);
} }
static void comparison (lua_Type tag_less, lua_Type tag_equal, static void comparison (lua_Type tag_less, lua_Type tag_equal,
@@ -713,7 +764,7 @@ static void comparison (lua_Type tag_less, lua_Type tag_equal,
else if (tostring(l) || tostring(r)) else if (tostring(l) || tostring(r))
{ {
lua_pushstring(op); lua_pushstring(op);
do_call(&luaI_fallBacks[FB_ORDER].function, (top-stack)-3, 1, (top-stack)-3); callFB(FB_ORDER);
return; return;
} }
else else
@@ -732,26 +783,28 @@ static void comparison (lua_Type tag_less, lua_Type tag_equal,
*/ */
static StkId lua_execute (Byte *pc, StkId base) static StkId lua_execute (Byte *pc, StkId base)
{ {
lua_checkstack(STACKGAP+MAX_TEMPS+base);
while (1) while (1)
{ {
OpCode opcode; OpCode opcode;
switch (opcode = (OpCode)*pc++) switch (opcode = (OpCode)*pc++)
{ {
case PUSHNIL: tag(top++) = LUA_T_NIL; break; case PUSHNIL: tag(top) = LUA_T_NIL; incr_top; break;
case PUSH0: case PUSH1: case PUSH2: case PUSH0: case PUSH1: case PUSH2:
tag(top) = LUA_T_NUMBER; tag(top) = LUA_T_NUMBER;
nvalue(top++) = opcode-PUSH0; nvalue(top) = opcode-PUSH0;
incr_top;
break; break;
case PUSHBYTE: tag(top) = LUA_T_NUMBER; nvalue(top++) = *pc++; break; case PUSHBYTE:
tag(top) = LUA_T_NUMBER; nvalue(top) = *pc++; incr_top; break;
case PUSHWORD: case PUSHWORD:
{ {
CodeWord code; CodeWord code;
get_word(code,pc); get_word(code,pc);
tag(top) = LUA_T_NUMBER; nvalue(top++) = code.w; tag(top) = LUA_T_NUMBER; nvalue(top) = code.w;
incr_top;
} }
break; break;
@@ -759,7 +812,8 @@ static StkId lua_execute (Byte *pc, StkId base)
{ {
CodeFloat code; CodeFloat code;
get_float(code,pc); get_float(code,pc);
tag(top) = LUA_T_NUMBER; nvalue(top++) = code.f; tag(top) = LUA_T_NUMBER; nvalue(top) = code.f;
incr_top;
} }
break; break;
@@ -767,7 +821,8 @@ static StkId lua_execute (Byte *pc, StkId base)
{ {
CodeWord code; CodeWord code;
get_word(code,pc); get_word(code,pc);
tag(top) = LUA_T_STRING; tsvalue(top++) = lua_constant[code.w]; tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[code.w];
incr_top;
} }
break; break;
@@ -775,22 +830,27 @@ static StkId lua_execute (Byte *pc, StkId base)
{ {
CodeCode code; CodeCode code;
get_code(code,pc); get_code(code,pc);
tag(top) = LUA_T_FUNCTION; bvalue(top++) = code.b; luaI_insertfunction(code.tf); /* may take part in GC */
top->tag = LUA_T_FUNCTION;
top->value.tf = code.tf;
incr_top;
} }
break; break;
case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2:
case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5:
case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8:
case PUSHLOCAL9: *top++ = *((stack+base) + (int)(opcode-PUSHLOCAL0)); break; case PUSHLOCAL9:
*top = *((stack+base) + (int)(opcode-PUSHLOCAL0)); incr_top; break;
case PUSHLOCAL: *top++ = *((stack+base) + (*pc++)); break; case PUSHLOCAL: *top = *((stack+base) + (*pc++)); incr_top; break;
case PUSHGLOBAL: case PUSHGLOBAL:
{ {
CodeWord code; CodeWord code;
get_word(code,pc); get_word(code,pc);
*top++ = s_object(code.w); *top = s_object(code.w);
incr_top;
} }
break; break;
@@ -803,9 +863,11 @@ static StkId lua_execute (Byte *pc, StkId base)
Object receiver = *(top-1); Object receiver = *(top-1);
CodeWord code; CodeWord code;
get_word(code,pc); get_word(code,pc);
tag(top) = LUA_T_STRING; tsvalue(top++) = lua_constant[code.w]; tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[code.w];
incr_top;
pushsubscript(); pushsubscript();
*(top++) = receiver; *top = receiver;
incr_top;
break; break;
} }
@@ -835,11 +897,12 @@ static StkId lua_execute (Byte *pc, StkId base)
int n = *pc++; int n = *pc++;
if (tag(top-3-n) != LUA_T_ARRAY) if (tag(top-3-n) != LUA_T_ARRAY)
{ {
lua_checkstack(top+2);
*(top+1) = *(top-1); *(top+1) = *(top-1);
*(top) = *(top-2-n); *(top) = *(top-2-n);
*(top-1) = *(top-3-n); *(top-1) = *(top-3-n);
top += 2; top += 2;
do_call(&luaI_fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); callFB(FB_SETTABLE);
} }
else else
{ {
@@ -899,7 +962,7 @@ static StkId lua_execute (Byte *pc, StkId base)
get_word(size,pc); get_word(size,pc);
avalue(top) = lua_createarray(size.w); avalue(top) = lua_createarray(size.w);
tag(top) = LUA_T_ARRAY; tag(top) = LUA_T_ARRAY;
top++; incr_top;
} }
break; break;
@@ -993,7 +1056,7 @@ static StkId lua_execute (Byte *pc, StkId base)
Object *l = top-2; Object *l = top-2;
Object *r = top-1; Object *r = top-1;
if (tostring(r) || tostring(l)) if (tostring(r) || tostring(l))
do_call(&luaI_fallBacks[FB_CONCAT].function, (top-stack)-2, 1, (top-stack)-2); callFB(FB_CONCAT);
else else
{ {
tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r)));
@@ -1005,7 +1068,8 @@ static StkId lua_execute (Byte *pc, StkId base)
case MINUSOP: case MINUSOP:
if (tonumber(top-1)) if (tonumber(top-1))
{ {
tag(top++) = LUA_T_NIL; tag(top) = LUA_T_NIL;
incr_top;
call_arith("unm"); call_arith("unm");
} }
else else
@@ -1073,9 +1137,8 @@ static StkId lua_execute (Byte *pc, StkId base)
{ {
int nParams = *(pc++); int nParams = *(pc++);
int nResults = *(pc++); int nResults = *(pc++);
Object *func = top-1-nParams; /* function is below parameters */
StkId newBase = (top-stack)-nParams; StkId newBase = (top-stack)-nParams;
do_call(func, newBase, nResults, newBase-1); do_call(newBase, nResults);
} }
break; break;
@@ -1085,27 +1148,20 @@ static StkId lua_execute (Byte *pc, StkId base)
case RETCODE: case RETCODE:
return base+*pc; return base+*pc;
case SETFUNCTION:
{
CodeCode file;
CodeWord func;
get_code(file,pc);
get_word(func,pc);
lua_pushfunction ((char *)file.b, func.w);
}
break;
case SETLINE: case SETLINE:
{ {
CodeWord code; CodeWord code;
get_word(code,pc); get_word(code,pc);
lua_debugline = code.w; if ((stack+base-1)->tag != LUA_T_LINE)
{
/* open space for LINE value */
open_stack((top-stack)-base);
base++;
(stack+base-1)->tag = LUA_T_LINE;
}
(stack+base-1)->value.i = code.w;
break;
} }
break;
case RESET:
lua_popfunction ();
break;
default: default:
lua_error ("internal error - opcode doesn't match"); lua_error ("internal error - opcode doesn't match");

View File

@@ -1,6 +1,6 @@
/* /*
** TeCGraf - PUC-Rio ** TeCGraf - PUC-Rio
** $Id: opcode.h,v 3.9 1994/11/23 14:31:11 roberto Stab $ ** $Id: opcode.h,v 3.13 1995/10/17 11:58:41 roberto Exp roberto $
*/ */
#ifndef opcode_h #ifndef opcode_h
@@ -9,10 +9,7 @@
#include "lua.h" #include "lua.h"
#include "types.h" #include "types.h"
#include "tree.h" #include "tree.h"
#include "func.h"
#ifndef STACKGAP
#define STACKGAP 128
#endif
#ifndef real #ifndef real
#define real float #define real float
@@ -20,8 +17,6 @@
#define FIELDS_PER_FLUSH 40 #define FIELDS_PER_FLUSH 40
#define MAX_TEMPS 20
typedef enum typedef enum
{ {
@@ -73,9 +68,7 @@ typedef enum
CALLFUNC, CALLFUNC,
RETCODE0, RETCODE0,
RETCODE, RETCODE,
SETFUNCTION, SETLINE
SETLINE,
RESET
} OpCode; } OpCode;
#define MULT_RET 255 #define MULT_RET 255
@@ -89,9 +82,10 @@ typedef union
Cfunction f; Cfunction f;
real n; real n;
TaggedString *ts; TaggedString *ts;
Byte *b; TFunc *tf;
struct Hash *a; struct Hash *a;
void *u; void *u;
int i;
} Value; } Value;
typedef struct Object typedef struct Object
@@ -110,7 +104,6 @@ typedef struct
#define nvalue(o) ((o)->value.n) #define nvalue(o) ((o)->value.n)
#define svalue(o) ((o)->value.ts->str) #define svalue(o) ((o)->value.ts->str)
#define tsvalue(o) ((o)->value.ts) #define tsvalue(o) ((o)->value.ts)
#define bvalue(o) ((o)->value.b)
#define avalue(o) ((o)->value.a) #define avalue(o) ((o)->value.a)
#define fvalue(o) ((o)->value.f) #define fvalue(o) ((o)->value.f)
#define uvalue(o) ((o)->value.u) #define uvalue(o) ((o)->value.u)
@@ -120,7 +113,6 @@ typedef struct
#define s_tag(i) (tag(&s_object(i))) #define s_tag(i) (tag(&s_object(i)))
#define s_nvalue(i) (nvalue(&s_object(i))) #define s_nvalue(i) (nvalue(&s_object(i)))
#define s_svalue(i) (svalue(&s_object(i))) #define s_svalue(i) (svalue(&s_object(i)))
#define s_bvalue(i) (bvalue(&s_object(i)))
#define s_avalue(i) (avalue(&s_object(i))) #define s_avalue(i) (avalue(&s_object(i)))
#define s_fvalue(i) (fvalue(&s_object(i))) #define s_fvalue(i) (fvalue(&s_object(i)))
#define s_uvalue(i) (uvalue(&s_object(i))) #define s_uvalue(i) (uvalue(&s_object(i)))
@@ -143,7 +135,7 @@ typedef union
typedef union typedef union
{ {
struct {char c1; char c2; char c3; char c4;} m; struct {char c1; char c2; char c3; char c4;} m;
Byte *b; TFunc *tf;
} CodeCode; } CodeCode;
#define get_code(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\ #define get_code(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\
code.m.c3 = *pc++; code.m.c4 = *pc++;} code.m.c3 = *pc++; code.m.c4 = *pc++;}
@@ -155,8 +147,9 @@ char *lua_strdup (char *l);
void lua_setinput (Input fn); /* from "lex.c" module */ void lua_setinput (Input fn); /* from "lex.c" module */
char *lua_lasttext (void); /* from "lex.c" module */ char *lua_lasttext (void); /* from "lex.c" module */
int yylex (void); /* from "lex.c" module */ int yylex (void); /* from "lex.c" module */
void lua_parse (Byte **code); /* from "lua.stx" module */ void lua_parse (TFunc *tf); /* from "lua.stx" module */
void lua_travstack (void (*fn)(Object *)); void luaI_codedebugline (int line); /* from "lua.stx" module */
void lua_travstack (int (*fn)(Object *));
Object *luaI_Address (lua_Object o); Object *luaI_Address (lua_Object o);
void luaI_pushobject (Object *o); void luaI_pushobject (Object *o);
void luaI_gcFB (Object *o); void luaI_gcFB (Object *o);

163
strlib.c
View File

@@ -3,9 +3,10 @@
** String library to LUA ** String library to LUA
*/ */
char *rcs_strlib="$Id: strlib.c,v 1.11 1995/02/02 20:05:37 roberto Exp roberto $"; char *rcs_strlib="$Id: strlib.c,v 1.13 1995/10/09 12:49:21 roberto Exp roberto $";
#include <string.h> #include <string.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
@@ -13,9 +14,31 @@ char *rcs_strlib="$Id: strlib.c,v 1.11 1995/02/02 20:05:37 roberto Exp roberto $
#include "lualib.h" #include "lualib.h"
static char *newstring (lua_Object o) void lua_arg_error(char *funcname)
{
char buff[100];
sprintf(buff, "incorrect arguments to function `%s'", funcname);
lua_error(buff);
}
char *lua_check_string (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
if (!(lua_isstring(o) || lua_isnumber(o)))
lua_arg_error(funcname);
return lua_getstring(o);
}
float lua_check_number (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
if (!lua_isnumber(o))
lua_arg_error(funcname);
return lua_getnumber(o);
}
static char *newstring (char *s)
{ {
char *s = lua_getstring(o);
char *ns = (char *)malloc(strlen(s)+1); char *ns = (char *)malloc(strlen(s)+1);
if (ns == 0) if (ns == 0)
lua_error("not enough memory for new string"); lua_error("not enough memory for new string");
@@ -31,34 +54,17 @@ static char *newstring (lua_Object o)
*/ */
static void str_find (void) static void str_find (void)
{ {
char *s1, *s2, *f; char *s1 = lua_check_string(1, "strfind");
int init; char *s2 = lua_check_string(2, "strfind");
lua_Object o1 = lua_getparam (1); int init = (lua_getparam(3) == LUA_NOOBJECT) ? 0 :
lua_Object o2 = lua_getparam (2); (int)lua_check_number(3, "strfind")-1;
lua_Object o3 = lua_getparam (3); char *f = strstr(s1+init,s2);
lua_Object o4 = lua_getparam (4);
if (!lua_isstring(o1) || !lua_isstring(o2))
lua_error ("incorrect arguments to function `strfind'");
if (o3 == LUA_NOOBJECT)
init = 0;
else if (lua_isnumber(o3))
init = lua_getnumber(o3)-1;
else
{
lua_error ("incorrect arguments to function `strfind'");
return; /* to avoid warnings */
}
s1 = lua_getstring(o1);
s2 = lua_getstring(o2);
f = strstr(s1+init,s2);
if (f != NULL) if (f != NULL)
{ {
int pos = f-s1+1; int pos = f-s1+1;
if (o4 == LUA_NOOBJECT) if (lua_getparam (4) == LUA_NOOBJECT)
lua_pushnumber (pos); lua_pushnumber (pos);
else if (!lua_isnumber(o4)) else if ((int)lua_check_number(4, "strfind") >= pos+strlen(s2)-1)
lua_error ("incorrect arguments to function `strfind'");
else if ((int)lua_getnumber(o4) >= pos+strlen(s2)-1)
lua_pushnumber (pos); lua_pushnumber (pos);
else else
lua_pushnil(); lua_pushnil();
@@ -74,10 +80,8 @@ static void str_find (void)
*/ */
static void str_len (void) static void str_len (void)
{ {
lua_Object o = lua_getparam (1); char *s = lua_check_string(1, "strlen");
if (!lua_isstring(o)) lua_pushnumber(strlen(s));
lua_error ("incorrect arguments to function `strlen'");
lua_pushnumber(strlen(lua_getstring(o)));
} }
@@ -88,25 +92,35 @@ static void str_len (void)
*/ */
static void str_sub (void) static void str_sub (void)
{ {
int start, end; char *s = lua_check_string(1, "strsub");
char *s; int start = (int)lua_check_number(2, "strsub");
lua_Object o1 = lua_getparam (1); int end = (lua_getparam(3) == LUA_NOOBJECT) ? strlen(s) :
lua_Object o2 = lua_getparam (2); (int)lua_check_number(3, "strsub");
lua_Object o3 = lua_getparam (3);
if (!lua_isstring(o1) || !lua_isnumber(o2))
lua_error ("incorrect arguments to function `strsub'");
if (o3 != LUA_NOOBJECT && !lua_isnumber(o3))
lua_error ("incorrect third argument to function `strsub'");
s = newstring(o1);
start = lua_getnumber (o2);
end = o3 == LUA_NOOBJECT ? strlen(s) : lua_getnumber (o3);
if (end < start || start < 1 || end > strlen(s)) if (end < start || start < 1 || end > strlen(s))
lua_pushliteral(""); lua_pushliteral("");
else else
{ {
char temp = s[end];
s[end] = 0; s[end] = 0;
lua_pushstring (&s[start-1]); lua_pushstring (&s[start-1]);
s[end] = temp;
} }
}
/*
** Convert a string according to given function.
*/
typedef int (*strfunc)(int s);
static void str_apply (strfunc f, char *funcname)
{
char *s, *c;
c = s = newstring(lua_check_string(1, funcname));
while (*c != 0)
{
*c = f(*c);
c++;
}
lua_pushstring(s);
free(s); free(s);
} }
@@ -117,19 +131,8 @@ static void str_sub (void)
*/ */
static void str_lower (void) static void str_lower (void)
{ {
char *s, *c; str_apply(tolower, "strlower");
lua_Object o = lua_getparam (1); }
if (!lua_isstring(o))
lua_error ("incorrect arguments to function `strlower'");
c = s = newstring(o);
while (*c != 0)
{
*c = tolower(*c);
c++;
}
lua_pushstring(s);
free(s);
}
/* /*
@@ -139,20 +142,40 @@ static void str_lower (void)
*/ */
static void str_upper (void) static void str_upper (void)
{ {
char *s, *c; str_apply(toupper, "strupper");
lua_Object o = lua_getparam (1); }
if (!lua_isstring(o))
lua_error ("incorrect arguments to function `strlower'");
c = s = newstring(o);
while (*c != 0)
{
*c = toupper(*c);
c++;
}
lua_pushstring(s);
free(s);
}
/*
** get ascii value of a character in a string
*/
static void str_ascii (void)
{
char *s = lua_check_string(1, "ascii");
lua_Object o2 = lua_getparam(2);
int pos;
pos = (o2 == LUA_NOOBJECT) ? 0 : (int)lua_check_number(2, "ascii")-1;
if (pos<0 || pos>=strlen(s))
lua_arg_error("ascii");
lua_pushnumber(s[pos]);
}
/*
** converts one or more integers to chars in a string
*/
#define maxparams 50
static void str_int2str (void)
{
char s[maxparams+1];
int i = 0;
while (lua_getparam(++i) != LUA_NOOBJECT)
{
if (i > maxparams)
lua_error("too many parameters to function `int2str'");
s[i-1] = (int)lua_check_number(i, "int2str");
}
s[i-1] = 0;
lua_pushstring(s);
}
/* /*
** Open string library ** Open string library
@@ -164,4 +187,6 @@ void strlib_open (void)
lua_register ("strsub", str_sub); lua_register ("strsub", str_sub);
lua_register ("strlower", str_lower); lua_register ("strlower", str_lower);
lua_register ("strupper", str_upper); lua_register ("strupper", str_upper);
lua_register ("ascii", str_ascii);
lua_register ("int2str", str_int2str);
} }

129
table.c
View File

@@ -3,38 +3,34 @@
** Module to control static tables ** Module to control static tables
*/ */
char *rcs_table="$Id: table.c,v 2.27 1995/01/13 22:11:12 roberto Exp celes $"; char *rcs_table="$Id: table.c,v 2.37 1995/10/26 14:21:56 roberto Exp roberto $";
#include <string.h> /*#include <string.h>*/
#include "mem.h" #include "mem.h"
#include "opcode.h" #include "opcode.h"
#include "tree.h" #include "tree.h"
#include "hash.h" #include "hash.h"
#include "inout.h"
#include "table.h" #include "table.h"
#include "inout.h"
#include "lua.h" #include "lua.h"
#include "fallback.h" #include "fallback.h"
#include "luadebug.h"
#define BUFFER_BLOCK 256 #define BUFFER_BLOCK 256
Symbol *lua_table; Symbol *lua_table = NULL;
static Word lua_ntable = 0; static Word lua_ntable = 0;
static Long lua_maxsymbol = 0; static Long lua_maxsymbol = 0;
TaggedString **lua_constant; TaggedString **lua_constant = NULL;
static Word lua_nconstant = 0; static Word lua_nconstant = 0;
static Long lua_maxconstant = 0; static Long lua_maxconstant = 0;
#define GARBAGE_BLOCK 1024
#define MAXFILE 20 #define MIN_GARBAGE_BLOCK (GARBAGE_BLOCK/2)
char *lua_file[MAXFILE];
int lua_nfile;
#define GARBAGE_BLOCK 256
#define MIN_GARBAGE_BLOCK 10
static void lua_nextvar (void); static void lua_nextvar (void);
static void setglobal (void); static void setglobal (void);
@@ -117,9 +113,8 @@ Word luaI_findsymbolbyname (char *name)
/* /*
** Given a name, search it at constant table and return its index. If not ** Given a tree node, check it is has a correspondent constant index. If not,
** found, allocate it. ** allocate it.
** On error, return -1.
*/ */
Word luaI_findconstant (TreeNode *t) Word luaI_findconstant (TreeNode *t)
{ {
@@ -144,26 +139,38 @@ Word luaI_findconstant (TreeNode *t)
} }
Word luaI_findconstantbyname (char *name)
{
return luaI_findconstant(lua_constcreate(name));
}
/* /*
** Traverse symbol table objects ** Traverse symbol table objects
*/ */
void lua_travsymbol (void (*fn)(Object *)) static char *lua_travsymbol (int (*fn)(Object *))
{ {
Word i; Word i;
for (i=0; i<lua_ntable; i++) for (i=0; i<lua_ntable; i++)
fn(&s_object(i)); if (fn(&s_object(i)))
return luaI_nodebysymbol(i)->ts.str;
return NULL;
} }
/* /*
** Mark an object if it is a string or a unmarked array. ** Mark an object if it is a string or a unmarked array.
*/ */
void lua_markobject (Object *o) int lua_markobject (Object *o)
{ {
if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked) if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked)
tsvalue(o)->marked = 1; tsvalue(o)->marked = 1;
else if (tag(o) == LUA_T_ARRAY) else if (tag(o) == LUA_T_ARRAY)
lua_hashmark (avalue(o)); 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;
} }
@@ -180,79 +187,50 @@ void lua_pack (void)
lua_travstack(lua_markobject); /* mark stack objects */ lua_travstack(lua_markobject); /* mark stack objects */
lua_travsymbol(lua_markobject); /* mark symbol table objects */ lua_travsymbol(lua_markobject); /* mark symbol table objects */
luaI_travlock(lua_markobject); /* mark locked objects */ luaI_travlock(lua_markobject); /* mark locked objects */
luaI_travfallbacks(lua_markobject); /* mark fallbacks */
recovered += lua_strcollector(); recovered += lua_strcollector();
recovered += lua_hashcollector(); recovered += lua_hashcollector();
recovered += luaI_funccollector();
nentity = 0; /* reset counter */ nentity = 0; /* reset counter */
block=(16*block-7*recovered)/12; /* adapt block size */ block=(16*block-7*recovered)/12; /* adapt block size */
if (block < MIN_GARBAGE_BLOCK) block = MIN_GARBAGE_BLOCK; if (block < MIN_GARBAGE_BLOCK) block = MIN_GARBAGE_BLOCK;
} }
/*
** 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 error message on error.
*/
char *lua_addfile (char *fn)
{
if (lua_nfile >= MAXFILE)
return "too many files";
if ((lua_file[lua_nfile++] = luaI_strdup (fn)) == NULL)
return "not enough memory";
return NULL;
}
/*
** Delete a file from file stack
*/
int lua_delfile (void)
{
luaI_free(lua_file[--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 ** Internal function: return next global variable
*/ */
static void lua_nextvar (void) static void lua_nextvar (void)
{ {
char *varname; Word next;
TreeNode *next;
lua_Object o = lua_getparam(1); lua_Object o = lua_getparam(1);
if (o == LUA_NOOBJECT) if (o == LUA_NOOBJECT)
lua_reportbug("too few arguments to function `nextvar'"); lua_error("too few arguments to function `nextvar'");
if (lua_getparam(2) != LUA_NOOBJECT) if (lua_getparam(2) != LUA_NOOBJECT)
lua_reportbug("too many arguments to function `nextvar'"); lua_error("too many arguments to function `nextvar'");
if (lua_isnil(o)) if (lua_isnil(o))
varname = NULL; next = 0;
else if (!lua_isstring(o)) else if (!lua_isstring(o))
{ {
lua_reportbug("incorrect argument to function `nextvar'"); lua_error("incorrect argument to function `nextvar'");
return; /* to avoid warnings */ return; /* to avoid warnings */
} }
else else
varname = lua_getstring(o); next = luaI_findsymbolbyname(lua_getstring(o)) + 1;
next = lua_varnext(varname); while (next < lua_ntable && s_tag(next) == LUA_T_NIL) next++;
if (next == NULL) if (next >= lua_ntable)
{ {
lua_pushnil(); lua_pushnil();
lua_pushnil(); lua_pushnil();
} }
else else
{ {
TreeNode *t = luaI_nodebysymbol(next);
Object name; Object name;
tag(&name) = LUA_T_STRING; tag(&name) = LUA_T_STRING;
tsvalue(&name) = &(next->ts); tsvalue(&name) = &(t->ts);
luaI_pushobject(&name); luaI_pushobject(&name);
luaI_pushobject(&s_object(next->varindex)); luaI_pushobject(&s_object(next));
} }
} }
@@ -262,7 +240,7 @@ static void setglobal (void)
lua_Object name = lua_getparam(1); lua_Object name = lua_getparam(1);
lua_Object value = lua_getparam(2); lua_Object value = lua_getparam(2);
if (!lua_isstring(name)) if (!lua_isstring(name))
lua_reportbug("incorrect argument to function `setglobal'"); lua_error("incorrect argument to function `setglobal'");
lua_pushobject(value); lua_pushobject(value);
lua_storeglobal(lua_getstring(name)); lua_storeglobal(lua_getstring(name));
} }
@@ -272,6 +250,33 @@ static void getglobal (void)
{ {
lua_Object name = lua_getparam(1); lua_Object name = lua_getparam(1);
if (!lua_isstring(name)) if (!lua_isstring(name))
lua_reportbug("incorrect argument to function `getglobal'"); lua_error("incorrect argument to function `getglobal'");
lua_pushobject(lua_getglobal(lua_getstring(name))); lua_pushobject(lua_getglobal(lua_getstring(name)));
} }
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 *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 "";
}

10
table.h
View File

@@ -1,7 +1,7 @@
/* /*
** Module to control static tables ** Module to control static tables
** TeCGraf - PUC-Rio ** TeCGraf - PUC-Rio
** $Id: table.h,v 2.9 1994/11/23 14:31:11 roberto Stab roberto $ ** $Id: table.h,v 2.12 1995/10/17 11:58:41 roberto Exp roberto $
*/ */
#ifndef table_h #ifndef table_h
@@ -21,11 +21,9 @@ void lua_initconstant (void);
Word luaI_findsymbolbyname (char *name); Word luaI_findsymbolbyname (char *name);
Word luaI_findsymbol (TreeNode *t); Word luaI_findsymbol (TreeNode *t);
Word luaI_findconstant (TreeNode *t); Word luaI_findconstant (TreeNode *t);
void lua_travsymbol (void (*fn)(Object *)); Word luaI_findconstantbyname (char *name);
void lua_markobject (Object *o); int lua_markobject (Object *o);
void lua_pack (void); void lua_pack (void);
char *lua_addfile (char *fn);
int lua_delfile (void);
char *lua_filename (void);
#endif #endif

42
tree.c
View File

@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio ** TecCGraf - PUC-Rio
*/ */
char *rcs_tree="$Id: tree.c,v 1.12 1994/12/20 21:20:36 roberto Exp roberto $"; char *rcs_tree="$Id: tree.c,v 1.13 1995/01/12 14:19:04 roberto Exp roberto $";
#include <string.h> #include <string.h>
@@ -102,40 +102,22 @@ Long lua_strcollector (void)
return counter; return counter;
} }
/* /*
** Return next variable. ** Traverse the constant tree looking for a specific symbol number
*/ */
static TreeNode *tree_next (TreeNode *node, char *str) static TreeNode *nodebysymbol (TreeNode *root, Word symbol)
{ {
if (node == NULL) return NULL; TreeNode *t;
else if (str == NULL) return node; if (root == NULL) return NULL;
else if (root->varindex == symbol) return root;
{ t = nodebysymbol(root->left, symbol);
int c = lua_strcmp(str, node->ts.str); if (t) return t;
if (c == 0) return nodebysymbol(root->right, symbol);
return node->left != NULL ? node->left : node->right;
else if (c < 0)
{
TreeNode *result = tree_next(node->left, str);
return result != NULL ? result : node->right;
}
else
return tree_next(node->right, str);
}
} }
TreeNode *lua_varnext (char *n) TreeNode *luaI_nodebysymbol (Word symbol)
{ {
TreeNode *result; return nodebysymbol(constant_root, symbol);
char *name = n;
while (1)
{ /* repeat until a valid (non nil) variable */
result = tree_next(constant_root, name);
if (result == NULL) return NULL;
if (result->varindex != NOT_USED &&
s_tag(result->varindex) != LUA_T_NIL)
return result;
name = result->ts.str;
}
} }

4
tree.h
View File

@@ -1,7 +1,7 @@
/* /*
** tree.h ** tree.h
** TecCGraf - PUC-Rio ** TecCGraf - PUC-Rio
** $Id: tree.h,v 1.8 1994/12/20 21:20:36 roberto Exp roberto $ ** $Id: tree.h,v 1.9 1995/01/12 14:19:04 roberto Exp roberto $
*/ */
#ifndef tree_h #ifndef tree_h
@@ -32,6 +32,6 @@ typedef struct TreeNode
TaggedString *lua_createstring (char *str); TaggedString *lua_createstring (char *str);
TreeNode *lua_constcreate (char *str); TreeNode *lua_constcreate (char *str);
Long lua_strcollector (void); Long lua_strcollector (void);
TreeNode *lua_varnext (char *n); TreeNode *luaI_nodebysymbol (Word symbol);
#endif #endif