mirror of
https://github.com/lua/lua.git
synced 2026-07-27 08:29:08 +00:00
Compare commits
62 Commits
v3.1-alpha
...
v3.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcb1a08906 | ||
|
|
1788501eed | ||
|
|
bee1a5aeb2 | ||
|
|
994aba062b | ||
|
|
e869d17eb1 | ||
|
|
9a0221ef58 | ||
|
|
07008b5d45 | ||
|
|
8f31eda649 | ||
|
|
da94130160 | ||
|
|
468fbdbde7 | ||
|
|
eb45f8b631 | ||
|
|
df0df08bc5 | ||
|
|
9618aaf07d | ||
|
|
bec9bc4154 | ||
|
|
955a811aa1 | ||
|
|
c9902be294 | ||
|
|
112c9d53ab | ||
|
|
0789451458 | ||
|
|
d97af0de26 | ||
|
|
1917149fdd | ||
|
|
0845e73b6a | ||
|
|
7dfa952091 | ||
|
|
02134b4a87 | ||
|
|
bdb1db4d37 | ||
|
|
02a6891939 | ||
|
|
741c6f5006 | ||
|
|
6152973f9c | ||
|
|
243a808067 | ||
|
|
62c36a6056 | ||
|
|
74719afc33 | ||
|
|
7e59a8901d | ||
|
|
abc6eac404 | ||
|
|
054e0b888a | ||
|
|
da252eeff7 | ||
|
|
9890bedaab | ||
|
|
0a0c9593b8 | ||
|
|
d470792517 | ||
|
|
439236773b | ||
|
|
2a2b64d6ac | ||
|
|
daa937c043 | ||
|
|
21455162b5 | ||
|
|
99cc4b20f2 | ||
|
|
0969a971cd | ||
|
|
be6d215f67 | ||
|
|
e74817f8aa | ||
|
|
043c2ac258 | ||
|
|
88a2023c32 | ||
|
|
5ef1989c4b | ||
|
|
f380d627f8 | ||
|
|
aafa106d10 | ||
|
|
29b7b8e52c | ||
|
|
a9dd2c6717 | ||
|
|
aee3f97acb | ||
|
|
46968b8ffa | ||
|
|
6cdf0d8768 | ||
|
|
07ff251a17 | ||
|
|
b3b7cf7335 | ||
|
|
8622dc18bf | ||
|
|
d22e2644dd | ||
|
|
f529a22ca5 | ||
|
|
783ba75129 | ||
|
|
d49e4dd752 |
39
bugs
39
bugs
@@ -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
57
lapi.c
@@ -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
4
lapi.h
@@ -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
|
||||
*/
|
||||
|
||||
|
||||
22
lauxlib.c
22
lauxlib.c
@@ -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)
|
||||
|
||||
12
lauxlib.h
12
lauxlib.h
@@ -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
|
||||
|
||||
12
lbuffer.c
12
lbuffer.c
@@ -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)
|
||||
{
|
||||
|
||||
110
lbuiltin.c
110
lbuiltin.c
@@ -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
59
ldo.c
@@ -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
|
||||
|
||||
|
||||
4
lfunc.c
4
lfunc.c
@@ -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
14
lgc.c
@@ -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
137
liolib.c
@@ -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
196
llex.c
@@ -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
33
llex.h
@@ -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
|
||||
|
||||
18
lmathlib.c
18
lmathlib.c
@@ -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
21
lmem.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
17
lobject.c
17
lobject.c
@@ -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;
|
||||
|
||||
42
lobject.h
42
lobject.h
@@ -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
|
||||
|
||||
31
lopcodes.h
31
lopcodes.h
@@ -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) */
|
||||
|
||||
14
lstate.c
14
lstate.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
33
lstate.h
33
lstate.h
@@ -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
145
lstring.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
232
lstrlib.c
@@ -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}
|
||||
|
||||
34
ltable.c
34
ltable.c
@@ -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
12
ltm.c
@@ -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
47
lua.c
@@ -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
96
lua.h
@@ -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
939
lua.stx
@@ -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; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
|
||||
4
lualib.h
4
lualib.h
@@ -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
254
lundump.c
@@ -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;
|
||||
}
|
||||
|
||||
72
lundump.h
72
lundump.h
@@ -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
66
lvm.c
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
25
makefile
25
makefile
@@ -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
|
||||
|
||||
894
manual.tex
894
manual.tex
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user