Compare commits

..

62 Commits

Author SHA1 Message Date
Roberto Ierusalimschy
dcb1a08906 "exp" changed to "exp0" to avoid problems with math.h. 1998-07-06 19:07:51 -03:00
Roberto Ierusalimschy
1788501eed double constant used in integer expression 1998-07-06 19:04:58 -03:00
Roberto Ierusalimschy
bee1a5aeb2 spelling 1998-07-01 11:21:57 -03:00
Roberto Ierusalimschy
994aba062b when debuging, blocks must be kept in double allignment. 1998-06-29 19:03:06 -03:00
Roberto Ierusalimschy
e869d17eb1 functions should return explicit "nil"s. 1998-06-29 15:24:06 -03:00
Roberto Ierusalimschy
9a0221ef58 detail 1998-06-29 15:09:28 -03:00
Roberto Ierusalimschy
07008b5d45 details (by lhf) 1998-06-25 13:48:44 -03:00
Roberto Ierusalimschy
8f31eda649 details in comments 1998-06-25 11:37:00 -03:00
Roberto Ierusalimschy
da94130160 stupid bug (in syntax print "hello") 1998-06-24 11:48:15 -03:00
Roberto Ierusalimschy
468fbdbde7 details 1998-06-24 10:33:00 -03:00
Roberto Ierusalimschy
eb45f8b631 details (dependencies) 1998-06-19 15:52:27 -03:00
Roberto Ierusalimschy
df0df08bc5 "dostring" accepts chunk name. 1998-06-19 15:47:06 -03:00
Roberto Ierusalimschy
9618aaf07d small corrections in comments 1998-06-19 13:14:09 -03:00
Roberto Ierusalimschy
bec9bc4154 sugestions by lhf 1998-06-18 14:36:27 -03:00
Roberto Ierusalimschy
955a811aa1 category for "setlocale" is given by name 1998-06-18 14:04:28 -03:00
Roberto Ierusalimschy
c9902be294 "findname" moved from lobject.c to lauxlib.c (so libraries may use it). 1998-06-18 13:57:03 -03:00
Roberto Ierusalimschy
112c9d53ab new version by lhf 1998-06-18 13:52:04 -03:00
Roberto Ierusalimschy
0789451458 details 1998-06-18 13:51:53 -03:00
Roberto Ierusalimschy
d97af0de26 "lua_dobuffer" gets an extra argument, with the chunk name 1998-06-15 18:34:14 -03:00
Roberto Ierusalimschy
1917149fdd details. 1998-06-11 15:21:37 -03:00
Roberto Ierusalimschy
0845e73b6a new copyright notice 1998-06-06 18:05:52 -03:00
Roberto Ierusalimschy
7dfa952091 no more error for '\x' (with "invalid" x) 1998-06-06 17:44:05 -03:00
Roberto Ierusalimschy
02134b4a87 name: lua_pushCclosure -> lua_pushcclosure. 1998-06-05 19:17:44 -03:00
Roberto Ierusalimschy
bdb1db4d37 "read" more efficient when reading lines and whole files ('.*') 1998-06-02 18:20:54 -03:00
Roberto Ierusalimschy
02a6891939 API for functions to manipulate global state. 1998-06-02 17:37:04 -03:00
Roberto Ierusalimschy
741c6f5006 'dobuffer' addpoted. 1998-05-31 19:22:00 -03:00
Roberto Ierusalimschy
6152973f9c new names for 'ascii' ('strbyte') and 'int2str' ('strchar') 1998-05-31 19:20:45 -03:00
Roberto Ierusalimschy
243a808067 'print' now calls 'tostring' 1998-05-31 19:19:35 -03:00
Roberto Ierusalimschy
62c36a6056 better error message when '^' is not defined. 1998-05-31 19:18:24 -03:00
Roberto Ierusalimschy
74719afc33 new functions "frexp" and "ldexp" 1998-05-27 16:09:39 -03:00
Roberto Ierusalimschy
7e59a8901d NEW LL(1) PARSER 1998-05-27 10:08:34 -03:00
Roberto Ierusalimschy
abc6eac404 new function "clock" 1998-05-20 19:21:35 -03:00
Roberto Ierusalimschy
054e0b888a number type in Lua changed for double (by default). 1998-05-18 19:26:03 -03:00
Roberto Ierusalimschy
da252eeff7 arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int. 1998-05-18 19:21:55 -03:00
Roberto Ierusalimschy
9890bedaab details (format for html) 1998-04-02 13:09:16 -03:00
Roberto Ierusalimschy
0a0c9593b8 many small corrections; strings with '\0' 1998-03-30 15:17:55 -03:00
Roberto Ierusalimschy
d470792517 words are stored in hi-lo order (easier to print) 1998-03-30 10:57:23 -03:00
Roberto Ierusalimschy
439236773b changes by lhf 1998-03-26 11:50:19 -03:00
Roberto Ierusalimschy
2a2b64d6ac opcode "CLOSURE" gets the prototipe (instead of a previous pushconstant) 1998-03-25 15:52:29 -03:00
Roberto Ierusalimschy
daa937c043 pattern-matching support for '\0'. 1998-03-24 17:14:25 -03:00
Roberto Ierusalimschy
21455162b5 details (and new escape sequences: \a, \b, ...) 1998-03-20 11:18:18 -03:00
Roberto Ierusalimschy
99cc4b20f2 details 1998-03-11 10:59:50 -03:00
Roberto Ierusalimschy
0969a971cd better use of "ASSERT". 1998-03-09 18:49:52 -03:00
Roberto Ierusalimschy
be6d215f67 BUG: gsub('a', '(b?)%1*' ...) loops (because the capture is empty). 1998-03-09 15:28:08 -03:00
Roberto Ierusalimschy
e74817f8aa correct way to handle string delimiters 1998-03-09 14:22:49 -03:00
Roberto Ierusalimschy
043c2ac258 new names for "lua_pushlstr" and "lua_getstrlen" 1998-03-06 15:47:42 -03:00
Roberto Ierusalimschy
88a2023c32 support for strings with '\0' 1998-03-06 13:54:42 -03:00
Roberto Ierusalimschy
5ef1989c4b "settag" returns its first argument. 1998-02-12 17:27:10 -02:00
Roberto Ierusalimschy
f380d627f8 usefull macros also available as functions 1998-02-12 17:23:32 -02:00
Roberto Ierusalimschy
aafa106d10 implementation of numerical escape sequences in strings ("\12");
better error messages for wrong tokens
1998-02-11 18:56:46 -02:00
Roberto Ierusalimschy
29b7b8e52c better error messages for wrong tokens 1998-02-11 18:56:46 -02:00
Roberto Ierusalimschy
a9dd2c6717 interrupts lua loops with "^C" (via signals) 1998-02-11 18:56:05 -02:00
Roberto Ierusalimschy
aee3f97acb put back quotes (") when string in dostring ends with a \n 1998-01-29 13:59:35 -02:00
Roberto Ierusalimschy
46968b8ffa "volatile is the only reliable way to ensure that a local variable
retains the value it had at the time of the call to longjmp"
1998-01-28 15:47:05 -02:00
Roberto Ierusalimschy
6cdf0d8768 tables can become full of "emptys" slots, and keep growing without limits. 1998-01-28 14:50:33 -02:00
Roberto Ierusalimschy
07ff251a17 details in "dostring" identification 1998-01-27 19:21:27 -02:00
Roberto Ierusalimschy
b3b7cf7335 BUG: "lua_getstring" may create a new string, so should check GC 1998-01-27 17:13:45 -02:00
Roberto Ierusalimschy
8622dc18bf bug: format size limits with little problems 1998-01-27 17:11:36 -02:00
Roberto Ierusalimschy
d22e2644dd wrong line number (+1) in error report when file starts with "#..." 1998-01-19 18:18:02 -02:00
Roberto Ierusalimschy
f529a22ca5 BUG: wrong line number (+1) in error report when file starts with "#..." 1998-01-19 18:18:02 -02:00
Roberto Ierusalimschy
783ba75129 needs "stdlib.h" (calls "exit") 1998-01-19 17:49:49 -02:00
Roberto Ierusalimschy
d49e4dd752 MAX_WORD should not be bigger than MAX_INT 1998-01-19 17:49:22 -02:00
36 changed files with 3021 additions and 2014 deletions

39
bugs
View File

@@ -2,3 +2,42 @@
Tue Dec 2 10:45:48 EDT 1997
>> BUG: "lastline" was not reset on function entry, so debug information
>> started only in the 2nd line of a function.
--- Version 3.1 alpha
** lua.c
Thu Jan 15 14:34:58 EDT 1998
>> must include "stdlib.h" (for "exit()").
** lbuiltin.c / lobject.h
Thu Jan 15 14:34:58 EDT 1998
>> MAX_WORD may be bigger than MAX_INT
** llex.c
Mon Jan 19 18:17:18 EDT 1998
>> wrong line number (+1) in error report when file starts with "#..."
** lstrlib.c
Tue Jan 27 15:27:49 EDT 1998
>> formats like "%020d" were considered too big (3 digits); moreover,
>> some sistems limit printf to at most 500 chars, so we can limit sizes
>> to 2 digits (99).
** lapi.c
Tue Jan 27 17:12:36 EDT 1998
>> "lua_getstring" may create a new string, so should check GC
** lstring.c / ltable.c
Wed Jan 28 14:48:12 EDT 1998
>> tables can become full of "emptys" slots, and keep growing without limits.
** lstrlib.c
Mon Mar 9 15:26:09 EST 1998
>> gsub('a', '(b?)%1*' ...) loops (because the capture is empty).
** lstrlib.c
Mon May 18 19:20:00 EST 1998
>> arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int.

57
lapi.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 1.18 1998/01/07 16:26:48 roberto Exp roberto $
** $Id: lapi.c,v 1.24 1998/03/09 21:49:52 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -219,7 +219,7 @@ lua_Object lua_getglobal (char *name)
lua_Object lua_rawgetglobal (char *name)
{
TaggedString *ts = luaS_new(name);
return put_luaObject(&ts->u.globalval);
return put_luaObject(&ts->u.s.globalval);
}
@@ -287,11 +287,20 @@ double lua_getnumber (lua_Object object)
char *lua_getstring (lua_Object object)
{
luaC_checkGC(); /* "tostring" may create a new string */
if (object == LUA_NOOBJECT || tostring(Address(object)))
return NULL;
else return (svalue(Address(object)));
}
long lua_strlen (lua_Object object)
{
luaC_checkGC(); /* "tostring" may create a new string */
if (object == LUA_NOOBJECT || tostring(Address(object)))
return 0L;
else return (tsvalue(Address(object))->u.s.len);
}
void *lua_getuserdata (lua_Object object)
{
if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
@@ -320,19 +329,23 @@ void lua_pushnumber (double n)
incr_top;
}
void lua_pushstring (char *s)
void lua_pushlstring (char *s, long len)
{
if (s == NULL)
ttype(L->stack.top) = LUA_T_NIL;
else {
tsvalue(L->stack.top) = luaS_new(s);
ttype(L->stack.top) = LUA_T_STRING;
}
tsvalue(L->stack.top) = luaS_newlstr(s, len);
ttype(L->stack.top) = LUA_T_STRING;
incr_top;
luaC_checkGC();
}
void lua_pushCclosure (lua_CFunction fn, int n)
void lua_pushstring (char *s)
{
if (s == NULL)
lua_pushnil();
else
lua_pushlstring(s, strlen(s));
}
void lua_pushcclosure (lua_CFunction fn, int n)
{
if (fn == NULL)
lua_error("API error - attempt to push a NULL Cfunction");
@@ -341,6 +354,7 @@ void lua_pushCclosure (lua_CFunction fn, int n)
fvalue(L->stack.top) = fn;
incr_top;
luaV_closure(n);
luaC_checkGC();
}
void lua_pushusertag (void *u, int tag)
@@ -390,7 +404,7 @@ int lua_tag (lua_Object lo)
return o->value.cl->consts[0].ttype;
#ifdef DEBUG
case LUA_T_LINE:
lua_error("internal error");
LUA_INTERNALERROR("invalid type");
#endif
default:
return t;
@@ -570,6 +584,27 @@ lua_Object lua_getref (int ref)
}
/*
** =======================================================
** Derived functions
** =======================================================
*/
int (lua_call) (char *name) { return lua_call(name); }
void (lua_pushref) (int ref) { lua_pushref(ref); }
int (lua_refobject) (lua_Object o, int l) { return lua_refobject(o, l); }
void (lua_register) (char *n, lua_CFunction f) { lua_register(n, f); }
void (lua_pushuserdata) (void *u) { lua_pushuserdata(u); }
void (lua_pushcfunction) (lua_CFunction f) { lua_pushcfunction(f); }
int (lua_clonetag) (int t) { return lua_clonetag(t); }
#ifdef LUA_COMPAT2_5
/*

4
lapi.h
View File

@@ -1,6 +1,6 @@
/*
** $Id: $
** auxiliar functions from Lua API
** $Id: lapi.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/

View File

@@ -1,14 +1,15 @@
/*
** $Id: lauxlib.c,v 1.8 1998/01/09 15:06:07 roberto Exp $
** Auxiliar functions for building Lua libraries
** $Id: lauxlib.c,v 1.11 1998/06/18 16:57:03 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
/* Please Notice: This file uses only the oficial API of Lua
/* Please Notice: This file uses only the official API of Lua
** Any function declared here could be written as an application
** function. With care, these functions can be used by other libraries.
*/
@@ -18,6 +19,14 @@
int luaL_findstring (char *name, char *list[]) {
int i;
for (i=0; list[i]; i++)
if (strcmp(list[i], name) == 0)
return i;
return -1; /* name not found */
}
void luaL_argerror (int numarg, char *extramsg)
{
char *funcname;
@@ -31,17 +40,18 @@ void luaL_argerror (int numarg, char *extramsg)
numarg, funcname, extramsg);
}
char *luaL_check_string (int numArg)
char *luaL_check_lstr (int numArg, long *len)
{
lua_Object o = lua_getparam(numArg);
luaL_arg_check(lua_isstring(o), numArg, "string expected");
if (len) *len = lua_strlen(o);
return lua_getstring(o);
}
char *luaL_opt_string (int numArg, char *def)
char *luaL_opt_lstr (int numArg, char *def, long *len)
{
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
luaL_check_string(numArg);
luaL_check_lstr(numArg, len);
}
double luaL_check_number (int numArg)

View File

@@ -1,6 +1,6 @@
/*
** $Id: lauxlib.h,v 1.5 1997/12/17 20:48:58 roberto Exp roberto $
** Auxiliar functions for building Lua libraries
** $Id: lauxlib.h,v 1.8 1998/06/18 16:57:03 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -23,8 +23,10 @@ struct luaL_reg {
void luaL_openlib (struct luaL_reg *l, int n);
void luaL_argerror (int numarg, char *extramsg);
char *luaL_check_string (int numArg);
char *luaL_opt_string (int numArg, char *def);
#define luaL_check_string(n) (luaL_check_lstr((n), NULL))
char *luaL_check_lstr (int numArg, long *len);
#define luaL_opt_string(n, d) (luaL_opt_lstr((n), (d), NULL))
char *luaL_opt_lstr (int numArg, char *def, long *len);
double luaL_check_number (int numArg);
double luaL_opt_number (int numArg, double def);
lua_Object luaL_functionarg (int arg);
@@ -34,10 +36,12 @@ void luaL_verror (char *fmt, ...);
char *luaL_openspace (int size);
void luaL_resetbuffer (void);
void luaL_addchar (int c);
int luaL_getsize (void);
void luaL_addsize (int n);
int luaL_newbuffer (int size);
void luaL_oldbuffer (int old);
char *luaL_buffer (void);
int luaL_findstring (char *name, char *list[]);
#endif

View File

@@ -1,6 +1,6 @@
/*
** $Id: $
** Auxiliar functions for building Lua libraries
** $Id: lbuffer.c,v 1.3 1998/06/02 20:37:04 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -13,7 +13,7 @@
/*-------------------------------------------------------
** Auxiliar buffer
** Auxiliary buffer
-------------------------------------------------------*/
#define BUFF_STEP 32
@@ -22,7 +22,7 @@
static void Openspace (int size)
{
LState *l = L; /* to optimize */
lua_State *l = L; /* to optimize */
int base = l->Mbuffbase-l->Mbuffer;
l->Mbuffsize *= 2;
if (l->Mbuffnext+size > l->Mbuffsize) /* still not big enough? */
@@ -57,6 +57,10 @@ void luaL_addsize (int n)
L->Mbuffnext += n;
}
int luaL_getsize (void)
{
return L->Mbuffnext-(L->Mbuffbase-L->Mbuffer);
}
int luaL_newbuffer (int size)
{

View File

@@ -1,5 +1,5 @@
/*
** $Id: lbuiltin.c,v 1.21 1998/01/02 17:46:32 roberto Exp roberto $
** $Id: lbuiltin.c,v 1.31 1998/06/19 18:47:06 roberto Exp roberto $
** Built-in functions
** See Copyright Notice in lua.h
*/
@@ -22,6 +22,7 @@
#include "ltable.h"
#include "ltm.h"
#include "lua.h"
#include "lundump.h"
@@ -47,12 +48,13 @@ static void nextvar (void)
luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
g = (TaggedString *)g->head.next;
}
while (g && g->u.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
g = (TaggedString *)g->head.next;
if (g) {
pushstring(g);
luaA_pushobject(&g->u.globalval);
luaA_pushobject(&g->u.s.globalval);
}
else lua_pushnil();
}
@@ -65,12 +67,12 @@ static void foreachvar (void)
L->stack.top++;
for (g = L->rootglobal.next; g; g = g->next) {
TaggedString *s = (TaggedString *)g;
if (s->u.globalval.ttype != LUA_T_NIL) {
if (s->u.s.globalval.ttype != LUA_T_NIL) {
ttype(L->stack.stack+name) = LUA_T_STRING;
tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */
luaA_pushobject(&f);
pushstring(s);
luaA_pushobject(&s->u.globalval);
luaA_pushobject(&s->u.s.globalval);
luaD_call((L->stack.top-L->stack.stack)-2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL)
return;
@@ -89,6 +91,7 @@ static void next (void)
luaA_pushobject(&n->ref);
luaA_pushobject(&n->val);
}
else lua_pushnil();
}
@@ -114,9 +117,11 @@ static void foreach (void)
static void internaldostring (void)
{
if (lua_getparam(2) != LUA_NOOBJECT)
lua_error("invalid 2nd argument (probably obsolete code)");
if (lua_dostring(luaL_check_string(1)) == 0)
long l;
char *s = luaL_check_lstr(1, &l);
if (*s == ID_CHUNK)
lua_error("`dostring' cannot run pre-compiled code");
if (lua_dobuffer(s, l, luaL_opt_string(2, NULL)) == 0)
if (luaA_passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
@@ -131,53 +136,60 @@ static void internaldofile (void)
}
static char *to_string (lua_Object obj)
{
static void to_string (void) {
lua_Object obj = lua_getparam(1);
char *buff = luaL_openspace(30);
TObject *o = luaA_Address(obj);
switch (ttype(o)) {
case LUA_T_NUMBER: case LUA_T_STRING:
return lua_getstring(obj);
case LUA_T_NUMBER:
lua_pushstring(lua_getstring(obj));
return;
case LUA_T_STRING:
lua_pushobject(obj);
return;
case LUA_T_ARRAY: {
sprintf(buff, "table: %p", (void *)o->value.a);
return buff;
break;
}
case LUA_T_CLOSURE: {
sprintf(buff, "function: %p", (void *)o->value.cl);
return buff;
break;
}
case LUA_T_PROTO: {
sprintf(buff, "function: %p", (void *)o->value.tf);
return buff;
break;
}
case LUA_T_CPROTO: {
sprintf(buff, "function: %p", (void *)o->value.f);
return buff;
break;
}
case LUA_T_USERDATA: {
sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
return buff;
break;
}
case LUA_T_NIL:
return "nil";
default:
lua_error("internal error");
return NULL; /* to avoid warnings */
lua_pushstring("nil");
return;
default:
LUA_INTERNALERROR("invalid type");
}
}
static void bi_tostring (void)
{
lua_pushstring(to_string(lua_getparam(1)));
lua_pushstring(buff);
}
static void luaI_print (void)
{
int i = 1;
static void luaI_print (void) {
TaggedString *ts = luaS_new("tostring");
lua_Object obj;
while ((obj = lua_getparam(i++)) != LUA_NOOBJECT)
printf("%s\t", to_string(obj));
int i = 1;
while ((obj = lua_getparam(i++)) != LUA_NOOBJECT) {
luaA_pushobject(&ts->u.s.globalval);
lua_pushobject(obj);
luaD_call((L->stack.top-L->stack.stack)-1, 1);
if (ttype(L->stack.top-1) != LUA_T_STRING)
lua_error("`tostring' must return a string to `print'");
printf("%s\t", svalue(L->stack.top-1));
L->stack.top--;
}
printf("\n");
}
@@ -193,7 +205,7 @@ static void luaI_type (void)
static void tonumber (void)
{
int base = luaL_opt_number(2, 10);
if (base == 10) { /* standard convertion */
if (base == 10) { /* standard conversion */
lua_Object o = lua_getparam(1);
if (lua_isnumber(o))
lua_pushnumber(lua_getnumber(o));
@@ -204,8 +216,8 @@ static void tonumber (void)
luaL_arg_check(0 <= base && base <= 36, 2, "base out of range");
n = strtol(s, &s, base);
while (isspace(*s)) s++; /* skip trailing spaces */
if (*s) return; /* invalid format: return nil */
lua_pushnumber(n);
if (*s) lua_pushnil(); /* invalid format: return nil */
else lua_pushnumber(n);
}
}
@@ -263,7 +275,7 @@ static int getnarg (lua_Object table)
lua_Object temp;
/* temp = table.n */
lua_pushobject(table); lua_pushstring("n"); temp = lua_rawgettable();
return (lua_isnumber(temp) ? lua_getnumber(temp) : MAX_WORD);
return (lua_isnumber(temp) ? lua_getnumber(temp) : MAX_INT);
}
static void luaI_call (void)
@@ -283,7 +295,7 @@ static void luaI_call (void)
lua_Object temp;
/* temp = arg[i+1] */
lua_pushobject(arg); lua_pushnumber(i+1); temp = lua_rawgettable();
if (narg == MAX_WORD && lua_isnil(temp))
if (narg == MAX_INT && lua_isnil(temp))
break;
lua_pushobject(temp);
}
@@ -293,8 +305,10 @@ static void luaI_call (void)
lua_seterrormethod();
}
if (status != 0) { /* error in call? */
if (strchr(options, 'x'))
if (strchr(options, 'x')) {
lua_pushnil();
return; /* return nil to signal the error */
}
else
lua_error(NULL);
}
@@ -312,6 +326,7 @@ static void settag (void)
lua_Object o = luaL_tablearg(1);
lua_pushobject(o);
lua_settag(luaL_check_number(2));
lua_pushobject(o); /* returns first argument */
}
@@ -330,22 +345,17 @@ static void copytagmethods (void)
static void rawgettable (void)
{
lua_Object t = luaL_nonnullarg(1);
lua_Object i = luaL_nonnullarg(2);
lua_pushobject(t);
lua_pushobject(i);
lua_pushobject(luaL_nonnullarg(1));
lua_pushobject(luaL_nonnullarg(2));
lua_pushobject(lua_rawgettable());
}
static void rawsettable (void)
{
lua_Object t = luaL_nonnullarg(1);
lua_Object i = luaL_nonnullarg(2);
lua_Object v = luaL_nonnullarg(3);
lua_pushobject(t);
lua_pushobject(i);
lua_pushobject(v);
lua_pushobject(luaL_nonnullarg(1));
lua_pushobject(luaL_nonnullarg(2));
lua_pushobject(luaL_nonnullarg(3));
lua_rawsettable();
}
@@ -427,7 +437,7 @@ static void testC (void)
case 'c': reg[getnum(s)] = lua_createtable(); break;
case 'C': { lua_CFunction f = lua_getcfunction(lua_getglobal(getname(s)));
lua_pushCclosure(f, getnum(s));
lua_pushcclosure(f, getnum(s));
break;
}
case 'P': reg[getnum(s)] = lua_pop(); break;
@@ -444,7 +454,7 @@ static void testC (void)
case '=': lua_setglobal(getname(s)); break;
case 's': lua_pushstring(getname(s)); break;
case 'o': lua_pushobject(reg[getnum(s)]); break;
case 'f': lua_call(getname(s)); break;
case 'f': (lua_call)(getname(s)); break;
case 'i': reg[getnum(s)] = lua_gettable(); break;
case 'I': reg[getnum(s)] = lua_rawgettable(); break;
case 't': lua_settable(); break;
@@ -495,7 +505,7 @@ static struct luaL_reg int_funcs[] = {
{"gettagmethod", gettagmethod},
{"settag", settag},
{"tonumber", tonumber},
{"tostring", bi_tostring},
{"tostring", to_string},
{"tag", luatag},
{"type", luaI_type}
};

59
ldo.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.20 1997/12/26 18:38:16 roberto Exp roberto $
** $Id: ldo.c,v 1.26 1998/06/15 21:34:14 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -288,8 +288,8 @@ int luaD_protectedrun (int nResults)
{
jmp_buf myErrorJmp;
int status;
struct C_Lua_Stack oldCLS = L->Cstack;
jmp_buf *oldErr = L->errorJmp;
volatile struct C_Lua_Stack oldCLS = L->Cstack;
jmp_buf *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp) == 0) {
do_callinc(nResults);
@@ -310,10 +310,10 @@ int luaD_protectedrun (int nResults)
*/
static int protectedparser (ZIO *z, int bin)
{
int status;
TProtoFunc *tf;
volatile int status;
TProtoFunc *volatile tf;
jmp_buf myErrorJmp;
jmp_buf *oldErr = L->errorJmp;
jmp_buf *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp) == 0) {
tf = bin ? luaU_undump1(z) : luaY_parser(z);
@@ -392,29 +392,36 @@ int lua_dofile (char *filename)
#define SSIZE_PREF "20"
int lua_dostring (char *str)
{
int status;
char name[SIZE_PREF+25];
char *temp;
ZIO z;
if (str == NULL) return 1;
sprintf(name, "(dostring) >> %." SSIZE_PREF "s", str);
temp = strchr(name, '\n');
if (temp) *temp = 0; /* end string after first line */
luaZ_sopen(&z, str, name);
status = do_main(&z, 0);
return status;
static void build_name (char *str, char *name) {
if (str == NULL || *str == ID_CHUNK)
strcpy(name, "(buffer)");
else {
char *temp;
sprintf(name, "(dostring) >> \"%." SSIZE_PREF "s\"", str);
temp = strchr(name, '\n');
if (temp) { /* end string after first line */
*temp = '"';
*(temp+1) = 0;
}
}
}
#if 0
int lua_dobuffer (char *buff, int size)
{
int status;
int lua_dostring (char *str) {
return lua_dobuffer(str, strlen(str), NULL);
}
int lua_dobuffer (char *buff, int size, char *name) {
char newname[SIZE_PREF+25];
ZIO z;
luaZ_mopen(&z, buff, size, "(buffer)");
status = do_main(&z, 1);
int status;
if (name==NULL) {
build_name(buff, newname);
name = newname;
}
luaZ_mopen(&z, buff, size, name);
status = do_main(&z, buff[0]==ID_CHUNK);
return status;
}
#endif

View File

@@ -1,6 +1,6 @@
/*
** $Id: lfunc.c,v 1.7 1997/12/09 13:35:19 roberto Exp roberto $
** Auxiliar functions to manipulate prototypes and closures
** $Id: lfunc.c,v 1.8 1997/12/15 16:17:20 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/

14
lgc.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 1.14 1997/12/17 20:48:58 roberto Exp roberto $
** $Id: lgc.c,v 1.17 1998/03/06 16:54:42 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -41,7 +41,7 @@ int luaC_ref (TObject *o, int lock)
/* no more empty spaces */ {
int oldSize = L->refSize;
L->refSize = luaM_growvector(&L->refArray, L->refSize, struct ref,
refEM, MAX_WORD);
refEM, MAX_INT);
for (ref=oldSize; ref<L->refSize; ref++)
L->refArray[ref].status = FREE;
ref = oldSize;
@@ -96,7 +96,7 @@ static int ismarked (TObject *o)
#ifdef DEBUG
case LUA_T_LINE: case LUA_T_CLMARK:
case LUA_T_CMARK: case LUA_T_PMARK:
lua_error("internal error");
LUA_INTERNALERROR("invalid type");
#endif
default: /* nil, number or cproto */
return 1;
@@ -212,11 +212,13 @@ static void hashmark (Hash *h)
static void globalmark (void)
{
TaggedString *g;
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
if (g->u.globalval.ttype != LUA_T_NIL) {
markobject(&g->u.globalval);
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next){
LUA_ASSERT(g->constindex >= 0, "userdata in global list");
if (g->u.s.globalval.ttype != LUA_T_NIL) {
markobject(&g->u.s.globalval);
strmark(g); /* cannot collect non nil global variables */
}
}
}

137
liolib.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 1.13 1997/12/26 18:38:16 roberto Exp roberto $
** $Id: liolib.c,v 1.20 1998/06/05 22:17:44 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -180,55 +180,81 @@ static void io_appendto (void)
#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
static void io_read (void)
{
static void read_until (FILE *f, int lim) {
int l = 0;
int c;
for (c = getc(f); c != EOF && c != lim; c = getc(f)) {
luaL_addchar(c);
l++;
}
if (l > 0 || c == lim) /* read anything? */
lua_pushlstring(luaL_buffer(), l);
}
static void io_read (void) {
int arg = FIRSTARG;
FILE *f = getfileparam(FINPUT, &arg);
char *buff;
char *p = luaL_opt_string(arg, "[^\n]*{\n}");
int inskip = 0; /* to control {skips} */
int c = NEED_OTHER;
char *p = luaL_opt_string(arg, NULL);
luaL_resetbuffer();
while (*p) {
if (*p == '{') {
inskip++;
p++;
}
else if (*p == '}') {
if (inskip == 0)
lua_error("unbalanced braces in read pattern");
inskip--;
p++;
}
else {
char *ep; /* get what is next */
int m; /* match result */
if (c == NEED_OTHER) c = getc(f);
m = luaI_singlematch((c == EOF) ? 0 : (char)c, p, &ep);
if (m) {
if (inskip == 0) luaL_addchar(c);
c = NEED_OTHER;
if (p == NULL) /* default: read a line */
read_until(f, '\n');
else if (p[0] == '.' && p[1] == '*' && p[2] == 0) /* p = ".*" */
read_until(f, EOF);
else {
int l = 0; /* number of chars read in buffer */
int inskip = 0; /* to control {skips} */
int c = NEED_OTHER;
while (*p) {
switch (*p) {
case '{':
inskip++;
p++;
continue;
case '}':
if (inskip == 0)
lua_error("unbalanced braces in read pattern");
inskip--;
p++;
continue;
default: {
char *ep; /* get what is next */
int m; /* match result */
if (c == NEED_OTHER) c = getc(f);
if (c == EOF) {
luaI_singlematch(0, p, &ep); /* to set "ep" */
m = 0;
}
else {
m = luaI_singlematch(c, p, &ep);
if (m) {
if (inskip == 0) {
luaL_addchar(c);
l++;
}
c = NEED_OTHER;
}
}
switch (*ep) {
case '*': /* repetition */
if (!m) p = ep+1; /* else stay in (repeat) the same item */
continue;
case '?': /* optional */
p = ep+1; /* continues reading the pattern */
continue;
default:
if (m) p = ep; /* continues reading the pattern */
else
goto break_while; /* pattern fails */
}
}
}
switch (*ep) {
case '*': /* repetition */
if (!m) p = ep+1; /* else stay in (repeat) the same item */
break;
case '?': /* optional */
p = ep+1; /* continues reading the pattern */
break;
default:
if (m) p = ep; /* continues reading the pattern */
else
goto break_while; /* pattern fails */
}
}
} break_while:
if (c >= 0) /* not EOF nor NEED_OTHER? */
ungetc(c, f);
luaL_addchar(0);
buff = luaL_buffer();
if (*buff != 0 || *p == 0) /* read something or did not fail? */
lua_pushstring(buff);
} break_while:
if (c >= 0) /* not EOF nor NEED_OTHER? */
ungetc(c, f);
if (l > 0 || *p == 0) /* read something or did not fail? */
lua_pushlstring(luaL_buffer(), l);
}
}
@@ -238,8 +264,9 @@ static void io_write (void)
FILE *f = getfileparam(FOUTPUT, &arg);
int status = 1;
char *s;
while ((s = luaL_opt_string(arg++, NULL)) != NULL)
status = status && (fputs(s, f) != EOF);
long l;
while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL)
status = status && (fwrite(s, 1, l, f) == l);
pushresult(status);
}
@@ -276,6 +303,11 @@ static void io_getenv (void)
}
static void io_clock (void) {
lua_pushnumber(((double)clock())/CLOCKS_PER_SEC);
}
static void io_date (void)
{
time_t t;
@@ -294,8 +326,10 @@ static void setloc (void)
{
static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC,
LC_TIME};
int op = (int)luaL_opt_number(2, 0);
luaL_arg_check(0 <= op && op <= 5, 2, "invalid option");
static char *catnames[] = {"all", "collate", "ctype", "monetary",
"numeric", "time", NULL};
int op = luaL_findstring(luaL_opt_string(2, "all"), catnames);
luaL_arg_check(op != -1, 2, "invalid option");
lua_pushstring(setlocale(cat[op], luaL_check_string(1)));
}
@@ -372,6 +406,7 @@ static struct luaL_reg iolib[] = {
{"tmpname", io_tmpname},
{"getenv", io_getenv},
{"date", io_date},
{"clock", io_clock},
{"exit", io_exit},
{"debug", io_debug},
{"print_stack", errorfb}
@@ -394,7 +429,7 @@ static void openwithtags (void)
/* put both tags as upvalues for these functions */
lua_pushnumber(iotag);
lua_pushnumber(closedtag);
lua_pushCclosure(iolibtag[i].func, 2);
lua_pushcclosure(iolibtag[i].func, 2);
lua_setglobal(iolibtag[i].name);
}
setfile(stdin, FINPUT, iotag);

196
llex.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.c,v 1.12 1997/12/22 17:52:20 roberto Exp roberto $
** $Id: llex.c,v 1.22 1998/06/19 18:47:06 roberto Exp roberto $
** Lexical Analizer
** See Copyright Notice in lua.h
*/
@@ -15,7 +15,6 @@
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "lstx.h"
#include "luadebug.h"
#include "lzio.h"
@@ -27,47 +26,74 @@ int lua_debug=0;
#define next(LS) (LS->current = zgetc(LS->lex_z))
static struct {
char *name;
int token;
} reserved [] = {
{"and", AND}, {"do", DO}, {"else", ELSE}, {"elseif", ELSEIF},
{"end", END}, {"function", FUNCTION}, {"if", IF}, {"local", LOCAL},
{"nil", NIL}, {"not", NOT}, {"or", OR}, {"repeat", REPEAT},
{"return", RETURN}, {"then", THEN}, {"until", UNTIL}, {"while", WHILE}
};
#define save(c) luaL_addchar(c)
#define save_and_next(LS) (save(LS->current), next(LS))
char *reserved [] = {"and", "do", "else", "elseif", "end", "function",
"if", "local", "nil", "not", "or", "repeat", "return", "then",
"until", "while"};
void luaX_init (void)
{
int i;
for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
TaggedString *ts = luaS_new(reserved[i].name);
ts->head.marked = reserved[i].token; /* reserved word (always > 255) */
TaggedString *ts = luaS_new(reserved[i]);
ts->head.marked = FIRST_RESERVED+i; /* reserved word (always > 255) */
}
}
void luaX_syntaxerror (LexState *ls, char *s, char *token) {
if (token[0] == 0)
token = "<eof>";
luaL_verror("%.100s;\n last token read: `%.50s' at line %d in chunk `%.50s'",
s, token, ls->linenumber, zname(ls->lex_z));
}
void luaX_error (LexState *ls, char *s) {
save(0);
luaX_syntaxerror(ls, s, luaL_buffer());
}
void luaX_token2str (LexState *ls, int token, char *s) {
if (token < 255) {
s[0] = token;
s[1] = 0;
}
else
strcpy(s, reserved[token-FIRST_RESERVED]);
}
static void luaX_invalidchar (LexState *ls, int c) {
char buff[10];
sprintf(buff, "0x%X", c);
luaX_syntaxerror(ls, "invalid control char", buff);
}
static void firstline (LexState *LS)
{
int c = zgetc(LS->lex_z);
if (c == '#') {
LS->linenumber++;
if (c == '#')
while ((c=zgetc(LS->lex_z)) != '\n' && c != EOZ) /* skip first line */;
}
zungetc(LS->lex_z);
}
void luaX_setinput (ZIO *z)
void luaX_setinput (LexState *LS, ZIO *z)
{
LexState *LS = L->lexstate;
LS->current = '\n';
LS->linelasttoken = 0;
LS->linenumber = 0;
LS->iflevel = 0;
LS->ifstate[0].skip = 0;
LS->ifstate[0].elsepart = 1; /* to avoid a free $else */
LS->lex_z = z;
LS->fs = NULL;
firstline(LS);
luaL_resetbuffer();
}
@@ -89,15 +115,15 @@ static void skipspace (LexState *LS)
}
static int checkcond (char *buff)
static int checkcond (LexState *LS, char *buff)
{
static char *opts[] = {"nil", "1", NULL};
int i = luaO_findstring(buff, opts);
int i = luaL_findstring(buff, opts);
if (i >= 0) return i;
else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
return luaS_globaldefined(buff);
else {
luaY_syntaxerror("invalid $if condition", buff);
luaX_syntaxerror(LS, "invalid $if condition", buff);
return 0; /* to avoid warnings */
}
}
@@ -110,7 +136,7 @@ static void readname (LexState *LS, char *buff)
while (isalnum(LS->current) || LS->current == '_') {
if (i >= PRAGMASIZE) {
buff[PRAGMASIZE] = 0;
luaY_syntaxerror("pragma too long", buff);
luaX_syntaxerror(LS, "pragma too long", buff);
}
buff[i++] = LS->current;
next(LS);
@@ -128,7 +154,7 @@ static void ifskip (LexState *LS)
if (LS->current == '\n')
inclinenumber(LS);
else if (LS->current == EOZ)
luaY_syntaxerror("input ends inside a $if", "");
luaX_error(LS, "input ends inside a $if");
else next(LS);
}
}
@@ -146,7 +172,7 @@ static void inclinenumber (LexState *LS)
int skip = LS->ifstate[LS->iflevel].skip;
next(LS); /* skip $ */
readname(LS, buff);
switch (luaO_findstring(buff, pragmas)) {
switch (luaL_findstring(buff, pragmas)) {
case 0: /* debug */
if (!skip) lua_debug = 1;
break;
@@ -161,35 +187,35 @@ static void inclinenumber (LexState *LS)
break;
case 3: /* end */
if (LS->iflevel-- == 0)
luaY_syntaxerror("unmatched $end", "$end");
luaX_syntaxerror(LS, "unmatched $end", "$end");
break;
case 4: /* ifnot */
ifnot = 1;
/* go through */
case 5: /* if */
if (LS->iflevel == MAX_IFS-1)
luaY_syntaxerror("too many nested $ifs", "$if");
luaX_syntaxerror(LS, "too many nested $ifs", "$if");
readname(LS, buff);
LS->iflevel++;
LS->ifstate[LS->iflevel].elsepart = 0;
LS->ifstate[LS->iflevel].condition = checkcond(buff) ? !ifnot : ifnot;
LS->ifstate[LS->iflevel].condition = checkcond(LS, buff) ? !ifnot : ifnot;
LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition;
break;
case 6: /* else */
if (LS->ifstate[LS->iflevel].elsepart)
luaY_syntaxerror("unmatched $else", "$else");
luaX_syntaxerror(LS, "unmatched $else", "$else");
LS->ifstate[LS->iflevel].elsepart = 1;
LS->ifstate[LS->iflevel].skip = LS->ifstate[LS->iflevel-1].skip ||
LS->ifstate[LS->iflevel].condition;
break;
default:
luaY_syntaxerror("unknown pragma", buff);
luaX_syntaxerror(LS, "unknown pragma", buff);
}
skipspace(LS);
if (LS->current == '\n') /* pragma must end with a '\n' ... */
inclinenumber(LS);
else if (LS->current != EOZ) /* or eof */
luaY_syntaxerror("invalid pragma format", buff);
luaX_syntaxerror(LS, "invalid pragma format", buff);
ifskip(LS);
}
}
@@ -203,25 +229,16 @@ static void inclinenumber (LexState *LS)
#define save(c) luaL_addchar(c)
#define save_and_next(LS) (save(LS->current), next(LS))
char *luaX_lasttoken (void)
{
save(0);
return luaL_buffer();
}
static int read_long_string (LexState *LS, YYSTYPE *l)
static int read_long_string (LexState *LS)
{
int cont = 0;
while (1) {
switch (LS->current) {
case EOZ:
save(0);
return WRONGTOKEN;
luaX_error(LS, "unfinished long string");
return EOS; /* to avoid warnings */
case '[':
save_and_next(LS);
if (LS->current == '[') {
@@ -246,26 +263,15 @@ static int read_long_string (LexState *LS, YYSTYPE *l)
}
} endloop:
save_and_next(LS); /* pass the second ']' */
L->Mbuffer[L->Mbuffnext-2] = 0; /* erases ']]' */
l->pTStr = luaS_new(L->Mbuffbase+2);
L->Mbuffer[L->Mbuffnext-2] = ']'; /* restores ']]' */
LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+2,
L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4);
return STRING;
}
/* to avoid warnings; this declaration cannot be public since YYSTYPE
** cannot be visible in llex.h (otherwise there is an error, since
** the parser body redefines it!)
*/
int luaY_lex (YYSTYPE *l);
int luaY_lex (YYSTYPE *l)
{
LexState *LS = L->lexstate;
int luaX_lex (LexState *LS) {
double a;
luaL_resetbuffer();
if (lua_debug)
luaY_codedebugline(LS->linelasttoken);
LS->linelasttoken = LS->linenumber;
while (1) {
switch (LS->current) {
@@ -275,7 +281,6 @@ int luaY_lex (YYSTYPE *l)
case '\n':
inclinenumber(LS);
LS->linelasttoken = LS->linenumber;
continue;
case '-':
@@ -290,7 +295,7 @@ int luaY_lex (YYSTYPE *l)
if (LS->current != '[') return '[';
else {
save_and_next(LS); /* pass the second '[' */
return read_long_string(LS, l);
return read_long_string(LS);
}
case '=':
@@ -321,26 +326,46 @@ int luaY_lex (YYSTYPE *l)
switch (LS->current) {
case EOZ:
case '\n':
save(0);
return WRONGTOKEN;
luaX_error(LS, "unfinished string");
return EOS; /* to avoid warnings */
case '\\':
next(LS); /* do not save the '\' */
switch (LS->current) {
case 'a': save('\a'); next(LS); break;
case 'b': save('\b'); next(LS); break;
case 'f': save('\f'); next(LS); break;
case 'n': save('\n'); next(LS); break;
case 't': save('\t'); next(LS); break;
case 'r': save('\r'); next(LS); break;
case 't': save('\t'); next(LS); break;
case 'v': save('\v'); next(LS); break;
case '\n': save('\n'); inclinenumber(LS); break;
default : save_and_next(LS); break;
default : {
if (isdigit(LS->current)) {
int c = 0;
int i = 0;
do {
c = 10*c + (LS->current-'0');
next(LS);
} while (++i<3 && isdigit(LS->current));
if (c >= 256)
luaX_error(LS, "escape sequence too large");
save(c);
}
else { /* handles \, ", ', and ? */
save(LS->current);
next(LS);
}
break;
}
}
break;
default:
save_and_next(LS);
}
}
next(LS); /* skip delimiter */
save(0);
l->pTStr = luaS_new(L->Mbuffbase+1);
L->Mbuffer[L->Mbuffnext-1] = del; /* restore delimiter */
save_and_next(LS); /* skip delimiter */
LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+1,
L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-2);
return STRING;
}
@@ -365,14 +390,14 @@ int luaY_lex (YYSTYPE *l)
case '5': case '6': case '7': case '8': case '9':
a=0.0;
do {
a=10.0*a+(LS->current-'0');
a = 10.0*a + (LS->current-'0');
save_and_next(LS);
} while (isdigit(LS->current));
if (LS->current == '.') {
save_and_next(LS);
if (LS->current == '.') {
save(0);
luaY_error(
save('.');
luaX_error(LS,
"ambiguous syntax (decimal point x string concatenation)");
}
}
@@ -380,42 +405,43 @@ int luaY_lex (YYSTYPE *l)
{ double da=0.1;
while (isdigit(LS->current))
{
a+=(LS->current-'0')*da;
da/=10.0;
a += (LS->current-'0')*da;
da /= 10.0;
save_and_next(LS);
}
if (toupper(LS->current) == 'E') {
int e=0;
int e = 0;
int neg;
double ea;
save_and_next(LS);
neg=(LS->current=='-');
neg = (LS->current=='-');
if (LS->current == '+' || LS->current == '-') save_and_next(LS);
if (!isdigit(LS->current)) {
save(0); return WRONGTOKEN; }
if (!isdigit(LS->current))
luaX_error(LS, "invalid numeral format");
do {
e=10.0*e+(LS->current-'0');
e = 10*e + (LS->current-'0');
save_and_next(LS);
} while (isdigit(LS->current));
for (ea=neg?0.1:10.0; e>0; e>>=1)
{
if (e & 1) a*=ea;
ea*=ea;
if (e & 1) a *= ea;
ea *= ea;
}
}
l->vReal = a;
LS->seminfo.r = a;
return NUMBER;
}
case EOZ:
save(0);
if (LS->iflevel > 0)
luaY_syntaxerror("input ends inside a $if", "");
return 0;
luaX_error(LS, "input ends inside a $if");
return EOS;
default:
if (LS->current != '_' && !isalpha(LS->current)) {
int c = LS->current;
if (iscntrl(c))
luaX_invalidchar(LS, c);
save_and_next(LS);
return c;
}
@@ -426,9 +452,9 @@ int luaY_lex (YYSTYPE *l)
} while (isalnum(LS->current) || LS->current == '_');
save(0);
ts = luaS_new(L->Mbuffbase);
if (ts->head.marked > 255)
if (ts->head.marked >= 'A')
return ts->head.marked; /* reserved word */
l->pTStr = ts;
LS->seminfo.ts = ts;
return NAME;
}
}

33
llex.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.h,v 1.6 1997/12/17 20:48:58 roberto Exp roberto $
** $Id: llex.h,v 1.8 1998/05/27 13:03:40 roberto Exp roberto $
** Lexical Analizer
** See Copyright Notice in lua.h
*/
@@ -11,6 +11,20 @@
#include "lzio.h"
#define FIRST_RESERVED 260
/* maximum length of a reserved word (+1 for terminal 0) */
#define TOKEN_LEN 15
enum RESERVED {
/* terminal symbols denoted by reserved words */
AND = FIRST_RESERVED,
DO, ELSE, ELSEIF, END, FUNCTION, IF, LOCAL, NIL, NOT, OR,
REPEAT, RETURN, THEN, UNTIL, WHILE,
/* other terminal symbols */
NAME, CONC, DOTS, EQ, GE, LE, NE, NUMBER, STRING, EOS};
#define MAX_IFS 5
/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
@@ -18,24 +32,31 @@
struct ifState {
int elsepart; /* true if its in the $else part */
int condition; /* true if $if condition is true */
int skip; /* true if part must be skiped */
int skip; /* true if part must be skipped */
};
typedef struct LexState {
int current; /* look ahead character */
int token; /* look ahead token */
struct FuncState *fs; /* 'FuncState' is private for the parser */
union {
real r;
TaggedString *ts;
} seminfo; /* semantics information */
struct zio *lex_z; /* input stream */
int linenumber; /* input line counter */
int linelasttoken; /* line where last token was read */
int lastline; /* last line wherein a SETLINE was generated */
int iflevel; /* level of nested $if's (for lexical analysis) */
struct ifState ifstate[MAX_IFS];
} LexState;
void luaX_init (void);
void luaX_setinput (ZIO *z);
char *luaX_lasttoken (void);
void luaX_setinput (LexState *LS, ZIO *z);
int luaX_lex (LexState *LS);
void luaX_syntaxerror (LexState *ls, char *s, char *token);
void luaX_error (LexState *ls, char *s);
void luaX_token2str (LexState *ls, int token, char *s);
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lmathlib.c,v 1.7 1997/12/09 13:35:19 roberto Exp roberto $
** $Id: lmathlib.c,v 1.9 1998/05/27 19:09:39 roberto Exp roberto $
** Lua standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -115,6 +115,16 @@ static void math_rad (void)
lua_pushnumber(luaL_check_number(1)*(PI/180.0));
}
static void math_frexp (void) {
int e;
lua_pushnumber(frexp(luaL_check_number(1), &e));
lua_pushnumber(e);
}
static void math_ldexp (void) {
lua_pushnumber(ldexp(luaL_check_number(1), luaL_check_number(2)));
}
static void math_min (void)
@@ -145,7 +155,7 @@ static void math_max (void)
static void math_random (void)
{
/* the '%' is needed because on some sistems (SunOS!) "rand()" may */
/* the '%' is needed because on some systems (SunOS!) "rand()" may */
/* return a value bigger than RAND_MAX... */
double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
double l = luaL_opt_number(1, 0);
@@ -170,10 +180,12 @@ static struct luaL_reg mathlib[] = {
{"asin", math_asin},
{"acos", math_acos},
{"atan", math_atan},
{"atan2", math_atan2},
{"atan2", math_atan2},
{"ceil", math_ceil},
{"floor", math_floor},
{"mod", math_mod},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
{"sqrt", math_sqrt},
{"min", math_min},
{"max", math_max},

21
lmem.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lmem.c,v 1.3 1997/12/01 20:30:44 roberto Exp roberto $
** $Id: lmem.c,v 1.6 1998/06/19 16:14:09 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -57,10 +57,11 @@ void *luaM_realloc (void *block, unsigned long size)
#else
/* DEBUG */
#include <assert.h>
#include <string.h>
#define HEADER (sizeof(double))
#define MARK 55
unsigned long numblocks = 0;
@@ -69,9 +70,10 @@ unsigned long totalmem = 0;
static void *checkblock (void *block)
{
unsigned long *b = (unsigned long *)block - 1;
unsigned long *b = (unsigned long *)((char *)block - HEADER);
unsigned long size = *b;
assert(*(((char *)b)+size+sizeof(unsigned long)) == MARK);
LUA_ASSERT(*(((char *)b)+size+HEADER) == MARK,
"corrupted block");
numblocks--;
totalmem -= size;
return b;
@@ -80,12 +82,13 @@ static void *checkblock (void *block)
void *luaM_realloc (void *block, unsigned long size)
{
unsigned long realsize = sizeof(unsigned long)+size+sizeof(char);
unsigned long realsize = HEADER+size+1;
if (realsize != (size_t)realsize)
lua_error("Allocation Error: Block too big");
if (size == 0) { /* ANSI doen't need this, but some machines... */
if (size == 0) { /* ANSI dosen't need this, but some machines... */
if (block) {
memset(block, -1, *((unsigned long *)block-1)); /* erase block */
unsigned long *b = (unsigned long *)((char *)block - HEADER);
memset(block, -1, *b); /* erase block */
block = checkblock(block);
free(block);
}
@@ -102,8 +105,8 @@ void *luaM_realloc (void *block, unsigned long size)
totalmem += size;
numblocks++;
*(unsigned long *)block = size;
*(((char *)block)+size+sizeof(unsigned long)) = MARK;
return (unsigned long *)block+1;
*(((char *)block)+size+HEADER) = MARK;
return (unsigned long *)((char *)block+HEADER);
}

View File

@@ -1,11 +1,10 @@
/*
** $Id: lobject.c,v 1.9 1997/12/26 18:38:16 roberto Exp roberto $
** $Id: lobject.c,v 1.12 1998/06/18 16:57:03 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <string.h>
#include "lobject.h"
#include "lua.h"
@@ -52,22 +51,12 @@ int luaO_equalObj (TObject *t1, TObject *t2)
case LUA_T_CPROTO: return fvalue(t1) == fvalue(t2);
case LUA_T_CLOSURE: return t1->value.cl == t2->value.cl;
default:
lua_error("internal error in `lua_equalObj'");
return 0; /* UNREACHEABLE */
LUA_INTERNALERROR("invalid type");
return 0; /* UNREACHABLE */
}
}
int luaO_findstring (char *name, char *list[])
{
int i;
for (i=0; list[i]; i++)
if (strcmp(list[i], name) == 0)
return i;
return -1; /* name not found */
}
void luaO_insertlist (GCnode *root, GCnode *node)
{
node->next = root->next;

View File

@@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 1.15 1998/01/13 13:27:25 roberto Exp $
** $Id: lobject.h,v 1.20 1998/06/11 18:21:37 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -13,20 +13,44 @@
#include "lua.h"
#ifdef DEBUG
#include "lauxlib.h"
#define LUA_INTERNALERROR(s) \
luaL_verror("INTERNAL ERROR - %s [%s:%d]",(s),__FILE__,__LINE__)
#define LUA_ASSERT(c,s) { if (!(c)) LUA_INTERNALERROR(s); }
#else
#define LUA_INTERNALERROR(s) /* empty */
#define LUA_ASSERT(c,s) /* empty */
#endif
/*
** "real" is the type "number" of Lua
** GREP LUA_NUMBER to change that
*/
#ifndef real
#define real float
#ifndef LUA_NUM_TYPE
#define LUA_NUM_TYPE double
#endif
/*
** format to convert number to strings
*/
#define NUMBER_FMT "%g"
typedef LUA_NUM_TYPE real;
#define Byte lua_Byte /* some systems have Byte as a predefined type */
typedef unsigned char Byte; /* unsigned 8 bits */
#define MAX_WORD (65534U) /* maximum value of a word (-2 for safety) */
#define MAX_INT (INT_MAX-2) /* maximum value of a int (-2 for safety) */
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
/* maximum value of a word of 2 bytes (-2 for safety); must fit in an "int" */
#if MAX_INT < 65534
#define MAX_WORD MAX_INT
#else
#define MAX_WORD 65534
#endif
typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */
@@ -88,10 +112,13 @@ typedef struct GCnode {
typedef struct TaggedString {
GCnode head;
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
unsigned long hash;
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
union {
TObject globalval;
struct {
TObject globalval;
long len; /* if this is a string, here is its length */
} s;
struct {
int tag;
void *v; /* if this is a userdata, here is its value */
@@ -169,7 +196,6 @@ extern TObject luaO_nilobject;
int luaO_equalObj (TObject *t1, TObject *t2);
int luaO_redimension (int oldsize);
int luaO_findstring (char *name, char *list[]);
void luaO_insertlist (GCnode *root, GCnode *node);
#ifdef OLD_ANSI

View File

@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.14 1997/12/30 19:08:23 roberto Exp roberto $
** $Id: lopcodes.h,v 1.17 1998/03/25 18:52:29 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -67,16 +67,16 @@ GETGLOBALW,/* w - VAR[CNST[w]] */
GETTABLE,/* - i t t[i] */
GETDOTTED,/* b t t[CONST[b]] */
GETDOTTED0,/* - t t[CONST[0]] */
GETDOTTED1,/* - t t[CONST[1]] */
GETDOTTED2,/* - t t[CONST[2]] */
GETDOTTED3,/* - t t[CONST[3]] */
GETDOTTED4,/* - t t[CONST[4]] */
GETDOTTED5,/* - t t[CONST[5]] */
GETDOTTED6,/* - t t[CONST[6]] */
GETDOTTED7,/* - t t[CONST[7]] */
GETDOTTEDW,/* w t t[CONST[w]] */
GETDOTTED,/* b t t[CNST[b]] */
GETDOTTED0,/* - t t[CNST[0]] */
GETDOTTED1,/* - t t[CNST[1]] */
GETDOTTED2,/* - t t[CNST[2]] */
GETDOTTED3,/* - t t[CNST[3]] */
GETDOTTED4,/* - t t[CNST[4]] */
GETDOTTED5,/* - t t[CNST[5]] */
GETDOTTED6,/* - t t[CNST[6]] */
GETDOTTED7,/* - t t[CNST[7]] */
GETDOTTEDW,/* w t t[CNST[w]] */
PUSHSELF,/* b t t t[CNST[b]] */
PUSHSELF0,/* - t t t[CNST[0]] */
@@ -119,9 +119,9 @@ SETTABLE0,/* - v i t - t[i]=v */
SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
SETLIST,/* b c v_b...v_1 t - t[i+c*FPF]=v_i */
SETLIST,/* b c v_c...v_1 t - t[i+b*FPF]=v_i */
SETLIST0,/* b v_b...v_1 t - t[i]=v_i */
SETLISTW,/* w c v_b...v_1 t - t[i+c*FPF]=v_i */
SETLISTW,/* w c v_c...v_1 t - t[i+w*FPF]=v_i */
SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */
SETMAP0,/* - v_0 k_0 t t t[k_0]=v_0 */
@@ -154,9 +154,8 @@ IFTUPJMPW,/* w x - (x!=nil)? PC-=w */
IFFUPJMP,/* b x - (x==nil)? PC-=b */
IFFUPJMPW,/* w x - (x==nil)? PC-=w */
CLOSURE,/* b proto v_b...v_1 c(proto) */
CLOSURE0,/* - proto c(proto) */
CLOSURE1,/* - proto v_1 c(proto) */
CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
CLOSUREW,/* w c v_b...v_1 closure(CNST[w], v_c...v_1) */
CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
CALLFUNC0,/* b v_b...v_1 f - f(v1,...,v_b) */

1333
lparser.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.c,v 1.4 1997/12/11 14:48:46 roberto Exp roberto $
** $Id: lstate.c,v 1.5 1997/12/17 20:48:58 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -17,13 +17,13 @@
#include "ltm.h"
LState *lua_state = NULL;
lua_State *lua_state = NULL;
void lua_open (void)
{
if (lua_state) return;
lua_state = luaM_new(LState);
lua_state = luaM_new(lua_State);
L->numCblocks = 0;
L->Cstack.base = 0;
L->Cstack.lua2C = 0;
@@ -76,3 +76,11 @@ void lua_close (void)
printf("total de memoria: %ld\n", totalmem);
#endif
}
lua_State *lua_setstate (lua_State *st) {
lua_State *old = lua_state;
lua_state = st;
return old;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 1.6 1997/12/17 20:48:58 roberto Exp roberto $
** $Id: lstate.h,v 1.10 1998/06/19 16:14:09 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -7,7 +7,10 @@
#ifndef lstate_h
#define lstate_h
#include <setjmp.h>
#include "lobject.h"
#include "lua.h"
#define MAX_C_BLOCKS 10
@@ -38,16 +41,26 @@ typedef struct {
} stringtable;
enum Status {LOCK, HOLD, FREE, COLLECTED};
struct ref {
TObject o;
enum {LOCK, HOLD, FREE, COLLECTED} status;
enum Status status;
};
typedef struct LState {
struct lua_State {
/* thread-specific state */
struct Stack stack; /* Lua stack */
struct C_Lua_Stack Cstack; /* C2lua struct */
void *errorJmp; /* current error recover point */
jmp_buf *errorJmp; /* current error recover point */
char *Mbuffer; /* global buffer */
char *Mbuffbase; /* current first position of Mbuffer */
int Mbuffsize; /* size of Mbuffer */
int Mbuffnext; /* next position to fill in Mbuffer */
struct C_Lua_Stack Cblocks[MAX_C_BLOCKS];
int numCblocks; /* number of nested Cblocks */
/* global state */
TObject errorim; /* error tag method */
GCnode rootproto; /* list of all prototypes */
GCnode rootcl; /* list of all closures */
@@ -57,22 +70,14 @@ typedef struct LState {
struct IM *IMtable; /* table for tag methods */
int IMtable_size; /* size of IMtable */
int last_tag; /* last used tag in IMtable */
struct FuncState *mainState, *currState; /* point to local structs in yacc */
struct LexState *lexstate; /* point to local struct in yacc */
struct ref *refArray; /* locked objects */
int refSize; /* size of refArray */
unsigned long GCthreshold;
unsigned long nblocks; /* number of 'blocks' currently allocated */
char *Mbuffer; /* global buffer */
char *Mbuffbase; /* current first position of Mbuffer */
int Mbuffsize; /* size of Mbuffer */
int Mbuffnext; /* next position to fill in Mbuffer */
struct C_Lua_Stack Cblocks[MAX_C_BLOCKS];
int numCblocks; /* number of nested Cblocks */
} LState;
};
extern LState *lua_state;
extern lua_State *lua_state;
#define L lua_state

145
lstring.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lstring.c,v 1.9 1997/12/30 19:15:52 roberto Exp roberto $
** $Id: lstring.c,v 1.12 1998/03/06 16:54:42 roberto Exp roberto $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -21,7 +21,8 @@
static TaggedString EMPTY = {{NULL, 2}, 0, 0L, {{LUA_T_NIL, {NULL}}}, {0}};
static TaggedString EMPTY = {{NULL, 2}, 0L, 0,
{{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
void luaS_init (void)
@@ -36,72 +37,87 @@ void luaS_init (void)
}
static unsigned long hash (char *s, int tag)
static unsigned long hash_s (char *s, long l)
{
unsigned long h;
if (tag != LUA_T_STRING)
h = (unsigned long)s;
else {
h = 0;
while (*s)
h = ((h<<5)-h)^(unsigned char)*(s++);
}
unsigned long h = 0;
while (l--)
h = ((h<<5)-h)^(unsigned char)*(s++);
return h;
}
static int newsize (stringtable *tb)
{
int size = tb->size;
int realuse = 0;
int i;
/* count how many entries are really in use */
for (i=0; i<size; i++)
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
realuse++;
if (2*(realuse+1) <= size) /* +1 is the new element */
return size; /* don't need to grow, just rehash to clear EMPTYs */
else
return luaO_redimension(size);
}
static void grow (stringtable *tb)
{
int newsize = luaO_redimension(tb->size);
TaggedString **newhash = luaM_newvector(newsize, TaggedString *);
int ns = newsize(tb);
TaggedString **newhash = luaM_newvector(ns, TaggedString *);
int i;
for (i=0; i<newsize; i++)
for (i=0; i<ns; i++)
newhash[i] = NULL;
/* rehash */
tb->nuse = 0;
for (i=0; i<tb->size; i++) {
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
int h = tb->hash[i]->hash%newsize;
int h = tb->hash[i]->hash%ns;
while (newhash[h])
h = (h+1)%newsize;
h = (h+1)%ns;
newhash[h] = tb->hash[i];
tb->nuse++;
}
}
luaM_free(tb->hash);
tb->size = newsize;
tb->size = ns;
tb->hash = newhash;
}
static TaggedString *newone (char *buff, int tag, unsigned long h)
static TaggedString *newone_s (char *str, long l, unsigned long h)
{
TaggedString *ts;
if (tag == LUA_T_STRING) {
long l = strlen(buff);
ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
strcpy(ts->str, buff);
ts->u.globalval.ttype = LUA_T_NIL; /* initialize global value */
ts->constindex = 0;
L->nblocks += gcsizestring(l);
}
else {
ts = (TaggedString *)luaM_malloc(sizeof(TaggedString));
ts->u.d.v = buff;
ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag;
ts->constindex = -1; /* tag -> this is a userdata */
L->nblocks++;
}
TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
memcpy(ts->str, str, l);
ts->str[l] = 0; /* ending 0 */
ts->u.s.globalval.ttype = LUA_T_NIL; /* initialize global value */
ts->u.s.len = l;
ts->constindex = 0;
L->nblocks += gcsizestring(l);
ts->head.marked = 0;
ts->head.next = (GCnode *)ts; /* signal it is in no list */
ts->hash = h;
return ts;
}
static TaggedString *insert (char *buff, int tag, stringtable *tb)
static TaggedString *newone_u (char *buff, int tag, unsigned long h)
{
TaggedString *ts = luaM_new(TaggedString);
ts->u.d.v = buff;
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
ts->constindex = -1; /* tag -> this is a userdata */
L->nblocks++;
ts->head.marked = 0;
ts->head.next = (GCnode *)ts; /* signal it is in no list */
ts->hash = h;
return ts;
}
static TaggedString *insert_s (char *str, long l, stringtable *tb)
{
TaggedString *ts;
unsigned long h = hash(buff, tag);
unsigned long h = hash_s(str, l);
int size = tb->size;
int i;
int j = -1;
@@ -112,9 +128,9 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb)
for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
if (ts == &EMPTY)
j = i;
else if ((ts->constindex >= 0) ? /* is a string? */
(tag == LUA_T_STRING && (strcmp(buff, ts->str) == 0)) :
((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v))
else if (ts->constindex >= 0 &&
ts->u.s.len == l &&
(memcmp(str, ts->str, l) == 0))
return ts;
if (++i == size) i=0;
}
@@ -123,18 +139,53 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb)
i = j;
else
tb->nuse++;
ts = tb->hash[i] = newone(buff, tag, h);
ts = tb->hash[i] = newone_s(str, l, h);
return ts;
}
static TaggedString *insert_u (void *buff, int tag, stringtable *tb)
{
TaggedString *ts;
unsigned long h = (unsigned long)buff;
int size = tb->size;
int i;
int j = -1;
if ((long)tb->nuse*3 >= (long)size*2) {
grow(tb);
size = tb->size;
}
for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
if (ts == &EMPTY)
j = i;
else if (ts->constindex < 0 && /* is a udata? */
(tag == ts->u.d.tag || tag == LUA_ANYTAG) &&
buff == ts->u.d.v)
return ts;
if (++i == size) i=0;
}
/* not found */
if (j != -1) /* is there an EMPTY space? */
i = j;
else
tb->nuse++;
ts = tb->hash[i] = newone_u(buff, tag, h);
return ts;
}
TaggedString *luaS_createudata (void *udata, int tag)
{
return insert(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]);
return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]);
}
TaggedString *luaS_newlstr (char *str, long l)
{
int i = (l==0)?0:(unsigned char)str[0];
return insert_s(str, l, &L->string_root[i%NUM_HASHS]);
}
TaggedString *luaS_new (char *str)
{
return insert(str, LUA_T_STRING, &L->string_root[(unsigned)str[0]%NUM_HASHS]);
return luaS_newlstr(str, strlen(str));
}
TaggedString *luaS_newfixedstring (char *str)
@@ -150,7 +201,7 @@ void luaS_free (TaggedString *l)
{
while (l) {
TaggedString *next = (TaggedString *)l->head.next;
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(strlen(l->str));
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
luaM_free(l);
l = next;
}
@@ -207,7 +258,7 @@ TaggedString *luaS_collectudata (void)
for (j=0; j<tb->size; j++) {
TaggedString *t = tb->hash[j];
if (t == NULL || t == &EMPTY || t->constindex != -1)
continue; /* get only user datas */
continue; /* get only user data */
t->head.next = (GCnode *)frees;
frees = t;
tb->hash[j] = &EMPTY;
@@ -236,7 +287,7 @@ void luaS_freeall (void)
void luaS_rawsetglobal (TaggedString *ts, TObject *newval)
{
ts->u.globalval = *newval;
ts->u.s.globalval = *newval;
if (ts->head.next == (GCnode *)ts) { /* is not in list? */
ts->head.next = L->rootglobal.next;
L->rootglobal.next = (GCnode *)ts;
@@ -248,7 +299,7 @@ char *luaS_travsymbol (int (*fn)(TObject *))
{
TaggedString *g;
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
if (fn(&g->u.globalval))
if (fn(&g->u.s.globalval))
return g->str;
return NULL;
}
@@ -257,6 +308,6 @@ char *luaS_travsymbol (int (*fn)(TObject *))
int luaS_globaldefined (char *name)
{
TaggedString *ts = luaS_new(name);
return ts->u.globalval.ttype != LUA_T_NIL;
return ts->u.s.globalval.ttype != LUA_T_NIL;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstring.h,v 1.5 1997/11/26 18:53:45 roberto Exp roberto $
** $Id: lstring.h,v 1.6 1997/12/01 20:31:25 roberto Exp roberto $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -15,6 +15,7 @@ void luaS_init (void);
TaggedString *luaS_createudata (void *udata, int tag);
TaggedString *luaS_collector (void);
void luaS_free (TaggedString *l);
TaggedString *luaS_newlstr (char *str, long l);
TaggedString *luaS_new (char *str);
TaggedString *luaS_newfixedstring (char *str);
void luaS_rawsetglobal (TaggedString *ts, TObject *newval);

232
lstrlib.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lstrlib.c,v 1.6 1998/01/09 14:44:55 roberto Exp $
** $Id: lstrlib.c,v 1.17 1998/06/29 18:24:06 roberto Exp roberto $
** Standard library for strings and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -19,85 +19,98 @@
static void addnchar (char *s, int n)
{
char *b = luaL_openspace(n);
strncpy(b, s, n);
memcpy(b, s, n);
luaL_addsize(n);
}
static void addstr (char *s)
{
addnchar(s, strlen(s));
}
static void str_len (void)
{
lua_pushnumber(strlen(luaL_check_string(1)));
long l;
luaL_check_lstr(1, &l);
lua_pushnumber(l);
}
static void closeandpush (void)
{
luaL_addchar(0);
lua_pushstring(luaL_buffer());
lua_pushlstring(luaL_buffer(), luaL_getsize());
}
static long posrelat (long pos, long len)
{
/* relative string position: negative means back from end */
return (pos>=0) ? pos : len+pos+1;
}
static void str_sub (void)
{
char *s = luaL_check_string(1);
long l = strlen(s);
long start = (long)luaL_check_number(2);
long end = (long)luaL_opt_number(3, -1);
if (start < 0) start = l+start+1;
if (end < 0) end = l+end+1;
if (1 <= start && start <= end && end <= l) {
luaL_resetbuffer();
addnchar(s+start-1, end-start+1);
closeandpush();
}
long l;
char *s = luaL_check_lstr(1, &l);
long start = posrelat(luaL_check_number(2), l);
long end = posrelat(luaL_opt_number(3, -1), l);
if (1 <= start && start <= end && end <= l)
lua_pushlstring(s+start-1, end-start+1);
else lua_pushstring("");
}
static void str_lower (void)
{
char *s;
long l;
int i;
char *s = luaL_check_lstr(1, &l);
luaL_resetbuffer();
for (s = luaL_check_string(1); *s; s++)
luaL_addchar(tolower((unsigned char)*s));
for (i=0; i<l; i++)
luaL_addchar(tolower((unsigned char)(s[i])));
closeandpush();
}
static void str_upper (void)
{
char *s;
long l;
int i;
char *s = luaL_check_lstr(1, &l);
luaL_resetbuffer();
for (s = luaL_check_string(1); *s; s++)
luaL_addchar(toupper((unsigned char)*s));
for (i=0; i<l; i++)
luaL_addchar(toupper((unsigned char)(s[i])));
closeandpush();
}
static void str_rep (void)
{
char *s = luaL_check_string(1);
long l;
char *s = luaL_check_lstr(1, &l);
int n = (int)luaL_check_number(2);
luaL_resetbuffer();
while (n-- > 0)
addstr(s);
addnchar(s, l);
closeandpush();
}
static void str_ascii (void)
static void str_byte (void)
{
char *s = luaL_check_string(1);
long pos = (long)luaL_opt_number(2, 1) - 1;
luaL_arg_check(0<=pos && pos<strlen(s), 2, "out of range");
lua_pushnumber((unsigned char)s[pos]);
long l;
char *s = luaL_check_lstr(1, &l);
long pos = posrelat(luaL_opt_number(2, 1), l);
luaL_arg_check(0<pos && pos<=l, 2, "out of range");
lua_pushnumber((unsigned char)s[pos-1]);
}
static void str_char (void) {
int i = 0;
luaL_resetbuffer();
while (lua_getparam(++i) != LUA_NOOBJECT) {
double c = luaL_check_number(i);
luaL_arg_check((unsigned char)c == c, i, "invalid value");
luaL_addchar((int)c);
}
closeandpush();
}
/*
@@ -110,6 +123,7 @@ static void str_ascii (void)
struct Capture {
int level; /* total number of captures (finished or unfinished) */
char *src_end; /* end ('\0') of source string */
struct {
char *init;
int len; /* -1 signals unfinished capture */
@@ -124,14 +138,8 @@ struct Capture {
static void push_captures (struct Capture *cap)
{
int i;
for (i=0; i<cap->level; i++) {
int l = cap->capture[i].len;
char *buff = luaL_openspace(l+1);
if (l == -1) lua_error("unfinished capture");
strncpy(buff, cap->capture[i].init, l);
buff[l] = 0;
lua_pushstring(buff);
}
for (i=0; i<cap->level; i++)
lua_pushlstring(cap->capture[i].init, cap->capture[i].len);
}
@@ -163,16 +171,16 @@ static char *bracket_end (char *p)
static int matchclass (int c, int cl)
{
int res;
if (c == 0) return 0;
switch (tolower((unsigned char)cl)) {
case 'w' : res = isalnum((unsigned char)c); break;
case 'd' : res = isdigit((unsigned char)c); break;
case 's' : res = isspace((unsigned char)c); break;
case 'a' : res = isalpha((unsigned char)c); break;
case 'p' : res = ispunct((unsigned char)c); break;
case 'l' : res = islower((unsigned char)c); break;
case 'u' : res = isupper((unsigned char)c); break;
case 'c' : res = iscntrl((unsigned char)c); break;
switch (tolower(cl)) {
case 'a' : res = isalpha(c); break;
case 'c' : res = iscntrl(c); break;
case 'd' : res = isdigit(c); break;
case 'l' : res = islower(c); break;
case 'p' : res = ispunct(c); break;
case 's' : res = isspace(c); break;
case 'u' : res = isupper(c); break;
case 'w' : res = isalnum(c); break;
case 'z' : res = (c == '\0'); break;
default: return (cl == c);
}
return (islower((unsigned char)cl) ? res : !res);
@@ -182,48 +190,49 @@ static int matchclass (int c, int cl)
int luaI_singlematch (int c, char *p, char **ep)
{
switch (*p) {
case '.':
case '.': /* matches any char */
*ep = p+1;
return (c != 0);
case '\0':
return 1;
case '\0': /* end of pattern; matches nothing */
*ep = p;
return 0;
case ESC:
if (*(++p) == '\0')
luaL_verror("incorrect pattern (ends with `%c')", ESC);
*ep = p+1;
return matchclass(c, *p);
return matchclass(c, (unsigned char)*p);
case '[': {
char *end = bracket_end(p+1);
int sig = *(p+1) == '^' ? (p++, 0) : 1;
if (end == NULL) lua_error("incorrect pattern (missing `]')");
*ep = end+1;
if (c == 0) return 0;
while (++p < end) {
if (*p == ESC) {
if (((p+1) < end) && matchclass(c, *++p)) return sig;
if (((p+1) < end) && matchclass(c, (unsigned char)*++p))
return sig;
}
else if ((*(p+1) == '-') && (p+2 < end)) {
p+=2;
if (*(p-2) <= c && c <= *p) return sig;
if ((unsigned char)*(p-2) <= c && c <= (unsigned char)*p)
return sig;
}
else if (*p == c) return sig;
else if ((unsigned char)*p == c) return sig;
}
return !sig;
}
default:
*ep = p+1;
return (*p == c);
return ((unsigned char)*p == c);
}
}
static char *matchbalance (char *s, int b, int e)
static char *matchbalance (char *s, int b, int e, struct Capture *cap)
{
if (*s != b) return NULL;
else {
int cont = 1;
while (*(++s)) {
while (++s < cap->src_end) {
if (*s == e) {
if (--cont == 0) return s+1;
}
@@ -240,9 +249,10 @@ static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
p++;
if (isdigit((unsigned char)*p)) { /* capture */
int l = check_cap(*p, cap);
int len = cap->capture[l].len;
*ep = p+1;
if (strncmp(cap->capture[l].init, s, cap->capture[l].len) == 0)
return s+cap->capture[l].len;
if (cap->src_end-s >= len && memcmp(cap->capture[l].init, s, len) == 0)
return s+len;
else return NULL;
}
else if (*p == 'b') { /* balanced string */
@@ -250,11 +260,13 @@ static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
if (*p == 0 || *(p+1) == 0)
lua_error("unbalanced pattern");
*ep = p+2;
return matchbalance(s, *p, *(p+1));
return matchbalance(s, *p, *(p+1), cap);
}
else p--; /* and go through */
}
return (luaI_singlematch(*s, p, ep) ? s+1 : NULL);
/* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */
return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ?
s+1 : NULL;
}
@@ -281,7 +293,7 @@ static char *match (char *s, char *p, struct Capture *cap)
return res;
}
case '\0': case '$': /* (possibly) end of pattern */
if (*p == 0 || (*(p+1) == 0 && *s == 0))
if (*p == 0 || (*(p+1) == 0 && s == cap->src_end))
return s;
/* else go through */
default: { /* it is a pattern item */
@@ -290,21 +302,21 @@ static char *match (char *s, char *p, struct Capture *cap)
switch (*ep) {
case '*': { /* repetition */
char *res;
if (s1 && (res = match(s1, p, cap)))
if (s1 && s1>s && ((res=match(s1, p, cap)) != NULL))
return res;
p=ep+1; goto init; /* else return match(s, ep+1, cap); */
}
case '?': { /* optional */
char *res;
if (s1 && (res = match(s1, ep+1, cap)))
if (s1 && ((res=match(s1, ep+1, cap)) != NULL))
return res;
p=ep+1; goto init; /* else return match(s, ep+1, cap); */
}
case '-': { /* repetition */
char *res;
if ((res = match(s, ep+1, cap)) != 0)
if ((res = match(s, ep+1, cap)) != NULL)
return res;
else if (s1) {
else if (s1 && s1>s) {
s = s1;
goto init; /* return match(s1, p, cap); */
}
@@ -322,23 +334,26 @@ static char *match (char *s, char *p, struct Capture *cap)
static void str_find (void)
{
char *s = luaL_check_string(1);
long l;
char *s = luaL_check_lstr(1, &l);
char *p = luaL_check_string(2);
long init = (long)luaL_opt_number(3, 1) - 1;
luaL_arg_check(0 <= init && init <= strlen(s), 3, "out of range");
long init = posrelat(luaL_opt_number(3, 1), l) - 1;
struct Capture cap;
luaL_arg_check(0 <= init && init <= l, 3, "out of range");
if (lua_getparam(4) != LUA_NOOBJECT ||
strpbrk(p, SPECIALS) == NULL) { /* no special caracters? */
strpbrk(p, SPECIALS) == NULL) { /* no special characters? */
char *s2 = strstr(s+init, p);
if (s2) {
lua_pushnumber(s2-s+1);
lua_pushnumber(s2-s+strlen(p));
return;
}
}
else {
int anchor = (*p == '^') ? (p++, 1) : 0;
char *s1=s+init;
cap.src_end = s+l;
do {
struct Capture cap;
char *res;
cap.level = 0;
if ((res=match(s1, p, &cap)) != NULL) {
@@ -347,8 +362,9 @@ static void str_find (void)
push_captures(&cap);
return;
}
} while (*s1++ && !anchor);
} while (s1++<cap.src_end && !anchor);
}
lua_pushnil(); /* if arrives here, it didn't find */
}
@@ -356,16 +372,23 @@ static void add_s (lua_Object newp, struct Capture *cap)
{
if (lua_isstring(newp)) {
char *news = lua_getstring(newp);
while (*news) {
if (*news != ESC || !isdigit((unsigned char)*++news))
luaL_addchar(*news++);
int l = lua_strlen(newp);
int i;
for (i=0; i<l; i++) {
if (news[i] != ESC)
luaL_addchar(news[i]);
else {
int l = check_cap(*news++, cap);
addnchar(cap->capture[l].init, cap->capture[l].len);
i++; /* skip ESC */
if (!isdigit((unsigned char)news[i]))
luaL_addchar(news[i]);
else {
int level = check_cap(news[i], cap);
addnchar(cap->capture[level].init, cap->capture[level].len);
}
}
}
}
else if (lua_isfunction(newp)) {
else { /* is a function */
lua_Object res;
int status;
int oldbuff;
@@ -381,24 +404,28 @@ static void add_s (lua_Object newp, struct Capture *cap)
lua_error(NULL);
}
res = lua_getresult(1);
addstr(lua_isstring(res) ? lua_getstring(res) : "");
if (lua_isstring(res))
addnchar(lua_getstring(res), lua_strlen(res));
lua_endblock();
}
else luaL_arg_check(0, 3, "string or function expected");
}
static void str_gsub (void)
{
char *src = luaL_check_string(1);
long srcl;
char *src = luaL_check_lstr(1, &srcl);
char *p = luaL_check_string(2);
lua_Object newp = lua_getparam(3);
int max_s = (int)luaL_opt_number(4, strlen(src)+1);
int max_s = (int)luaL_opt_number(4, srcl+1);
int anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0;
struct Capture cap;
luaL_arg_check(lua_isstring(newp) || lua_isfunction(newp), 3,
"string or function expected");
luaL_resetbuffer();
cap.src_end = src+srcl;
while (n < max_s) {
struct Capture cap;
char *e;
cap.level = 0;
e = match(src, p, &cap);
@@ -408,12 +435,12 @@ static void str_gsub (void)
}
if (e && e>src) /* non empty match? */
src = e; /* skip it */
else if (*src)
else if (src < cap.src_end)
luaL_addchar(*src++);
else break;
if (anchor) break;
}
addstr(src);
addnchar(src, cap.src_end-src);
closeandpush();
lua_pushnumber(n); /* number of substitutions */
}
@@ -436,6 +463,8 @@ static void str_format (void)
{
int arg = 1;
char *strfrmt = luaL_check_string(arg);
struct Capture cap;
cap.src_end = strfrmt+strlen(strfrmt)+1;
luaL_resetbuffer();
while (*strfrmt) {
if (*strfrmt != '%')
@@ -444,20 +473,19 @@ static void str_format (void)
luaL_addchar(*strfrmt++); /* %% */
else { /* format item */
char form[MAX_FORMAT]; /* store the format ('%...') */
struct Capture cap;
char *buff;
char *initf = strfrmt;
form[0] = '%';
cap.level = 0;
strfrmt = match(strfrmt, "%d?%$?[-+ #]*(%d*)%.?(%d*)", &cap);
if (cap.capture[0].len > 3 || cap.capture[1].len > 3) /* < 1000? */
lua_error("invalid format (width or precision too long)");
if (isdigit((unsigned char)initf[0]) && initf[1] == '$') {
arg = initf[0] - '0';
initf += 2; /* skip the 'n$' */
}
arg++;
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include convertion */
strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
if (cap.capture[0].len > 2 || cap.capture[1].len > 2) /* < 100? */
lua_error("invalid format (width or precision too long)");
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
form[strfrmt-initf+2] = 0;
buff = luaL_openspace(1000); /* to store the formatted value */
switch (*strfrmt++) {
@@ -470,10 +498,12 @@ static void str_format (void)
sprintf(buff, form, s);
break;
}
case 'c': case 'd': case 'i': case 'o':
case 'u': case 'x': case 'X':
case 'c': case 'd': case 'i':
sprintf(buff, form, (int)luaL_check_number(arg));
break;
case 'o': case 'u': case 'x': case 'X':
sprintf(buff, form, (unsigned int)luaL_check_number(arg));
break;
case 'e': case 'E': case 'f': case 'g': case 'G':
sprintf(buff, form, luaL_check_number(arg));
break;
@@ -492,8 +522,10 @@ static struct luaL_reg strlib[] = {
{"strsub", str_sub},
{"strlower", str_lower},
{"strupper", str_upper},
{"strchar", str_char},
{"strrep", str_rep},
{"ascii", str_ascii},
{"ascii", str_byte}, /* for compatibility */
{"strbyte", str_byte},
{"format", str_format},
{"strfind", str_find},
{"gsub", str_gsub}

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltable.c,v 1.10 1998/01/09 14:44:55 roberto Exp roberto $
** $Id: ltable.c,v 1.11 1998/01/13 18:06:27 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -121,36 +121,36 @@ Hash *luaH_new (int nhash)
}
/*
** Rehash:
** Check if table has deleted slots. It it has, it does not need to
** grow, since rehash will reuse them.
*/
static int emptyslots (Hash *t)
static int newsize (Hash *t)
{
Node *v = t->node;
int size = nhash(t);
int realuse = 0;
int i;
for (i=nhash(t)-1; i>=0; i--) {
Node *n = node(t, i);
if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) == LUA_T_NIL)
return 1;
for (i=0; i<size; i++) {
if (ttype(ref(v+i)) != LUA_T_NIL && ttype(val(v+i)) != LUA_T_NIL)
realuse++;
}
return 0;
if (2*(realuse+1) <= size) /* +1 is the new element */
return size; /* don't need to grow, just rehash */
else
return luaO_redimension(size);
}
static void rehash (Hash *t)
{
int nold = nhash(t);
int nold = nhash(t);
Node *vold = nodevector(t);
int nnew = newsize(t);
int i;
if (!emptyslots(t))
nhash(t) = luaO_redimension(nhash(t));
nodevector(t) = hashnodecreate(nhash(t));
nodevector(t) = hashnodecreate(nnew);
nhash(t) = nnew;
for (i=0; i<nold; i++) {
Node *n = vold+i;
if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL)
*node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */
}
L->nblocks += gcsize(t->nhash)-gcsize(nold);
L->nblocks += gcsize(nnew)-gcsize(nold);
luaM_free(vold);
}

12
ltm.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.c,v 1.12 1997/12/15 16:17:20 roberto Exp roberto $
** $Id: ltm.c,v 1.15 1998/03/11 13:59:50 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -24,7 +24,7 @@ char *luaT_eventname[] = { /* ORDER IM */
static int luaI_checkevent (char *name, char *list[])
{
int e = luaO_findstring(name, list);
int e = luaL_findstring(name, list);
if (e < 0)
luaL_verror("`%.50s' is not a valid event name", name);
return e;
@@ -123,7 +123,7 @@ int luaT_efectivetag (TObject *o)
#ifdef DEBUG
case LUA_T_PMARK: case LUA_T_CMARK:
case LUA_T_CLMARK: case LUA_T_LINE:
lua_error("internal error");
LUA_INTERNALERROR("invalid type");
#endif
default:
return t;
@@ -148,7 +148,7 @@ void luaT_settagmethod (int t, char *event, TObject *func)
int e = luaI_checkevent(event, luaT_eventname);
checktag(t);
if (!validevent(t, e))
luaL_verror("settagmethod: cannot change internal method `%.20s' for tag %d",
luaL_verror("settagmethod: cannot change tag method `%.20s' for tag %d",
luaT_eventname[e], t);
*func = *luaT_getim(t,e);
*luaT_getim(t, e) = temp;
@@ -214,7 +214,7 @@ void luaT_setfallback (void)
char *name = luaL_check_string(1);
lua_Object func = lua_getparam(2);
luaL_arg_check(lua_isfunction(func), 2, "function expected");
switch (luaO_findstring(name, oldnames)) {
switch (luaL_findstring(name, oldnames)) {
case 0: /* old error fallback */
oldfunc = L->errorim;
L->errorim = *luaA_Address(func);
@@ -243,7 +243,7 @@ void luaT_setfallback (void)
}
default: {
int e;
if ((e = luaO_findstring(name, luaT_eventname)) >= 0) {
if ((e = luaL_findstring(name, luaT_eventname)) >= 0) {
oldfunc = *luaT_getim(LUA_T_NIL, e);
fillvalids(e, luaA_Address(func));
replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB;

47
lua.c
View File

@@ -1,11 +1,13 @@
/*
** $Id: lua.c,v 1.11 1997/12/22 18:05:23 roberto Exp roberto $
** $Id: lua.c,v 1.13 1998/01/19 19:49:49 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
@@ -26,6 +28,39 @@
#endif
typedef void (*handler)(int); /* type for signal actions */
static void laction (int i);
static handler lreset (void)
{
lua_linehook = NULL;
lua_callhook = NULL;
return signal(SIGINT, laction);
}
static void lstop (void)
{
lreset();
lua_error("interrupted!");
}
static void laction (int i)
{
lua_linehook = (lua_LHFunction)lstop;
lua_callhook = (lua_CHFunction)lstop;
}
static int ldo (int (*f)(char *), char *name)
{
int res;
handler h = lreset();
res = f(name); /* dostring | dofile */
signal(SIGINT, h); /* restore old action */
return res;
}
static void print_message (void)
{
fprintf(stderr,
@@ -84,7 +119,7 @@ static void manual_input (int prompt)
else buffer[i++] = c;
}
buffer[i] = 0;
lua_dostring(buffer);
ldo(lua_dostring, buffer);
lua_endblock();
}
printf("\n");
@@ -105,13 +140,13 @@ int main (int argc, char *argv[])
manual_input(1);
}
else
lua_dofile(NULL); /* executes stdin as a file */
ldo(lua_dofile, NULL); /* executes stdin as a file */
}
else for (i=1; i<argc; i++) {
if (argv[i][0] == '-') { /* option? */
switch (argv[i][1]) {
case 0:
lua_dofile(NULL); /* executes stdin as a file */
ldo(lua_dofile, NULL); /* executes stdin as a file */
break;
case 'i':
manual_input(1);
@@ -128,7 +163,7 @@ int main (int argc, char *argv[])
break;
case 'e':
i++;
if (lua_dostring(argv[i]) != 0) {
if (ldo(lua_dostring, argv[i]) != 0) {
fprintf(stderr, "lua: error running argument `%s'\n", argv[i]);
return 1;
}
@@ -141,7 +176,7 @@ int main (int argc, char *argv[])
else if (strchr(argv[i], '='))
assign(argv[i]);
else {
int result = lua_dofile(argv[i]);
int result = ldo(lua_dofile, argv[i]);
if (result) {
if (result == 2) {
fprintf(stderr, "lua: cannot execute file ");

96
lua.h
View File

@@ -1,50 +1,18 @@
/*
** $Id: lua.h,v 1.13 1998/01/02 17:46:32 roberto Exp roberto $
** $Id: lua.h,v 1.22 1998/06/15 21:34:14 roberto Exp roberto $
** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: lua@tecgraf.puc-rio.br
** www: http://www.tecgraf.puc-rio.br/lua/
** See Copyright Notice at the end of this file
*/
/*********************************************************************
* Copyright (c) 1994-1998 TeCGraf, PUC-Rio.
* Written by Waldemar Celes Filho, Roberto Ierusalimschy and
* Luiz Henrique de Figueiredo.
* All rights reserved.
*
* Permission is hereby granted, without written agreement and with­
* out license or royalty fees, to use, copy, modify, and distribute
* this software and its documentation for any purpose, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall ap­
* pear in all copies or substantial portions of this software.
*
* The name "Lua" cannot be used for any modified form of this soft­
* ware that does not originate from the authors. Nevertheless, the
* name "Lua" may and should be used to designate the language im­
* plemented and described in this package, even if embedded in any
* other system, as long as its syntax and semantics remain un­
* changed.
*
* The authors specifically disclaim any warranties, including, but
* not limited to, the implied warranties of merchantability and
* fitness for a particular purpose. The software provided hereunder
* is on an "as is" basis, and the authors have no obligation to
* provide maintenance, support, updates, enhancements, or modifica­
* tions. In no event shall TeCGraf, PUC-Rio, or the authors be li­
* able to any party for direct, indirect, special, incidental, or
* consequential damages arising out of the use of this software and
* its documentation.
*********************************************************************/
#ifndef lua_h
#define lua_h
#define LUA_VERSION "Lua 3.1 (alpha)"
#define LUA_COPYRIGHT "Copyright (C) 1994-1998 TeCGraf"
#define LUA_VERSION "Lua 3.1"
#define LUA_COPYRIGHT "Copyright (C) 1994-1998 TeCGraf, PUC-Rio"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
@@ -55,9 +23,12 @@
typedef void (*lua_CFunction) (void);
typedef unsigned int lua_Object;
typedef struct lua_State lua_State;
extern lua_State *lua_state;
void lua_open (void);
void lua_close (void);
lua_State *lua_setstate (lua_State *st);
lua_Object lua_settagmethod (int tag, char *event); /* In: new method */
lua_Object lua_gettagmethod (int tag, char *event);
@@ -70,6 +41,8 @@ void lua_settag (int tag); /* In: object */
void lua_error (char *s);
int lua_dofile (char *filename); /* Out: returns */
int lua_dostring (char *string); /* Out: returns */
int lua_dobuffer (char *buff, int size, char *name);
/* Out: returns */
int lua_callfunction (lua_Object f);
/* In: parameters; Out: returns */
@@ -90,14 +63,16 @@ int lua_isfunction (lua_Object object);
double lua_getnumber (lua_Object object);
char *lua_getstring (lua_Object object);
long lua_strlen (lua_Object object);
lua_CFunction lua_getcfunction (lua_Object object);
void *lua_getuserdata (lua_Object object);
void lua_pushnil (void);
void lua_pushnumber (double n);
void lua_pushlstring (char *s, long len);
void lua_pushstring (char *s);
void lua_pushCclosure (lua_CFunction fn, int n);
void lua_pushcclosure (lua_CFunction fn, int n);
void lua_pushusertag (void *u, int tag);
void lua_pushobject (lua_Object object);
@@ -126,20 +101,27 @@ long lua_collectgarbage (long limit);
/* =============================================================== */
/* some useful macros */
/* some useful macros/derived functions */
int (lua_call) (char *name);
#define lua_call(name) lua_callfunction(lua_getglobal(name))
void (lua_pushref) (int ref);
#define lua_pushref(ref) lua_pushobject(lua_getref(ref))
int (lua_refobject) (lua_Object o, int l);
#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l))
void (lua_register) (char *n, lua_CFunction f);
#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n))
void (lua_pushuserdata) (void *u);
#define lua_pushuserdata(u) lua_pushusertag(u, 0)
#define lua_pushcfunction(f) lua_pushCclosure(f, 0)
void (lua_pushcfunction) (lua_CFunction f);
#define lua_pushcfunction(f) lua_pushcclosure(f, 0)
int (lua_clonetag) (int t);
#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t))
@@ -176,3 +158,39 @@ lua_Object lua_setfallback (char *event, lua_CFunction fallback);
#endif
#endif
/******************************************************************************
* Copyright (c) 1994-1998 TeCGraf, PUC-Rio. All rights reserved.
*
* Permission is hereby granted, without written agreement and without license
* or royalty fees, to use, copy, modify, and distribute this software and its
* documentation for any purpose, including commercial applications, subject to
* the following conditions:
*
* - The above copyright notice and this permission notice shall appear in all
* copies or substantial portions of this software.
*
* - The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in a
* product, an acknowledgment in the product documentation would be greatly
* appreciated (but it is not required).
*
* - Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* The authors specifically disclaim any warranties, including, but not limited
* to, the implied warranties of merchantability and fitness for a particular
* purpose. The software provided hereunder is on an "as is" basis, and the
* authors have no obligation to provide maintenance, support, updates,
* enhancements, or modifications. In no event shall TeCGraf, PUC-Rio, or the
* authors be held liable to any party for direct, indirect, special,
* incidental, or consequential damages arising out of the use of this software
* and its documentation.
*
* The Lua language and this implementation have been entirely designed and
* written by Waldemar Celes Filho, Roberto Ierusalimschy and
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
* This implementation contains no third-party code.
******************************************************************************/

939
lua.stx
View File

@@ -1,939 +0,0 @@
%{
/*
** $Id: lua.stx,v 1.32 1998/01/12 13:00:51 roberto Exp roberto $
** Syntax analizer and code generator
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "llex.h"
#include "lmem.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "lua.h"
#include "luadebug.h"
#include "lzio.h"
int luaY_parse (void);
#define MES_LIM(x) "(limit=" x ")"
/* size of a "normal" jump instruction: OpCode + 1 byte */
#define JMPSIZE 2
/* maximum number of local variables */
#define MAXLOCALS 32
#define SMAXLOCALS "32"
#define MINGLOBAL (MAXLOCALS+1)
/* maximum number of variables in a multiple assignment */
#define MAXVAR 32
#define SMAXVAR "32"
/* maximum number of nested functions */
#define MAXSTATES 6
#define SMAXSTATES "6"
/* maximum number of upvalues */
#define MAXUPVALUES 16
#define SMAXUPVALUES "16"
/*
** Variable descriptor:
** if 0<n<MINGLOBAL, represents local variable indexed by (n-1);
** if MINGLOBAL<=n, represents global variable at position (n-MINGLOBAL);
** if n<0, indexed variable with index (-n)-1 (table on top of stack);
** if n==0, an indexed variable (table and index on top of stack)
** Must be long to store negative Word values.
*/
typedef long vardesc;
#define isglobal(v) (MINGLOBAL<=(v))
#define globalindex(v) ((v)-MINGLOBAL)
#define islocal(v) (0<(v) && (v)<MINGLOBAL)
#define localindex(v) ((v)-1)
#define isdot(v) (v<0)
#define dotindex(v) ((-(v))-1)
/* state needed to generate code for a given function */
typedef struct FuncState {
TProtoFunc *f; /* current function header */
int pc; /* next position to code */
TaggedString *localvar[MAXLOCALS]; /* store local variable names */
int stacksize; /* number of values on activation register */
int maxstacksize; /* maximum number of values on activation register */
int nlocalvar; /* number of active local variables */
int nupvalues; /* number of upvalues */
int nvars; /* number of entries in f->locvars */
int maxcode; /* size of f->code */
int maxvars; /* size of f->locvars (-1 if no debug information) */
int maxconsts; /* size of f->consts */
vardesc varbuffer[MAXVAR]; /* variables in an assignment list */
vardesc upvalues[MAXUPVALUES]; /* upvalues */
} FuncState;
#define YYPURE 1
void luaY_syntaxerror (char *s, char *token)
{
if (token[0] == 0)
token = "<eof>";
luaL_verror("%.100s;\n last token read: \"%.50s\" at line %d in file %.50s",
s, token, L->lexstate->linenumber, L->mainState->f->fileName->str);
}
void luaY_error (char *s)
{
luaY_syntaxerror(s, luaX_lasttoken());
}
static void check_pc (int n)
{
FuncState *fs = L->currState;
if (fs->pc+n > fs->maxcode)
fs->maxcode = luaM_growvector(&fs->f->code, fs->maxcode,
Byte, codeEM, MAX_INT);
}
static void code_byte (Byte c)
{
check_pc(1);
L->currState->f->code[L->currState->pc++] = c;
}
static void deltastack (int delta)
{
FuncState *fs = L->currState;
fs->stacksize += delta;
if (fs->stacksize > fs->maxstacksize) {
if (fs->stacksize > 255)
luaY_error("function/expression too complex");
fs->maxstacksize = fs->stacksize;
}
}
static int code_oparg_at (int pc, OpCode op, int builtin, int arg, int delta)
{
Byte *code = L->currState->f->code;
deltastack(delta);
if (arg < builtin) {
code[pc] = op+1+arg;
return 1;
}
else if (arg <= 255) {
code[pc] = op;
code[pc+1] = arg;
return 2;
}
else if (arg <= MAX_WORD) {
code[pc] = op+1+builtin;
code[pc+1] = arg&0xFF;
code[pc+2] = arg>>8;
return 3;
}
else luaY_error("code too long " MES_LIM("64K"));
return 0; /* to avoid warnings */
}
static int fix_opcode (int pc, OpCode op, int builtin, int arg)
{
FuncState *fs = L->currState;
if (arg < builtin) { /* close space */
luaO_memdown(fs->f->code+pc+1, fs->f->code+pc+2, fs->pc-(pc+2));
fs->pc--;
}
else if (arg > 255) { /* open space */
check_pc(1);
luaO_memup(fs->f->code+pc+1, fs->f->code+pc, fs->pc-pc);
fs->pc++;
}
return code_oparg_at(pc, op, builtin, arg, 0) - 2;
}
static void code_oparg (OpCode op, int builtin, int arg, int delta)
{
check_pc(3); /* maximum code size */
L->currState->pc += code_oparg_at(L->currState->pc, op, builtin, arg, delta);
}
static void code_opcode (OpCode op, int delta)
{
deltastack(delta);
code_byte(op);
}
static void code_pop (OpCode op)
{
code_opcode(op, -1);
}
/* binary operations get 2 arguments and leave one, so they pop one */
#define code_binop(op) code_pop(op)
static void code_neutralop (OpCode op)
{
code_opcode(op, 0);
}
/* unary operations get 1 argument and leave one, so they are neutral */
#define code_unop(op) code_neutralop(op)
static void code_constant (int c)
{
code_oparg(PUSHCONSTANT, 8, c, 1);
}
static int next_constant (FuncState *cs)
{
TProtoFunc *f = cs->f;
if (f->nconsts >= cs->maxconsts) {
cs->maxconsts = luaM_growvector(&f->consts, cs->maxconsts, TObject,
constantEM, MAX_WORD);
}
return f->nconsts++;
}
static int string_constant (TaggedString *s, FuncState *cs)
{
TProtoFunc *f = cs->f;
int c = s->constindex;
if (!(c < f->nconsts &&
ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) {
c = next_constant(cs);
ttype(&f->consts[c]) = LUA_T_STRING;
tsvalue(&f->consts[c]) = s;
s->constindex = c; /* hint for next time */
}
return c;
}
static void code_string (TaggedString *s)
{
code_constant(string_constant(s, L->currState));
}
#define LIM 20
static int real_constant (real r)
{
/* check whether 'r' has appeared within the last LIM entries */
TObject *cnt = L->currState->f->consts;
int c = L->currState->f->nconsts;
int lim = c < LIM ? 0 : c-LIM;
while (--c >= lim) {
if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r)
return c;
}
/* not found; create a luaM_new entry */
c = next_constant(L->currState);
cnt = L->currState->f->consts; /* 'next_constant' may reallocate this vector */
ttype(&cnt[c]) = LUA_T_NUMBER;
nvalue(&cnt[c]) = r;
return c;
}
static void code_number (real f)
{
int i;
if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(int)f) == f)
code_oparg(PUSHNUMBER, 3, i, 1); /* f has an (short) integer value */
else
code_constant(real_constant(f));
}
static void flush_record (int n)
{
if (n > 0)
code_oparg(SETMAP, 1, n-1, -2*n);
}
static void flush_list (int m, int n)
{
if (n == 0) return;
code_oparg(SETLIST, 1, m, -n);
code_byte(n);
}
static void luaI_registerlocalvar (TaggedString *varname, int line)
{
FuncState *fs = L->currState;
if (fs->maxvars != -1) { /* debug information? */
if (fs->nvars >= fs->maxvars)
fs->maxvars = luaM_growvector(&fs->f->locvars, fs->maxvars,
LocVar, "", MAX_WORD);
fs->f->locvars[fs->nvars].varname = varname;
fs->f->locvars[fs->nvars].line = line;
fs->nvars++;
}
}
static void luaI_unregisterlocalvar (int line)
{
luaI_registerlocalvar(NULL, line);
}
static void store_localvar (TaggedString *name, int n)
{
if (L->currState->nlocalvar+n < MAXLOCALS)
L->currState->localvar[L->currState->nlocalvar+n] = name;
else
luaY_error("too many local variables " MES_LIM(SMAXLOCALS));
luaI_registerlocalvar(name, L->lexstate->linenumber);
}
static void add_localvar (TaggedString *name)
{
store_localvar(name, 0);
L->currState->nlocalvar++;
}
/*
** dotted variables <a.x> must be stored like regular indexed vars <a["x"]>
*/
static vardesc var2store (vardesc var)
{
if (isdot(var)) {
code_constant(dotindex(var));
var = 0;
}
return var;
}
static void add_varbuffer (vardesc var, int n)
{
if (n >= MAXVAR)
luaY_error("variable buffer overflow " MES_LIM(SMAXVAR));
L->currState->varbuffer[n] = var2store(var);
}
static int aux_localname (TaggedString *n, FuncState *st)
{
int i;
for (i=st->nlocalvar-1; i >= 0; i--)
if (n == st->localvar[i]) return i; /* local var index */
return -1; /* not found */
}
static vardesc singlevar (TaggedString *n, FuncState *st)
{
int i = aux_localname(n, st);
if (i == -1) { /* check shadowing */
int l;
for (l=1; l<=(st-L->mainState); l++)
if (aux_localname(n, st-l) >= 0)
luaY_syntaxerror("cannot access a variable in outer scope", n->str);
return string_constant(n, st)+MINGLOBAL; /* global value */
}
else return i+1; /* local value */
}
static int indexupvalue (TaggedString *n)
{
vardesc v = singlevar(n, L->currState-1);
int i;
for (i=0; i<L->currState->nupvalues; i++) {
if (L->currState->upvalues[i] == v)
return i;
}
/* new one */
if (++(L->currState->nupvalues) > MAXUPVALUES)
luaY_error("too many upvalues in a single function " MES_LIM(SMAXUPVALUES));
L->currState->upvalues[i] = v; /* i = L->currState->nupvalues - 1 */
return i;
}
static void pushupvalue (TaggedString *n)
{
int i;
if (L->currState == L->mainState)
luaY_error("cannot access upvalue in main");
if (aux_localname(n, L->currState) >= 0)
luaY_syntaxerror("cannot access an upvalue in current scope", n->str);
i = indexupvalue(n);
code_oparg(PUSHUPVALUE, 2, i, 1);
}
void luaY_codedebugline (int line)
{
if (lua_debug && line != L->lexstate->lastline) {
code_oparg(SETLINE, 0, line, 0);
L->lexstate->lastline = line;
}
}
static void adjuststack (int n)
{
if (n > 0)
code_oparg(POP, 2, n-1, -n);
else if (n < 0)
code_oparg(PUSHNIL, 1, (-n)-1, -n);
}
static long adjust_functioncall (long exp, int nresults)
{
if (exp <= 0)
return -exp; /* exp is -list length */
else {
int temp = L->currState->f->code[exp];
int nparams = L->currState->f->code[exp-1];
exp += fix_opcode(exp-2, CALLFUNC, 2, nresults);
L->currState->f->code[exp] = nparams;
if (nresults != MULT_RET)
deltastack(nresults);
deltastack(-(nparams+1));
return temp+nresults;
}
}
static void adjust_mult_assign (int vars, long exps)
{
if (exps > 0) { /* must correct function call */
int diff = L->currState->f->code[exps] - vars;
if (diff < 0)
adjust_functioncall(exps, -diff);
else {
adjust_functioncall(exps, 0);
adjuststack(diff);
}
}
else adjuststack((-exps)-vars);
}
static void code_args (int nparams, int dots)
{
L->currState->nlocalvar += nparams; /* "self" may already be there */
nparams = L->currState->nlocalvar;
if (!dots) {
L->currState->f->code[1] = nparams; /* fill-in arg information */
deltastack(nparams);
}
else {
L->currState->f->code[1] = nparams+ZEROVARARG;
deltastack(nparams+1);
add_localvar(luaS_new("arg"));
}
}
static void lua_pushvar (vardesc var)
{
if (isglobal(var))
code_oparg(GETGLOBAL, 8, globalindex(var), 1);
else if (islocal(var))
code_oparg(PUSHLOCAL, 8, localindex(var), 1);
else if (isdot(var))
code_oparg(GETDOTTED, 8, dotindex(var), 0);
else
code_pop(GETTABLE);
}
static void storevar (vardesc var)
{
if (var == 0) /* indexed var */
code_opcode(SETTABLE0, -3);
else if (isglobal(var))
code_oparg(SETGLOBAL, 8, globalindex(var), -1);
else /* local var */
code_oparg(SETLOCAL, 8, localindex(var), -1);
}
/* returns how many elements are left as 'garbage' on the stack */
static int lua_codestore (int i, int left)
{
if (L->currState->varbuffer[i] != 0 || /* global or local var or */
left+i == 0) { /* indexed var without values in between */
storevar(L->currState->varbuffer[i]);
return left;
}
else { /* indexed var with values in between*/
code_oparg(SETTABLE, 0, left+i, -1);
return left+2; /* table/index are not popped, since they are not on top */
}
}
static int fix_jump (int pc, OpCode op, int n)
{
/* jump is relative to position following jump instruction */
return fix_opcode(pc, op, 0, n-(pc+JMPSIZE));
}
static void fix_upjmp (OpCode op, int pos)
{
int delta = L->currState->pc+JMPSIZE - pos; /* jump is relative */
if (delta > 255) delta++;
code_oparg(op, 0, delta, 0);
}
static void codeIf (int thenAdd, int elseAdd)
{
int elseinit = elseAdd+JMPSIZE;
if (L->currState->pc == elseinit) { /* no else part */
L->currState->pc -= JMPSIZE;
elseinit = L->currState->pc;
}
else
elseinit += fix_jump(elseAdd, JMP, L->currState->pc);
fix_jump(thenAdd, IFFJMP, elseinit);
}
static void code_shortcircuit (int pc, OpCode op)
{
fix_jump(pc, op, L->currState->pc);
}
static void codereturn (void)
{
code_oparg(RETCODE, 0, L->currState->nlocalvar, 0);
L->currState->stacksize = L->currState->nlocalvar;
}
static void func_onstack (TProtoFunc *f)
{
int i;
int nupvalues = (L->currState+1)->nupvalues;
int c = next_constant(L->currState);
ttype(&L->currState->f->consts[c]) = LUA_T_PROTO;
L->currState->f->consts[c].value.tf = (L->currState+1)->f;
if (nupvalues == 0)
code_constant(c);
else {
for (i=0; i<nupvalues; i++)
lua_pushvar((L->currState+1)->upvalues[i]);
code_constant(c);
code_oparg(CLOSURE, 2, nupvalues, -nupvalues);
}
}
static void init_state (TaggedString *filename)
{
TProtoFunc *f = luaF_newproto();
FuncState *fs = L->currState;
fs->stacksize = 0;
fs->maxstacksize = 0;
fs->nlocalvar = 0;
fs->nupvalues = 0;
fs->f = f;
f->fileName = filename;
fs->pc = 0;
fs->maxcode = 0;
f->code = NULL;
fs->maxconsts = 0;
if (lua_debug) {
fs->nvars = 0;
fs->maxvars = 0;
}
else
fs->maxvars = -1; /* flag no debug information */
code_byte(0); /* to be filled with stacksize */
code_byte(0); /* to be filled with arg information */
L->lexstate->lastline = 0; /* invalidate it */
}
static void init_func (void)
{
if (L->currState-L->mainState >= MAXSTATES-1)
luaY_error("too many nested functions " MES_LIM(SMAXSTATES));
L->currState++;
init_state(L->mainState->f->fileName);
luaY_codedebugline(L->lexstate->linenumber);
L->currState->f->lineDefined = L->lexstate->linenumber;
}
static TProtoFunc *close_func (void)
{
TProtoFunc *f = L->currState->f;
code_neutralop(ENDCODE);
f->code[0] = L->currState->maxstacksize;
f->code = luaM_reallocvector(f->code, L->currState->pc, Byte);
f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject);
if (L->currState->maxvars != -1) { /* debug information? */
luaI_registerlocalvar(NULL, -1); /* flag end of vector */
f->locvars = luaM_reallocvector(f->locvars, L->currState->nvars, LocVar);
}
L->currState--;
return f;
}
/*
** Parse Lua code.
*/
TProtoFunc *luaY_parser (ZIO *z)
{
struct LexState lexstate;
FuncState state[MAXSTATES];
L->currState = L->mainState = &state[0];
L->lexstate = &lexstate;
luaX_setinput(z);
init_state(luaS_new(zname(z)));
if (luaY_parse()) lua_error("parse error");
return close_func();
}
%}
%union
{
int vInt;
real vReal;
char *pChar;
long vLong;
TaggedString *pTStr;
TProtoFunc *pFunc;
}
%start chunk
%token WRONGTOKEN
%token NIL
%token IF THEN ELSE ELSEIF WHILE DO REPEAT UNTIL END
%token RETURN
%token LOCAL
%token FUNCTION
%token DOTS
%token <vReal> NUMBER
%token <pTStr> NAME STRING
%type <vInt> SaveWord, cond, GetPC, SaveWordPop, SaveWordPush
%type <vLong> exprlist, exprlist1 /* if > 0, points to function return
counter (which has list length); if <= 0, -list lenght */
%type <vLong> functioncall, expr, sexp /* if != 0, points to function return
counter */
%type <vInt> varlist1, funcParams, funcvalue
%type <vInt> fieldlist, localnamelist, decinit
%type <vInt> ffieldlist1, lfieldlist1, ffieldlist, lfieldlist, part
%type <vLong> var, varname, funcname /* vardesc */
%left AND OR
%left EQ NE '>' '<' LE GE
%left CONC
%left '+' '-'
%left '*' '/'
%left UNARY NOT
%right '^'
%% /* beginning of rules section */
chunk : statlist ret ;
statlist : /* empty */
| statlist stat sc
;
sc : /* empty */ | ';' ;
stat : IF cond THEN block SaveWord elsepart END { codeIf($2, $5); }
| DO block END
| WHILE GetPC cond DO block END
{{
FuncState *fs = L->currState;
int expsize = $3-$2;
int newpos = $2+JMPSIZE;
check_pc(expsize);
memcpy(fs->f->code+fs->pc, fs->f->code+$2, expsize);
luaO_memdown(fs->f->code+$2, fs->f->code+$3, fs->pc-$2);
newpos += fix_jump($2, JMP, fs->pc-expsize);
fix_upjmp(IFTUPJMP, newpos);
}}
| REPEAT GetPC block UNTIL expr1
{
fix_upjmp(IFFUPJMP, $2);
deltastack(-1); /* pops condition */
}
| varlist1 '=' exprlist1
{{
int i;
int left = 0;
adjust_mult_assign($1, $3);
for (i=$1-1; i>=0; i--)
left = lua_codestore(i, left);
adjuststack(left); /* remove eventual 'garbage' left on stack */
}}
| functioncall { adjust_functioncall($1, 0); }
| LOCAL localnamelist decinit
{
L->currState->nlocalvar += $2;
adjust_mult_assign($2, $3);
}
| FUNCTION funcname body { storevar($2); }
;
block : {$<vInt>$ = L->currState->nlocalvar;} chunk
{
adjuststack(L->currState->nlocalvar - $<vInt>1);
for (; L->currState->nlocalvar > $<vInt>1; L->currState->nlocalvar--)
luaI_unregisterlocalvar(L->lexstate->linenumber);
}
;
funcname : varname { $$ = $1; init_func(); }
| fvarname '.' fname
{
$$ = 0; /* flag indexed variable */
init_func();
}
| fvarname ':' fname
{
$$ = 0; /* flag indexed variable */
init_func();
add_localvar(luaS_new("self"));
}
;
fvarname : varname { lua_pushvar($1); } ;
fname : NAME { code_string($1); } ;
body : '(' parlist ')' chunk END { func_onstack(close_func()); } ;
elsepart : /* empty */
| ELSE block
| ELSEIF cond THEN block SaveWord elsepart { codeIf($2, $5); }
;
ret : /* empty */
| RETURN exprlist sc
{
adjust_functioncall($2, MULT_RET);
codereturn();
}
;
GetPC : /* empty */ { $$ = L->currState->pc; } ;
SaveWord : /* empty */
{ $$ = L->currState->pc;
check_pc(JMPSIZE);
L->currState->pc += JMPSIZE; /* open space */
}
;
SaveWordPop : SaveWord { $$ = $1; deltastack(-1); /* pop condition */ } ;
SaveWordPush : SaveWord { $$ = $1; deltastack(1); /* push a value */ } ;
cond : expr1 SaveWordPop { $$ = $2; } ;
expr1 : expr { adjust_functioncall($1, 1); } ;
expr : '(' expr ')' { $$ = $2; }
| expr1 EQ expr1 { code_binop(EQOP); $$ = 0; }
| expr1 '<' expr1 { code_binop(LTOP); $$ = 0; }
| expr1 '>' expr1 { code_binop(GTOP); $$ = 0; }
| expr1 NE expr1 { code_binop(NEQOP); $$ = 0; }
| expr1 LE expr1 { code_binop(LEOP); $$ = 0; }
| expr1 GE expr1 { code_binop(GEOP); $$ = 0; }
| expr1 '+' expr1 { code_binop(ADDOP); $$ = 0; }
| expr1 '-' expr1 { code_binop(SUBOP); $$ = 0; }
| expr1 '*' expr1 { code_binop(MULTOP); $$ = 0; }
| expr1 '/' expr1 { code_binop(DIVOP); $$ = 0; }
| expr1 '^' expr1 { code_binop(POWOP); $$ = 0; }
| expr1 CONC expr1 { code_binop(CONCOP); $$ = 0; }
| '-' expr1 %prec UNARY { code_unop(MINUSOP); $$ = 0;}
| NOT expr1 { code_unop(NOTOP); $$ = 0;}
| sexp { $$ = $1; /* simple expressions */ }
| table { $$ = 0; }
| NUMBER { code_number($1); $$ = 0; }
| STRING { code_string($1); $$ = 0; }
| NIL { adjuststack(-1); $$ = 0; }
| FUNCTION { init_func(); } body { $$ = 0; }
| expr1 AND SaveWordPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; }
| expr1 OR SaveWordPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; }
;
sexp1 : sexp { adjust_functioncall($1, 1); } ;
sexp : var { lua_pushvar($1); $$ = 0; }
| '%' NAME { pushupvalue($2); $$ = 0; }
| functioncall { $$ = $1; }
;
var : varname { $$ = $1; }
| sexp1 '[' expr1 ']' { $$ = 0; } /* indexed variable */
| sexp1 '.' NAME { $$ = (-string_constant($3, L->currState))-1; }
;
varname : NAME { $$ = singlevar($1, L->currState); } ;
table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAY, 2, $3); } ;
functioncall : funcvalue funcParams
{
code_byte(0); /* save space for opcode */
code_byte($1+$2); /* number of parameters */
$$ = L->currState->pc;
code_byte(0); /* must be adjusted by other rules */
}
;
funcvalue : sexp1 { $$ = 0; }
| sexp1 ':' NAME
{
code_oparg(PUSHSELF, 8, string_constant($3, L->currState), 1);
$$ = 1;
}
;
funcParams : '(' exprlist ')' { $$ = adjust_functioncall($2, 1); }
| table { $$ = 1; }
| STRING { code_string($1); $$ = 1; }
;
exprlist : /* empty */ { $$ = 0; }
| exprlist1 { $$ = $1; }
;
exprlist1 : expr { if ($1 != 0) $$ = $1; else $$ = -1; }
| exprlist1 ',' { $<vLong>$ = adjust_functioncall($1, 1); } expr
{
if ($4 == 0) $$ = -($<vLong>3 + 1); /* -length */
else {
L->currState->f->code[$4] = $<vLong>3; /* store list length */
$$ = $4;
}
}
;
parlist : /* empty */ { code_args(0, 0); }
| DOTS { code_args(0, 1); }
| localnamelist { code_args($1, 0); }
| localnamelist ',' DOTS { code_args($1, 1); }
;
fieldlist : part { $$ = abs($1); }
| part ';' part
{
if ($1*$3 > 0) /* repeated parts? */
luaY_error("invalid constructor syntax");
$$ = abs($1)+abs($3);
}
;
part : /* empty */ { $$ = 0; }
| ffieldlist { $$ = $1; }
| lfieldlist { $$ = $1; }
;
lastcomma : /* empty */ | ',' ;
ffieldlist : ffieldlist1 lastcomma
{
flush_record($1%RFIELDS_PER_FLUSH);
$$ = -$1; /* negative signals a "record" part */
}
;
lfieldlist : lfieldlist1 lastcomma
{
flush_list($1/LFIELDS_PER_FLUSH, $1%LFIELDS_PER_FLUSH);
$$ = $1;
}
;
ffieldlist1 : ffield {$$=1;}
| ffieldlist1 ',' ffield
{
$$=$1+1;
if ($$%RFIELDS_PER_FLUSH == 0)
flush_record(RFIELDS_PER_FLUSH);
}
;
ffield : ffieldkey '=' expr1 ;
ffieldkey : '[' expr1 ']'
| fname
;
lfieldlist1 : expr1 {$$=1;}
| lfieldlist1 ',' expr1
{
$$=$1+1;
if ($$%LFIELDS_PER_FLUSH == 0)
flush_list($$/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
}
;
varlist1 : var { $$ = 1; add_varbuffer($1, 0); }
| varlist1 ',' var { add_varbuffer($3, $1); $$ = $1+1; }
;
localnamelist : NAME {store_localvar($1, 0); $$ = 1;}
| localnamelist ',' NAME { store_localvar($3, $1); $$ = $1+1; }
;
decinit : /* empty */ { $$ = 0; }
| '=' exprlist1 { $$ = $2; }
;
%%

View File

@@ -1,6 +1,6 @@
/*
** $Id: $
** Debuging API
** $Id: luadebug.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
** Debugging API
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lualib.h,v 1.2 1997/11/26 18:53:45 roberto Exp roberto $
** $Id: lualib.h,v 1.3 1997/12/17 20:48:58 roberto Exp roberto $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -26,7 +26,7 @@ void lua_mathlibopen (void);
/* auxiliar functions (private) */
/* Auxiliary functions (private) */
int luaI_singlematch (int c, char *p, char **ep);

254
lundump.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lundump.c,v 1.4 1998/01/13 20:05:24 lhf Exp $
** $Id: lundump.c,v 1.10 1998/06/25 15:50:09 lhf Exp $
** load bytecodes from files
** See Copyright Notice in lua.h
*/
@@ -11,15 +11,18 @@
#include "lstring.h"
#include "lundump.h"
typedef struct {
ZIO* Z;
int SwapNumber;
int LoadFloat;
} Sundump;
#define LoadBlock(b,size,Z) ezread(Z,b,size)
#define LoadNative(t,Z) LoadBlock(&t,sizeof(t),Z)
#if ID_NUMBER==ID_NATIVE
#define doLoadNumber(f,Z) LoadNative(f,Z)
#else
#define doLoadNumber(f,Z) f=LoadNumber(Z)
#endif
static void unexpectedEOZ(ZIO* Z)
{
luaL_verror("unexpected end of binary file %s",Z->name);
luaL_verror("unexpected end of file in %s",zname(Z));
}
static int ezgetc(ZIO* Z)
@@ -29,91 +32,81 @@ static int ezgetc(ZIO* Z)
return c;
}
static int ezread(ZIO* Z, void* b, int n)
static void ezread(ZIO* Z, void* b, int n)
{
int r=zread(Z,b,n);
if (r!=0) unexpectedEOZ(Z);
return r;
}
static int LoadWord(ZIO* Z)
static unsigned int LoadWord(ZIO* Z)
{
int hi=ezgetc(Z);
int lo=ezgetc(Z);
unsigned int hi=ezgetc(Z);
unsigned int lo=ezgetc(Z);
return (hi<<8)|lo;
}
static void* LoadBlock(int size, ZIO* Z)
static unsigned long LoadLong(ZIO* Z)
{
void* b=luaM_malloc(size);
ezread(Z,b,size);
unsigned long hi=LoadWord(Z);
unsigned long lo=LoadWord(Z);
return (hi<<16)|lo;
}
#if ID_NUMBER==ID_REAL4
/* LUA_NUMBER */
/* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */
static float LoadFloat(ZIO* Z)
{
unsigned long l=LoadLong(Z);
float f=*(float*)&l;
return f;
}
#endif
#if ID_NUMBER==ID_REAL8
/* LUA_NUMBER */
/* assumes sizeof(long)==4 and sizeof(double)==8 (IEEE) */
static double LoadDouble(ZIO* Z)
{
unsigned long l[2];
double f;
int x=1;
if (*(char*)&x==1) /* little-endian */
{
l[1]=LoadLong(Z);
l[0]=LoadLong(Z);
}
else /* big-endian */
{
l[0]=LoadLong(Z);
l[1]=LoadLong(Z);
}
f=*(double*)l;
return f;
}
#endif
static Byte* LoadCode(ZIO* Z)
{
unsigned long size=LoadLong(Z);
unsigned int s=size;
void* b;
if (s!=size) luaL_verror("code too long (%ld bytes) in %s",size,zname(Z));
b=luaM_malloc(size);
LoadBlock(b,size,Z);
return b;
}
static int LoadSize(ZIO* Z)
{
int hi=LoadWord(Z);
int lo=LoadWord(Z);
int s=(hi<<16)|lo;
if (hi!=0 && s==lo)
luaL_verror("code too long (%ld bytes)",(hi<<16)|(long)lo);
return s;
}
static char* LoadString(ZIO* Z)
static TaggedString* LoadTString(ZIO* Z)
{
int size=LoadWord(Z);
if (size==0)
return NULL;
else
{
char* b=luaL_openspace(size);
ezread(Z,b,size);
return b;
}
}
static TaggedString* LoadTString(ZIO* Z)
{
char* s=LoadString(Z);
return (s==NULL) ? NULL : luaS_new(s);
}
static void SwapFloat(float* f)
{
Byte* p=(Byte*)f;
Byte* q=p+sizeof(float)-1;
Byte t;
t=*p; *p++=*q; *q--=t;
t=*p; *p++=*q; *q--=t;
}
static void SwapDouble(double* f)
{
Byte* p=(Byte*)f;
Byte* q=p+sizeof(double)-1;
Byte t;
t=*p; *p++=*q; *q--=t;
t=*p; *p++=*q; *q--=t;
t=*p; *p++=*q; *q--=t;
t=*p; *p++=*q; *q--=t;
}
static real LoadNumber(Sundump* S)
{
if (S->LoadFloat)
{
float f;
ezread(S->Z,&f,sizeof(f));
if (S->SwapNumber) SwapFloat(&f);
return f;
}
else
{
double f;
ezread(S->Z,&f,sizeof(f));
if (S->SwapNumber) SwapDouble(&f);
return f;
char* s=luaL_openspace(size);
LoadBlock(s,size,Z);
return luaS_newlstr(s,size-1);
}
}
@@ -131,63 +124,47 @@ static void LoadLocals(TProtoFunc* tf, ZIO* Z)
tf->locvars[i].varname=NULL;
}
static void LoadConstants(TProtoFunc* tf, Sundump* S)
static TProtoFunc* LoadFunction(ZIO* Z);
static void LoadConstants(TProtoFunc* tf, ZIO* Z)
{
int i,n=LoadWord(S->Z);
int i,n=LoadWord(Z);
tf->nconsts=n;
if (n==0) return;
tf->consts=luaM_newvector(n,TObject);
for (i=0; i<n; i++)
{
TObject* o=tf->consts+i;
int c=ezgetc(S->Z);
int c=ezgetc(Z);
switch (c)
{
case ID_NUM:
ttype(o)=LUA_T_NUMBER;
nvalue(o)=LoadNumber(S);
doLoadNumber(nvalue(o),Z);
break;
case ID_STR:
ttype(o)=LUA_T_STRING;
tsvalue(o)=LoadTString(S->Z);
tsvalue(o)=LoadTString(Z);
break;
case ID_FUN:
ttype(o)=LUA_T_PROTO;
tfvalue(o)=NULL;
tfvalue(o)=LoadFunction(Z);
break;
#ifdef DEBUG
default: /* cannot happen */
luaL_verror("internal error in LoadConstants: "
"bad constant #%d type=%d ('%c')\n",i,c,c);
default:
luaL_verror("bad constant #%d in %s: type=%d ('%c')",i,zname(Z),c,c);
break;
#endif
}
}
}
static TProtoFunc* LoadFunction(Sundump* S);
static void LoadFunctions(TProtoFunc* tf, Sundump* S)
static TProtoFunc* LoadFunction(ZIO* Z)
{
while (zgetc(S->Z)==ID_FUNCTION)
{
int i=LoadWord(S->Z);
TProtoFunc* t=LoadFunction(S);
TObject* o=tf->consts+i;
tfvalue(o)=t;
}
}
static TProtoFunc* LoadFunction(Sundump* S)
{
ZIO* Z=S->Z;
TProtoFunc* tf=luaF_newproto();
tf->lineDefined=LoadWord(Z);
tf->fileName=LoadTString(Z);
tf->code=LoadBlock(LoadSize(Z),Z);
LoadConstants(tf,S);
tf->code=LoadCode(Z);
LoadLocals(tf,Z);
LoadFunctions(tf,S);
LoadConstants(tf,Z);
return tf;
}
@@ -196,61 +173,42 @@ static void LoadSignature(ZIO* Z)
char* s=SIGNATURE;
while (*s!=0 && ezgetc(Z)==*s)
++s;
if (*s!=0) luaL_verror("bad signature in binary file %s",Z->name);
if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
}
static void LoadHeader(Sundump* S)
static void LoadHeader(ZIO* Z)
{
ZIO* Z=S->Z;
int version,sizeofR;
int version,id,sizeofR;
real f=-TEST_NUMBER,tf=TEST_NUMBER;
LoadSignature(Z);
version=ezgetc(Z);
if (version>VERSION)
luaL_verror(
"binary file %s too new: version=0x%02x; expected at most 0x%02x",
Z->name,version,VERSION);
if (version<0x31) /* major change in 3.1 */
"%s too new: version=0x%02x; expected at most 0x%02x",
zname(Z),version,VERSION);
if (version<VERSION0) /* check last major change */
luaL_verror(
"binary file %s too old: version=0x%02x; expected at least 0x%02x",
Z->name,version,0x31);
sizeofR=ezgetc(Z); /* test float representation */
if (sizeofR==sizeof(float))
"%s too old: version=0x%02x; expected at least 0x%02x",
zname(Z),version,VERSION0);
id=ezgetc(Z); /* test number representation */
sizeofR=ezgetc(Z);
if (id!=ID_NUMBER || sizeofR!=sizeof(real))
{
float f,tf=TEST_FLOAT;
ezread(Z,&f,sizeof(f));
if (f!=tf)
{
SwapFloat(&f);
if (f!=tf)
luaL_verror("unknown float representation in binary file %s",Z->name);
S->SwapNumber=1;
}
S->LoadFloat=1;
luaL_verror("unknown number signature in %s: "
"read 0x%02x%02x; expected 0x%02x%02x",
zname(Z),id,sizeofR,ID_NUMBER,sizeof(real));
}
else if (sizeofR==sizeof(double))
{
double f,tf=TEST_FLOAT;
ezread(Z,&f,sizeof(f));
if (f!=tf)
{
SwapDouble(&f);
if (f!=tf)
luaL_verror("unknown float representation in binary file %s",Z->name);
S->SwapNumber=1;
}
S->LoadFloat=0;
}
else
luaL_verror(
"floats in binary file %s have %d bytes; "
"expected %d (float) or %d (double)",
Z->name,sizeofR,sizeof(float),sizeof(double));
doLoadNumber(f,Z);
if (f!=tf)
luaL_verror("unknown number representation in %s: "
"read " NUMBER_FMT "; expected " NUMBER_FMT "", /* LUA_NUMBER */
zname(Z),(double)f,(double)tf);
}
static TProtoFunc* LoadChunk(Sundump* S)
static TProtoFunc* LoadChunk(ZIO* Z)
{
LoadHeader(S);
return LoadFunction(S);
LoadHeader(Z);
return LoadFunction(Z);
}
/*
@@ -260,13 +218,9 @@ static TProtoFunc* LoadChunk(Sundump* S)
TProtoFunc* luaU_undump1(ZIO* Z)
{
int c=zgetc(Z);
Sundump S;
S.Z=Z;
S.SwapNumber=0;
S.LoadFloat=1;
if (c==ID_CHUNK)
return LoadChunk(&S);
return LoadChunk(Z);
else if (c!=EOZ)
luaL_verror("%s is not a lua binary file",Z->name);
luaL_verror("%s is not a Lua binary file",zname(Z));
return NULL;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lundump.h,v 1.4 1998/01/13 20:05:24 lhf Exp $
** $Id: lundump.h,v 1.7 1998/06/25 15:50:09 lhf Exp $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -10,18 +10,72 @@
#include "lobject.h"
#include "lzio.h"
#define ID_CHUNK 27 /* ESC */
#define ID_FUNCTION '#'
#define ID_END '$'
#define ID_NUM 'N'
#define ID_STR 'S'
#define ID_FUN 'F'
TProtoFunc* luaU_undump1(ZIO* Z); /* load one chunk */
#define SIGNATURE "Lua"
#define VERSION 0x31 /* last format change was in 3.1 */
#define TEST_FLOAT 0.123456789e-23 /* a float for testing representation */
#define VERSION0 0x31 /* last major change was in 3.1 */
#define IsMain(f) (f->lineDefined==0)
TProtoFunc* luaU_undump1(ZIO* Z); /* load one chunk */
#define ID_CHUNK 27 /* ESC */
#define ID_NUM 'N'
#define ID_STR 'S'
#define ID_FUN 'F'
/* number representation */
#define ID_INT4 'l' /* 4-byte integers */
#define ID_REAL4 'f' /* 4-byte reals */
#define ID_REAL8 'd' /* 8-byte reals */
#define ID_NATIVE '?' /* whatever your machine uses */
/*
* use a multiple of PI for testing number representation.
* multiplying by 1E8 gives notrivial integer values.
*/
#define TEST_NUMBER 3.14159265358979323846E8
/* LUA_NUMBER
* choose one below for the number representation in precompiled chunks.
* the default is ID_REAL8 because the default for LUA_NUM_TYPE is double.
* if your machine does not use IEEE 754, use ID_NATIVE.
* the next version will support conversion to/from IEEE 754.
*
* if you change LUA_NUM_TYPE, make sure you set ID_NUMBER accordingly,
* specially if sizeof(long)!=4.
* for types other than the ones listed below, you'll have to write your own
* dump and undump routines.
*/
#ifndef ID_NUMBER
#define ID_NUMBER ID_NATIVE
#endif
#if 0
#define ID_NUMBER ID_INT4
#define ID_NUMBER ID_REAL4
#define ID_NUMBER ID_REAL8
#define ID_NUMBER ID_NATIVE
#endif
#endif
#if ID_NUMBER==ID_REAL4
#define DumpNumber DumpFloat
#define LoadNumber LoadFloat
#define SIZEOF_NUMBER 4
#elif ID_NUMBER==ID_REAL8
#define DumpNumber DumpDouble
#define LoadNumber LoadDouble
#define SIZEOF_NUMBER 8
#elif ID_NUMBER==ID_INT4
#define DumpNumber DumpLong
#define LoadNumber LoadLong
#define SIZEOF_NUMBER 4
#elif ID_NUMBER==ID_NATIVE
#define DumpNumber DumpNative
#define LoadNumber LoadNative
#define SIZEOF_NUMBER sizeof(real)
#else
#error bad ID_NUMBER
#endif

66
lvm.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 1.22 1998/01/12 13:35:37 roberto Exp roberto $
** $Id: lvm.c,v 1.29 1998/05/31 22:18:24 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -28,7 +28,7 @@
#define skip_word(pc) (pc+=2)
#define get_word(pc) (*(pc)+(*((pc)+1)<<8))
#define get_word(pc) ((*(pc)<<8)+(*((pc)+1)))
#define next_word(pc) (pc+=2, get_word(pc-2))
@@ -37,13 +37,14 @@
static TaggedString *strconc (char *l, char *r)
static TaggedString *strconc (TaggedString *l, TaggedString *r)
{
size_t nl = strlen(l);
char *buffer = luaL_openspace(nl+strlen(r)+1);
strcpy(buffer, l);
strcpy(buffer+nl, r);
return luaS_new(buffer);
size_t nl = l->u.s.len;
size_t nr = r->u.s.len;
char *buffer = luaL_openspace(nl+nr+1);
memcpy(buffer, l->str, nl);
memcpy(buffer+nl, r->str, nr);
return luaS_newlstr(buffer, nl+nr);
}
@@ -74,7 +75,7 @@ int luaV_tostring (TObject *obj)
if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i=(int)f) == f)
sprintf (s, "%d", i);
else
sprintf (s, "%g", (double)nvalue(obj));
sprintf (s, NUMBER_FMT, nvalue(obj));
tsvalue(obj) = luaS_new(s);
ttype(obj) = LUA_T_STRING;
return 0;
@@ -135,9 +136,9 @@ void luaV_gettable (void)
/*
** Function to store indexed based on values at the stack.top
** mode = 0: raw store (without internal methods)
** mode = 1: normal store (with internal methods)
** mode = 2: "deep L->stack.stack" store (with internal methods)
** mode = 0: raw store (without tag methods)
** mode = 1: normal store (with tag methods)
** mode = 2: "deep L->stack.stack" store (with tag methods)
*/
void luaV_settable (TObject *t, int mode)
{
@@ -167,7 +168,7 @@ void luaV_settable (TObject *t, int mode)
void luaV_getglobal (TaggedString *ts)
{
/* WARNING: caller must assure stack space */
TObject *value = &ts->u.globalval;
TObject *value = &ts->u.s.globalval;
TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
if (ttype(im) == LUA_T_NIL) { /* default behavior */
*L->stack.top++ = *value;
@@ -185,7 +186,7 @@ void luaV_getglobal (TaggedString *ts)
void luaV_setglobal (TaggedString *ts)
{
TObject *oldvalue = &ts->u.globalval;
TObject *oldvalue = &ts->u.s.globalval;
TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
if (ttype(im) == LUA_T_NIL) /* default behavior */
luaS_rawsetglobal(ts, --L->stack.top);
@@ -224,6 +225,23 @@ static void call_arith (IMS event)
}
static int strcomp (char *l, long ll, char *r, long lr)
{
for (;;) {
long temp = strcoll(l, r);
if (temp != 0) return temp;
/* strings are equal up to a '\0' */
temp = strlen(l); /* index of first '\0' in both strings */
if (temp == ll) /* l is finished? */
return (temp == lr) ? 0 : -1; /* l is equal or smaller than r */
else if (temp == lr) /* r is finished? */
return 1; /* l is greater than r (because l is not finished) */
/* both strings longer than temp; go on comparing (after the '\0') */
temp++;
l += temp; ll -= temp; r += temp; lr -= temp;
}
}
static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
lua_Type ttype_great, IMS op)
{
@@ -234,7 +252,8 @@ static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1;
else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
result = strcoll(svalue(l), svalue(r));
result = strcomp(svalue(l), tsvalue(l)->u.s.len,
svalue(r), tsvalue(r)->u.s.len);
else {
call_binTM(op, "unexpected type in comparison");
return;
@@ -573,7 +592,7 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
}
case POWOP:
call_arith(IM_POW);
call_binTM(IM_POW, "undefined operation");
break;
case CONCOP: {
@@ -582,7 +601,7 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
if (tostring(l) || tostring(r))
call_binTM(IM_CONCAT, "unexpected type for concatenation");
else {
tsvalue(l) = strconc(svalue(l), svalue(r));
tsvalue(l) = strconc(tsvalue(l), tsvalue(r));
--S->top;
}
luaC_checkGC();
@@ -661,13 +680,14 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
break;
case CLOSURE:
aux = *pc++; goto closure;
case CLOSUREW:
aux = next_word(pc); goto closure;
case CLOSURE0: case CLOSURE1:
aux -= CLOSURE0;
case CLOSURE:
aux = *pc++;
closure:
luaV_closure(aux);
*S->top++ = consts[aux];
luaV_closure(*pc++);
luaC_checkGC();
break;
@@ -709,7 +729,7 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
#ifdef DEBUG
default:
lua_error("internal error - opcode doesn't match");
LUA_INTERNALERROR("opcode doesn't match");
#endif
}
}

View File

@@ -1,5 +1,5 @@
#
## $Id: makefile,v 1.9 1998/01/02 17:46:32 roberto Exp roberto $
## $Id: makefile,v 1.12 1998/05/27 13:03:40 roberto Exp roberto $
## Makefile
## See Copyright Notice in lua.h
#
@@ -17,6 +17,8 @@
#
# define LUA_COMPAT2_5 if yous system does need to be compatible with
# version 2.5 (or older)
#
# define LUA_NUM_TYPE if you need numbers to be different from double
CONFIG = -DPOPEN -D_POSIX_SOURCE
#CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG
@@ -44,8 +46,8 @@ LUAOBJS = \
llex.o \
lmem.o \
lobject.o \
lparser.o \
lstate.o \
lstx.o \
lstring.o \
ltable.o \
ltm.o \
@@ -73,16 +75,11 @@ liblualib.a : $(LIBOBJS)
liblua.so.1.0 : lua.o
ld -o liblua.so.1.0 $(LUAOBJS)
lstx.c lstx.h : lua.stx
bison -o lstx.c -p luaY_ -d lua.stx
# yacc -d lua.stx
# sed -e 's/yy/luaY_/g' -e 's/malloc\.h/stdlib\.h/g' y.tab.c > lstx.c
# sed -e 's/yy/luaY_/g' y.tab.h > lstx.h
clear :
rcsclean
rm -f *.o
rm -f lstx.c lstx.h
rm -f
co lua.h lualib.h luadebug.h
@@ -92,12 +89,14 @@ clear :
%.c : RCS/%.c,v
co $@
lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h lfunc.h \
lgc.h lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.h
lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h
lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \
ldo.h lstate.h lfunc.h lmem.h lstring.h ltable.h ltm.h
ldo.h lstate.h lfunc.h lmem.h lstring.h ltable.h ltm.h lundump.h \
lzio.h
ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \
lparser.h lzio.h ltm.h luadebug.h lundump.h lvm.h
lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h
@@ -105,18 +104,18 @@ lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \
lstring.h ltable.h ltm.h
liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h
llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \
lparser.h lstate.h lstring.h lstx.h luadebug.h
lparser.h lstate.h lstring.h luadebug.h
lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h
lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h
lobject.o: lobject.c lobject.h lua.h
lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h lfunc.h \
llex.h lzio.h lmem.h lopcodes.h lparser.h lstring.h luadebug.h
lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h lfunc.h \
lgc.h llex.h lzio.h lmem.h lstring.h ltable.h ltm.h
lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h lstring.h
lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h
lstx.o: lstx.c lauxlib.h lua.h ldo.h lobject.h lstate.h lfunc.h llex.h \
lzio.h lmem.h lopcodes.h lparser.h lstring.h luadebug.h
ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltable.h
ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltm.h lapi.h
ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltm.h
lua.o: lua.c lua.h luadebug.h lualib.h
lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \
lstring.h lundump.h lzio.h

File diff suppressed because it is too large Load Diff