Compare commits

..

1 Commits
v3.2 ... v1.0

Author SHA1 Message Date
The Lua team
b9dde086db This is Lua 1.0. It was never publicly released. This code is a snapshot of
the status of Lua on 28 Jul 1993. It is distributed for historical curiosity
to celebrate 10 years of Lua and is hereby placed in the public domain.

There is no documentation, except the test programs. The manual for Lua 1.1
probably works for this version as well.

The source files for the lexer and parser have been lost: all that is left is
the output of lex and yacc. A grammar can be found inside y_tab.c in yyreds.

The code compiles and runs in RedHat 5.2 with gcc 2.7.2.3. It may not run in
newer systems, because it assumes that stdin and stdout are constants, though
ANSI C does not promise they are. If make fails, try using the fixed modules
provided in the "fixed" directory. To see the differences (which are really
quite minor), do "make diff".

To see Lua 1.0 in action, do "make test". (The last test raises an error on
purpose.)

Enjoy!

-- The Lua team, lua@tecgraf.puc-rio.br
2003-10-09 23:44:30 -03:00
74 changed files with 7022 additions and 12803 deletions

29
Makefile Normal file
View File

@@ -0,0 +1,29 @@
OBJS= hash.o inout.o lex_yy.o opcode.o table.o y_tab.o lua.o iolib.o mathlib.o strlib.o
CFLAGS= -O2 -I.
T= lua
all: $T
$T: $(OBJS)
$(CC) -o $@ $(OBJS) -lm
A=--------------------------------------------------------------------------
test: $T
@echo "$A"
./$T sort.lua main
@echo "$A"
./$T globals.lua | sort | column
@echo "$A"
./$T array.lua
@echo "$A"
./$T save.lua
@echo "$A"
./$T test.lua retorno_multiplo norma
clean:
rm -f $T $(OBJS) core core.*
diff:
diff . fixed | grep -v ^Only

22
README Normal file
View File

@@ -0,0 +1,22 @@
This is Lua 1.0. It was never publicly released. This code is a snapshot of
the status of Lua on 28 Jul 1993. It is distributed for historical curiosity
to celebrate 10 years of Lua and is hereby placed in the public domain.
There is no documentation, except the test programs. The manual for Lua 1.1
probably works for this version as well.
The source files for the lexer and parser have been lost: all that is left is
the output of lex and yacc. A grammar can be found inside y_tab.c in yyreds.
The code compiles and runs in RedHat 5.2 with gcc 2.7.2.3. It may not run in
newer systems, because it assumes that stdin and stdout are constants, though
ANSI C does not promise they are. If make fails, try using the fixed modules
provided in the "fixed" directory. To see the differences (which are really
quite minor), do "make diff".
To see Lua 1.0 in action, do "make test". (The last test raises an error on
purpose.)
Enjoy!
-- The Lua team, lua@tecgraf.puc-rio.br

15
array.lua Normal file
View File

@@ -0,0 +1,15 @@
$debug
a = @()
i=0
while i<10 do
a[i] = i*i
i=i+1
end
r,v = next(a,nil)
while r ~= nil do
print ("array["..r.."] = "..v)
r,v = next(a,r)
end

104
bugs
View File

@@ -1,104 +0,0 @@
** lua.stx / llex.c
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
(by lhf)
** 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 "empty" 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.
--- Version 3.1
** liolib.c / lauxlib.c
Mon Sep 7 15:57:02 EST 1998
>> function "luaL_argerror" prints wrong argument number (from a user's point
of view) when functions have upvalues.
** lstrlib.c
Tue Nov 10 17:29:36 EDT 1998
>> gsub/strfind do not check whether captures are properly finished.
(by roberto/tomas)
** lbuiltin.c
Fri Dec 18 11:22:55 EDT 1998
>> "tonumber" goes crazy with negative numbers in other bases (not 10),
because "strtol" returns long, not unsigned long.
(by Visual C++)
** lstrlib.c
Mon Jan 4 10:41:40 EDT 1999
>> "format" does not check size of format item (such as "%00000...00000d").
** lapi.c
Wed Feb 3 14:40:21 EDT 1999
>> getlocal cannot return the local itself, since lua_isstring and
lua_isnumber can modify it.
** lstrlib.c
Thu Feb 4 17:08:50 EDT 1999
>> format "%s" may break limit of "sprintf" on some machines.
(by Marcelo Sales)
** lzio.c
Thu Mar 4 11:49:37 EST 1999
>> file stream cannot call fread after EOF.
(by lhf)
--- Version 3.2 (beta)
** lstrlib.c
Fri Apr 30 11:10:20 EST 1999
>> '$' at end of pattern was matching regular '$', too.
(by anna; since 2.5)
** lbuiltin.c
Fri May 21 17:15:11 EST 1999
>> foreach, foreachi, foreachvar points to function in stack when stack
can be reallocated.
(by tomas; since 3.2 beta)
** lparser.c
Wed Jun 16 10:32:46 EST 1999
>> cannot assign to unlimited variables, because it causes overflow in
the number of returns of a function.
(since 3.1)

402
fixed/iolib.c Normal file
View File

@@ -0,0 +1,402 @@
/*
** iolib.c
** Input/output library to LUA
**
** Waldemar Celes Filho
** TeCGraf - PUC-Rio
** 19 May 93
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#ifdef __GNUC__
#include <floatingpoint.h>
#endif
#include "lua.h"
static FILE *in=NULL, *out=NULL;
/*
** Open a file to read.
** LUA interface:
** status = readfrom (filename)
** where:
** status = 1 -> success
** status = 0 -> error
*/
static void io_readfrom (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart input */
{
if (in != stdin)
{
fclose (in);
in = stdin;
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'readfrom`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"r");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (in != stdin) fclose (in);
in = fp;
lua_pushnumber (1);
}
}
}
}
/*
** Open a file to write.
** LUA interface:
** status = writeto (filename)
** where:
** status = 1 -> success
** status = 0 -> error
*/
static void io_writeto (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart output */
{
if (out != stdout)
{
fclose (out);
out = stdout;
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'writeto`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"w");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (out != stdout) fclose (out);
out = fp;
lua_pushnumber (1);
}
}
}
}
/*
** Read a variable. On error put nil on stack.
** LUA interface:
** variable = read ([format])
**
** O formato pode ter um dos seguintes especificadores:
**
** s ou S -> para string
** f ou F, g ou G, e ou E -> para reais
** i ou I -> para inteiros
**
** Estes especificadores podem vir seguidos de numero que representa
** o numero de campos a serem lidos.
*/
static void io_read (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* free format */
{
int c;
char s[256];
while (isspace(c=fgetc(in)))
;
if (c == '\"')
{
if (fscanf (in, "%[^\"]\"", s) != 1)
{
lua_pushnil ();
return;
}
}
else if (c == '\'')
{
if (fscanf (in, "%[^\']\'", s) != 1)
{
lua_pushnil ();
return;
}
}
else
{
char *ptr;
double d;
ungetc (c, in);
if (fscanf (in, "%s", s) != 1)
{
lua_pushnil ();
return;
}
d = strtod (s, &ptr);
if (!(*ptr))
{
lua_pushnumber (d);
return;
}
}
lua_pushstring (s);
return;
}
else /* formatted */
{
char *e = lua_getstring(o);
char t;
int m=0;
while (isspace(*e)) e++;
t = *e++;
while (isdigit(*e))
m = m*10 + (*e++ - '0');
if (m > 0)
{
char f[80];
char s[256];
sprintf (f, "%%%ds", m);
fscanf (in, f, s);
switch (tolower(t))
{
case 'i':
{
long int l;
sscanf (s, "%ld", &l);
lua_pushnumber(l);
}
break;
case 'f': case 'g': case 'e':
{
float f;
sscanf (s, "%f", &f);
lua_pushnumber(f);
}
break;
default:
lua_pushstring(s);
break;
}
}
else
{
switch (tolower(t))
{
case 'i':
{
long int l;
fscanf (in, "%ld", &l);
lua_pushnumber(l);
}
break;
case 'f': case 'g': case 'e':
{
float f;
fscanf (in, "%f", &f);
lua_pushnumber(f);
}
break;
default:
{
char s[256];
fscanf (in, "%s", s);
lua_pushstring(s);
}
break;
}
}
}
}
/*
** Write a variable. On error put 0 on stack, otherwise put 1.
** LUA interface:
** status = write (variable [,format])
**
** O formato pode ter um dos seguintes especificadores:
**
** s ou S -> para string
** f ou F, g ou G, e ou E -> para reais
** i ou I -> para inteiros
**
** Estes especificadores podem vir seguidos de:
**
** [?][m][.n]
**
** onde:
** ? -> indica justificacao
** < = esquerda
** | = centro
** > = direita (default)
** m -> numero maximo de campos (se exceder estoura)
** n -> indica precisao para
** reais -> numero de casas decimais
** inteiros -> numero minimo de digitos
** string -> nao se aplica
*/
static char *buildformat (char *e, lua_Object o)
{
static char buffer[512];
static char f[80];
char *string = &buffer[255];
char t, j='r';
int m=0, n=0, l;
while (isspace(*e)) e++;
t = *e++;
if (*e == '<' || *e == '|' || *e == '>') j = *e++;
while (isdigit(*e))
m = m*10 + (*e++ - '0');
e++; /* skip point */
while (isdigit(*e))
n = n*10 + (*e++ - '0');
sprintf(f,"%%");
if (j == '<' || j == '|') sprintf(strchr(f,0),"-");
if (m != 0) sprintf(strchr(f,0),"%d", m);
if (n != 0) sprintf(strchr(f,0),".%d", n);
sprintf(strchr(f,0), "%c", t);
switch (tolower(t))
{
case 'i': t = 'i';
sprintf (string, f, (long int)lua_getnumber(o));
break;
case 'f': case 'g': case 'e': t = 'f';
sprintf (string, f, (float)lua_getnumber(o));
break;
case 's': t = 's';
sprintf (string, f, lua_getstring(o));
break;
default: return "";
}
l = strlen(string);
if (m!=0 && l>m)
{
int i;
for (i=0; i<m; i++)
string[i] = '*';
string[i] = 0;
}
else if (m!=0 && j=='|')
{
int i=l-1;
while (isspace(string[i])) i--;
string -= (m-i) / 2;
i=0;
while (string[i]==0) string[i++] = ' ';
string[l] = 0;
}
return string;
}
static void io_write (void)
{
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (o1 == NULL) /* new line */
{
fprintf (out, "\n");
lua_pushnumber(1);
}
else if (o2 == NULL) /* free format */
{
int status=0;
if (lua_isnumber(o1))
status = fprintf (out, "%g", lua_getnumber(o1));
else if (lua_isstring(o1))
status = fprintf (out, "%s", lua_getstring(o1));
lua_pushnumber(status);
}
else /* formated */
{
if (!lua_isstring(o2))
{
lua_error ("incorrect format to function `write'");
lua_pushnumber(0);
return;
}
lua_pushnumber(fprintf (out, "%s", buildformat(lua_getstring(o2),o1)));
}
}
/*
** Execute a executable program using "sustem".
** On error put 0 on stack, otherwise put 1.
*/
void io_execute (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
system(lua_getstring(o));
lua_pushnumber (1);
}
return;
}
/*
** Remove a file.
** On error put 0 on stack, otherwise put 1.
*/
void io_remove (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
if (remove(lua_getstring(o)) == 0)
lua_pushnumber (1);
else
lua_pushnumber (0);
}
return;
}
/*
** Open io library
*/
void iolib_open (void)
{
in=stdin; out=stdout;
lua_register ("readfrom", io_readfrom);
lua_register ("writeto", io_writeto);
lua_register ("read", io_read);
lua_register ("write", io_write);
lua_register ("execute", io_execute);
lua_register ("remove", io_remove);
}

923
fixed/lex_yy.c Normal file
View File

@@ -0,0 +1,923 @@
# include "stdio.h"
# define U(x) x
# define NLSTATE yyprevious=YYNEWLINE
# define BEGIN yybgin = yysvec + 1 +
# define INITIAL 0
# define YYLERR yysvec
# define YYSTATE (yyestate-yysvec-1)
# define YYOPTIM 1
# define YYLMAX BUFSIZ
# define output(c) putc(c,yyout)
# define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar)
# define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;}
# define yymore() (yymorfg=1)
# define ECHO fprintf(yyout, "%s",yytext)
# define REJECT { nstr = yyreject(); goto yyfussy;}
int yyleng; extern char yytext[];
int yymorfg;
extern char *yysptr, yysbuf[];
int yytchar;
FILE *yyin = {NULL}, *yyout = {NULL};
extern int yylineno;
struct yysvf {
struct yywork *yystoff;
struct yysvf *yyother;
int *yystops;};
struct yysvf *yyestate;
extern struct yysvf yysvec[], *yybgin;
#include <stdlib.h>
#include <string.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "y_tab.h"
#undef input
#undef unput
static Input input;
static Unput unput;
void lua_setinput (Input fn)
{
input = fn;
}
void lua_setunput (Unput fn)
{
unput = fn;
}
char *lua_lasttext (void)
{
return yytext;
}
# define YYNEWLINE 10
yylex(){
int nstr; extern int yyprevious;
while((nstr = yylook()) >= 0)
yyfussy: switch(nstr){
case 0:
if(yywrap()) return(0); break;
case 1:
;
break;
case 2:
{yylval.vInt = 1; return DEBUG;}
break;
case 3:
{yylval.vInt = 0; return DEBUG;}
break;
case 4:
lua_linenumber++;
break;
case 5:
;
break;
case 6:
return LOCAL;
break;
case 7:
return IF;
break;
case 8:
return THEN;
break;
case 9:
return ELSE;
break;
case 10:
return ELSEIF;
break;
case 11:
return WHILE;
break;
case 12:
return DO;
break;
case 13:
return REPEAT;
break;
case 14:
return UNTIL;
break;
case 15:
{
yylval.vWord = lua_nfile-1;
return FUNCTION;
}
break;
case 16:
return END;
break;
case 17:
return RETURN;
break;
case 18:
return LOCAL;
break;
case 19:
return NIL;
break;
case 20:
return AND;
break;
case 21:
return OR;
break;
case 22:
return NOT;
break;
case 23:
return NE;
break;
case 24:
return LE;
break;
case 25:
return GE;
break;
case 26:
return CONC;
break;
case 27:
case 28:
{
yylval.vWord = lua_findenclosedconstant (yytext);
return STRING;
}
break;
case 29:
case 30:
case 31:
case 32:
{
yylval.vFloat = atof(yytext);
return NUMBER;
}
break;
case 33:
{
yylval.vWord = lua_findsymbol (yytext);
return NAME;
}
break;
case 34:
return *yytext;
break;
case -1:
break;
default:
fprintf(yyout,"bad switch yylook %d",nstr);
} return(0); }
/* end of yylex */
int yyvstop[] = {
0,
1,
0,
1,
0,
34,
0,
1,
34,
0,
4,
0,
34,
0,
34,
0,
34,
0,
34,
0,
29,
34,
0,
34,
0,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
34,
0,
34,
0,
1,
0,
27,
0,
28,
0,
5,
0,
26,
0,
30,
0,
29,
0,
29,
0,
24,
0,
25,
0,
33,
0,
33,
0,
12,
33,
0,
33,
0,
33,
0,
33,
0,
7,
33,
0,
33,
0,
33,
0,
33,
0,
21,
33,
0,
33,
0,
33,
0,
33,
0,
33,
0,
23,
0,
29,
30,
0,
31,
0,
20,
33,
0,
33,
0,
16,
33,
0,
33,
0,
33,
0,
19,
33,
0,
22,
33,
0,
33,
0,
33,
0,
33,
0,
33,
0,
33,
0,
32,
0,
9,
33,
0,
33,
0,
33,
0,
33,
0,
33,
0,
8,
33,
0,
33,
0,
33,
0,
31,
32,
0,
33,
0,
33,
0,
6,
18,
33,
0,
33,
0,
33,
0,
14,
33,
0,
11,
33,
0,
10,
33,
0,
33,
0,
13,
33,
0,
17,
33,
0,
2,
0,
33,
0,
15,
33,
0,
3,
0,
0};
# define YYTYPE char
struct yywork { YYTYPE verify, advance; } yycrank[] = {
0,0, 0,0, 1,3, 0,0,
0,0, 0,0, 0,0, 0,0,
0,0, 0,0, 1,4, 1,5,
6,29, 4,28, 0,0, 0,0,
0,0, 0,0, 7,31, 0,0,
6,29, 6,29, 0,0, 0,0,
0,0, 0,0, 7,31, 7,31,
0,0, 0,0, 0,0, 0,0,
0,0, 0,0, 0,0, 1,6,
4,28, 0,0, 0,0, 0,0,
1,7, 0,0, 0,0, 0,0,
1,3, 6,30, 1,8, 1,9,
0,0, 1,10, 6,29, 7,31,
8,33, 0,0, 6,29, 0,0,
7,32, 0,0, 0,0, 6,29,
7,31, 1,11, 0,0, 1,12,
2,27, 7,31, 1,13, 11,39,
12,40, 1,13, 26,56, 0,0,
0,0, 2,8, 2,9, 0,0,
6,29, 0,0, 0,0, 6,29,
0,0, 0,0, 7,31, 0,0,
0,0, 7,31, 0,0, 0,0,
2,11, 0,0, 2,12, 0,0,
0,0, 0,0, 0,0, 0,0,
0,0, 0,0, 1,14, 0,0,
0,0, 1,15, 1,16, 1,17,
0,0, 22,52, 1,18, 18,47,
23,53, 1,19, 42,63, 1,20,
1,21, 25,55, 14,42, 1,22,
15,43, 1,23, 1,24, 16,44,
1,25, 16,45, 17,46, 19,48,
21,51, 2,14, 20,49, 1,26,
2,15, 2,16, 2,17, 24,54,
20,50, 2,18, 44,64, 45,65,
2,19, 46,66, 2,20, 2,21,
27,57, 48,67, 2,22, 49,68,
2,23, 2,24, 50,69, 2,25,
52,70, 53,72, 27,58, 54,73,
52,71, 9,34, 2,26, 9,35,
9,35, 9,35, 9,35, 9,35,
9,35, 9,35, 9,35, 9,35,
9,35, 10,36, 55,74, 10,37,
10,37, 10,37, 10,37, 10,37,
10,37, 10,37, 10,37, 10,37,
10,37, 57,75, 58,76, 64,80,
66,81, 67,82, 70,83, 71,84,
72,85, 73,86, 74,87, 10,38,
10,38, 38,61, 10,38, 38,61,
75,88, 76,89, 38,62, 38,62,
38,62, 38,62, 38,62, 38,62,
38,62, 38,62, 38,62, 38,62,
80,92, 81,93, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
82,94, 83,95, 84,96, 10,38,
10,38, 86,97, 10,38, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 87,98, 88,99, 60,79,
60,79, 13,41, 60,79, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 33,33, 89,100, 60,79,
60,79, 92,101, 60,79, 93,102,
95,103, 33,33, 33,0, 96,104,
99,105, 100,106, 102,107, 106,108,
107,109, 35,35, 35,35, 35,35,
35,35, 35,35, 35,35, 35,35,
35,35, 35,35, 35,35, 108,110,
0,0, 0,0, 0,0, 0,0,
0,0, 0,0, 33,33, 0,0,
0,0, 35,59, 35,59, 33,33,
35,59, 0,0, 0,0, 33,33,
0,0, 0,0, 0,0, 0,0,
33,33, 0,0, 0,0, 0,0,
0,0, 36,60, 36,60, 36,60,
36,60, 36,60, 36,60, 36,60,
36,60, 36,60, 36,60, 0,0,
0,0, 33,33, 0,0, 0,0,
33,33, 35,59, 35,59, 0,0,
35,59, 36,38, 36,38, 59,77,
36,38, 59,77, 0,0, 0,0,
59,78, 59,78, 59,78, 59,78,
59,78, 59,78, 59,78, 59,78,
59,78, 59,78, 61,62, 61,62,
61,62, 61,62, 61,62, 61,62,
61,62, 61,62, 61,62, 61,62,
0,0, 0,0, 0,0, 0,0,
0,0, 36,38, 36,38, 0,0,
36,38, 77,78, 77,78, 77,78,
77,78, 77,78, 77,78, 77,78,
77,78, 77,78, 77,78, 79,90,
0,0, 79,90, 0,0, 0,0,
79,91, 79,91, 79,91, 79,91,
79,91, 79,91, 79,91, 79,91,
79,91, 79,91, 90,91, 90,91,
90,91, 90,91, 90,91, 90,91,
90,91, 90,91, 90,91, 90,91,
0,0};
struct yysvf yysvec[] = {
0, 0, 0,
yycrank+-1, 0, yyvstop+1,
yycrank+-28, yysvec+1, yyvstop+3,
yycrank+0, 0, yyvstop+5,
yycrank+4, 0, yyvstop+7,
yycrank+0, 0, yyvstop+10,
yycrank+-11, 0, yyvstop+12,
yycrank+-17, 0, yyvstop+14,
yycrank+7, 0, yyvstop+16,
yycrank+107, 0, yyvstop+18,
yycrank+119, 0, yyvstop+20,
yycrank+6, 0, yyvstop+23,
yycrank+7, 0, yyvstop+25,
yycrank+158, 0, yyvstop+27,
yycrank+4, yysvec+13, yyvstop+30,
yycrank+5, yysvec+13, yyvstop+33,
yycrank+11, yysvec+13, yyvstop+36,
yycrank+5, yysvec+13, yyvstop+39,
yycrank+5, yysvec+13, yyvstop+42,
yycrank+12, yysvec+13, yyvstop+45,
yycrank+21, yysvec+13, yyvstop+48,
yycrank+10, yysvec+13, yyvstop+51,
yycrank+4, yysvec+13, yyvstop+54,
yycrank+4, yysvec+13, yyvstop+57,
yycrank+21, yysvec+13, yyvstop+60,
yycrank+9, yysvec+13, yyvstop+63,
yycrank+9, 0, yyvstop+66,
yycrank+40, 0, yyvstop+68,
yycrank+0, yysvec+4, yyvstop+70,
yycrank+0, yysvec+6, 0,
yycrank+0, 0, yyvstop+72,
yycrank+0, yysvec+7, 0,
yycrank+0, 0, yyvstop+74,
yycrank+-280, 0, yyvstop+76,
yycrank+0, 0, yyvstop+78,
yycrank+249, 0, yyvstop+80,
yycrank+285, 0, yyvstop+82,
yycrank+0, yysvec+10, yyvstop+84,
yycrank+146, 0, 0,
yycrank+0, 0, yyvstop+86,
yycrank+0, 0, yyvstop+88,
yycrank+0, yysvec+13, yyvstop+90,
yycrank+10, yysvec+13, yyvstop+92,
yycrank+0, yysvec+13, yyvstop+94,
yycrank+19, yysvec+13, yyvstop+97,
yycrank+35, yysvec+13, yyvstop+99,
yycrank+27, yysvec+13, yyvstop+101,
yycrank+0, yysvec+13, yyvstop+103,
yycrank+42, yysvec+13, yyvstop+106,
yycrank+35, yysvec+13, yyvstop+108,
yycrank+30, yysvec+13, yyvstop+110,
yycrank+0, yysvec+13, yyvstop+112,
yycrank+36, yysvec+13, yyvstop+115,
yycrank+48, yysvec+13, yyvstop+117,
yycrank+35, yysvec+13, yyvstop+119,
yycrank+61, yysvec+13, yyvstop+121,
yycrank+0, 0, yyvstop+123,
yycrank+76, 0, 0,
yycrank+67, 0, 0,
yycrank+312, 0, 0,
yycrank+183, yysvec+36, yyvstop+125,
yycrank+322, 0, 0,
yycrank+0, yysvec+61, yyvstop+128,
yycrank+0, yysvec+13, yyvstop+130,
yycrank+78, yysvec+13, yyvstop+133,
yycrank+0, yysvec+13, yyvstop+135,
yycrank+81, yysvec+13, yyvstop+138,
yycrank+84, yysvec+13, yyvstop+140,
yycrank+0, yysvec+13, yyvstop+142,
yycrank+0, yysvec+13, yyvstop+145,
yycrank+81, yysvec+13, yyvstop+148,
yycrank+66, yysvec+13, yyvstop+150,
yycrank+74, yysvec+13, yyvstop+152,
yycrank+80, yysvec+13, yyvstop+154,
yycrank+78, yysvec+13, yyvstop+156,
yycrank+94, 0, 0,
yycrank+93, 0, 0,
yycrank+341, 0, 0,
yycrank+0, yysvec+77, yyvstop+158,
yycrank+356, 0, 0,
yycrank+99, yysvec+13, yyvstop+160,
yycrank+89, yysvec+13, yyvstop+163,
yycrank+108, yysvec+13, yyvstop+165,
yycrank+120, yysvec+13, yyvstop+167,
yycrank+104, yysvec+13, yyvstop+169,
yycrank+0, yysvec+13, yyvstop+171,
yycrank+113, yysvec+13, yyvstop+174,
yycrank+148, yysvec+13, yyvstop+176,
yycrank+133, 0, 0,
yycrank+181, 0, 0,
yycrank+366, 0, 0,
yycrank+0, yysvec+90, yyvstop+178,
yycrank+183, yysvec+13, yyvstop+181,
yycrank+182, yysvec+13, yyvstop+183,
yycrank+0, yysvec+13, yyvstop+185,
yycrank+172, yysvec+13, yyvstop+189,
yycrank+181, yysvec+13, yyvstop+191,
yycrank+0, yysvec+13, yyvstop+193,
yycrank+0, yysvec+13, yyvstop+196,
yycrank+189, 0, 0,
yycrank+195, 0, 0,
yycrank+0, yysvec+13, yyvstop+199,
yycrank+183, yysvec+13, yyvstop+202,
yycrank+0, yysvec+13, yyvstop+204,
yycrank+0, yysvec+13, yyvstop+207,
yycrank+0, 0, yyvstop+210,
yycrank+178, 0, 0,
yycrank+186, yysvec+13, yyvstop+212,
yycrank+204, 0, 0,
yycrank+0, yysvec+13, yyvstop+214,
yycrank+0, 0, yyvstop+217,
0, 0, 0};
struct yywork *yytop = yycrank+423;
struct yysvf *yybgin = yysvec+1;
char yymatch[] = {
00 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
01 ,011 ,012 ,01 ,01 ,01 ,01 ,01 ,
01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
011 ,01 ,'"' ,01 ,01 ,01 ,01 ,047 ,
01 ,01 ,01 ,'+' ,01 ,'+' ,01 ,01 ,
'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,
'0' ,'0' ,01 ,01 ,01 ,01 ,01 ,01 ,
01 ,'A' ,'A' ,'A' ,'D' ,'D' ,'A' ,'D' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,'A' ,
01 ,'A' ,'A' ,'A' ,'D' ,'D' ,'A' ,'D' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,01 ,
0};
char yyextra[] = {
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0};
#ifndef lint
static char ncform_sccsid[] = "@(#)ncform 1.6 88/02/08 SMI"; /* from S5R2 1.2 */
#endif
int yylineno =1;
# define YYU(x) x
# define NLSTATE yyprevious=YYNEWLINE
char yytext[YYLMAX];
struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp;
char yysbuf[YYLMAX];
char *yysptr = yysbuf;
int *yyfnd;
extern struct yysvf *yyestate;
int yyprevious = YYNEWLINE;
yylook(){
register struct yysvf *yystate, **lsp;
register struct yywork *yyt;
struct yysvf *yyz;
int yych, yyfirst;
struct yywork *yyr;
# ifdef LEXDEBUG
int debug;
# endif
char *yylastch;
/* start off machines */
# ifdef LEXDEBUG
debug = 0;
# endif
yyfirst=1;
if (!yymorfg)
yylastch = yytext;
else {
yymorfg=0;
yylastch = yytext+yyleng;
}
for(;;){
lsp = yylstate;
yyestate = yystate = yybgin;
if (yyprevious==YYNEWLINE) yystate++;
for (;;){
# ifdef LEXDEBUG
if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1);
# endif
yyt = yystate->yystoff;
if(yyt == yycrank && !yyfirst){ /* may not be any transitions */
yyz = yystate->yyother;
if(yyz == 0)break;
if(yyz->yystoff == yycrank)break;
}
*yylastch++ = yych = input();
yyfirst=0;
tryagain:
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"char ");
allprint(yych);
putchar('\n');
}
# endif
yyr = yyt;
if ( (int)yyt > (int)yycrank){
yyt = yyr + yych;
if (yyt <= yytop && yyt->verify+yysvec == yystate){
if(yyt->advance+yysvec == YYLERR) /* error transitions */
{unput(*--yylastch);break;}
*lsp++ = yystate = yyt->advance+yysvec;
goto contin;
}
}
# ifdef YYOPTIM
else if((int)yyt < (int)yycrank) { /* r < yycrank */
yyt = yyr = yycrank+(yycrank-yyt);
# ifdef LEXDEBUG
if(debug)fprintf(yyout,"compressed state\n");
# endif
yyt = yyt + yych;
if(yyt <= yytop && yyt->verify+yysvec == yystate){
if(yyt->advance+yysvec == YYLERR) /* error transitions */
{unput(*--yylastch);break;}
*lsp++ = yystate = yyt->advance+yysvec;
goto contin;
}
yyt = yyr + YYU(yymatch[yych]);
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"try fall back character ");
allprint(YYU(yymatch[yych]));
putchar('\n');
}
# endif
if(yyt <= yytop && yyt->verify+yysvec == yystate){
if(yyt->advance+yysvec == YYLERR) /* error transition */
{unput(*--yylastch);break;}
*lsp++ = yystate = yyt->advance+yysvec;
goto contin;
}
}
if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){
# ifdef LEXDEBUG
if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1);
# endif
goto tryagain;
}
# endif
else
{unput(*--yylastch);break;}
contin:
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"state %d char ",yystate-yysvec-1);
allprint(yych);
putchar('\n');
}
# endif
;
}
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1);
allprint(yych);
putchar('\n');
}
# endif
while (lsp-- > yylstate){
*yylastch-- = 0;
if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){
yyolsp = lsp;
if(yyextra[*yyfnd]){ /* must backup */
while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){
lsp--;
unput(*yylastch--);
}
}
yyprevious = YYU(*yylastch);
yylsp = lsp;
yyleng = yylastch-yytext+1;
yytext[yyleng] = 0;
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"\nmatch ");
sprint(yytext);
fprintf(yyout," action %d\n",*yyfnd);
}
# endif
return(*yyfnd++);
}
unput(*yylastch);
}
if (yytext[0] == 0 /* && feof(yyin) */)
{
yysptr=yysbuf;
return(0);
}
yyprevious = yytext[0] = input();
if (yyprevious>0)
output(yyprevious);
yylastch=yytext;
# ifdef LEXDEBUG
if(debug)putchar('\n');
# endif
}
}
yyback(p, m)
int *p;
{
if (p==0) return(0);
while (*p)
{
if (*p++ == m)
return(1);
}
return(0);
}
/* the following are only used in the lex library */
yyinput(){
return(input());
}
yyoutput(c)
int c; {
output(c);
}
yyunput(c)
int c; {
unput(c);
}

55
fixed/lua.c Normal file
View File

@@ -0,0 +1,55 @@
/*
** lua.c
** Linguagem para Usuarios de Aplicacao
** TeCGraf - PUC-Rio
** 28 Apr 93
*/
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
void test (void)
{
lua_pushobject(lua_getparam(1));
lua_call ("c", 1);
}
static void callfunc (void)
{
lua_Object obj = lua_getparam (1);
if (lua_isstring(obj)) lua_call(lua_getstring(obj),0);
}
static void execstr (void)
{
lua_Object obj = lua_getparam (1);
if (lua_isstring(obj)) lua_dostring(lua_getstring(obj));
}
int main (int argc, char *argv[])
{
int i;
if (argc < 2)
{
puts ("usage: lua filename [functionnames]");
return;
}
lua_register ("callfunc", callfunc);
lua_register ("execstr", execstr);
lua_register ("test", test);
iolib_open ();
strlib_open ();
mathlib_open ();
lua_dofile (argv[1]);
for (i=2; i<argc; i++)
{
lua_call (argv[i],0);
}
return 0;
}

1
floatingpoint.h Normal file
View File

@@ -0,0 +1 @@
/* empty file to please silly code in iolib.c and opcode.c */

5
globals.lua Normal file
View File

@@ -0,0 +1,5 @@
k,v=nextvar(k)
while k do
print(k)
k,v=nextvar(k)
end

259
hash.c Normal file
View File

@@ -0,0 +1,259 @@
/*
** hash.c
** hash manager for lua
** Luiz Henrique de Figueiredo - 17 Aug 90
** Modified by Waldemar Celes Filho
** 12 May 93
*/
#include <string.h>
#include <stdlib.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "lua.h"
#define streq(s1,s2) (strcmp(s1,s2)==0)
#define strneq(s1,s2) (strcmp(s1,s2)!=0)
#define new(s) ((s *)malloc(sizeof(s)))
#define newvector(n,s) ((s *)calloc(n,sizeof(s)))
#define nhash(t) ((t)->nhash)
#define nodelist(t) ((t)->list)
#define list(t,i) ((t)->list[i])
#define ref_tag(n) (tag(&(n)->ref))
#define ref_nvalue(n) (nvalue(&(n)->ref))
#define ref_svalue(n) (svalue(&(n)->ref))
static int head (Hash *t, Object *ref) /* hash function */
{
if (tag(ref) == T_NUMBER) return (((int)nvalue(ref))%nhash(t));
else if (tag(ref) == T_STRING)
{
int h;
char *name = svalue(ref);
for (h=0; *name!=0; name++) /* interpret name as binary number */
{
h <<= 8;
h += (unsigned char) *name; /* avoid sign extension */
h %= nhash(t); /* make it a valid index */
}
return h;
}
else
{
lua_reportbug ("unexpected type to index table");
return -1;
}
}
static Node *present(Hash *t, Object *ref, int h)
{
Node *n=NULL, *p;
if (tag(ref) == T_NUMBER)
{
for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)
if (ref_tag(n) == T_NUMBER && nvalue(ref) == ref_nvalue(n)) break;
}
else if (tag(ref) == T_STRING)
{
for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)
if (ref_tag(n) == T_STRING && streq(svalue(ref),ref_svalue(n))) break;
}
if (n==NULL) /* name not present */
return NULL;
#if 0
if (p!=NULL) /* name present but not first */
{
p->next=n->next; /* move-to-front self-organization */
n->next=list(t,h);
list(t,h)=n;
}
#endif
return n;
}
static void freelist (Node *n)
{
while (n)
{
Node *next = n->next;
free (n);
n = next;
}
}
/*
** Create a new hash. Return the hash pointer or NULL on error.
*/
Hash *lua_hashcreate (unsigned int nhash)
{
Hash *t = new (Hash);
if (t == NULL)
{
lua_error ("not enough memory");
return NULL;
}
nhash(t) = nhash;
markarray(t) = 0;
nodelist(t) = newvector (nhash, Node*);
if (nodelist(t) == NULL)
{
lua_error ("not enough memory");
return NULL;
}
return t;
}
/*
** Delete a hash
*/
void lua_hashdelete (Hash *h)
{
int i;
for (i=0; i<nhash(h); i++)
freelist (list(h,i));
free (nodelist(h));
free(h);
}
/*
** If the hash node is present, return its pointer, otherwise create a new
** node for the given reference and also return its pointer.
** On error, return NULL.
*/
Object *lua_hashdefine (Hash *t, Object *ref)
{
int h;
Node *n;
h = head (t, ref);
if (h < 0) return NULL;
n = present(t, ref, h);
if (n == NULL)
{
n = new(Node);
if (n == NULL)
{
lua_error ("not enough memory");
return NULL;
}
n->ref = *ref;
tag(&n->val) = T_NIL;
n->next = list(t,h); /* link node to head of list */
list(t,h) = n;
}
return (&n->val);
}
/*
** Mark a hash and check its elements
*/
void lua_hashmark (Hash *h)
{
int i;
markarray(h) = 1;
for (i=0; i<nhash(h); i++)
{
Node *n;
for (n = list(h,i); n != NULL; n = n->next)
{
lua_markobject (&n->ref);
lua_markobject (&n->val);
}
}
}
/*
** Internal function to manipulate arrays.
** Given an array object and a reference value, return the next element
** in the hash.
** This function pushs the element value and its reference to the stack.
*/
#include "lua.h"
static void firstnode (Hash *a, int h)
{
if (h < nhash(a))
{
int i;
for (i=h; i<nhash(a); i++)
{
if (list(a,i) != NULL && tag(&list(a,i)->val) != T_NIL)
{
lua_pushobject (&list(a,i)->ref);
lua_pushobject (&list(a,i)->val);
return;
}
}
}
lua_pushnil();
lua_pushnil();
}
void lua_next (void)
{
Hash *a;
Object *o = lua_getparam (1);
Object *r = lua_getparam (2);
if (o == NULL || r == NULL)
{ lua_error ("too few arguments to function `next'"); return; }
if (lua_getparam (3) != NULL)
{ lua_error ("too many arguments to function `next'"); return; }
if (tag(o) != T_ARRAY)
{ lua_error ("first argument of function `next' is not a table"); return; }
a = avalue(o);
if (tag(r) == T_NIL)
{
firstnode (a, 0);
return;
}
else
{
int h = head (a, r);
if (h >= 0)
{
Node *n = list(a,h);
while (n)
{
if (memcmp(&n->ref,r,sizeof(Object)) == 0)
{
if (n->next == NULL)
{
firstnode (a, h+1);
return;
}
else if (tag(&n->next->val) != T_NIL)
{
lua_pushobject (&n->next->ref);
lua_pushobject (&n->next->val);
return;
}
else
{
Node *next = n->next->next;
while (next != NULL && tag(&next->val) == T_NIL) next = next->next;
if (next == NULL)
{
firstnode (a, h+1);
return;
}
else
{
lua_pushobject (&next->ref);
lua_pushobject (&next->val);
}
return;
}
}
n = n->next;
}
if (n == NULL)
lua_error ("error in function 'next': reference not found");
}
}
}

35
hash.h Normal file
View File

@@ -0,0 +1,35 @@
/*
** hash.h
** hash manager for lua
** Luiz Henrique de Figueiredo - 17 Aug 90
** Modified by Waldemar Celes Filho
** 26 Apr 93
*/
#ifndef hash_h
#define hash_h
typedef struct node
{
Object ref;
Object val;
struct node *next;
} Node;
typedef struct Hash
{
char mark;
unsigned int nhash;
Node **list;
} Hash;
#define markarray(t) ((t)->mark)
Hash *lua_hashcreate (unsigned int nhash);
void lua_hashdelete (Hash *h);
Object *lua_hashdefine (Hash *t, Object *ref);
void lua_hashmark (Hash *h);
void lua_next (void);
#endif

188
inout.c Normal file
View File

@@ -0,0 +1,188 @@
/*
** inout.c
** Provide function to realise the input/output function and debugger
** facilities.
**
** Waldemar Celes Filho
** TeCGraf - PUC-Rio
** 11 May 93
*/
#include <stdio.h>
#include <string.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
/* Exported variables */
int lua_linenumber;
int lua_debug;
int lua_debugline;
/* Internal variables */
#ifndef MAXFUNCSTACK
#define MAXFUNCSTACK 32
#endif
static struct { int file; int function; } funcstack[MAXFUNCSTACK];
static int nfuncstack=0;
static FILE *fp;
static char *st;
static void (*usererror) (char *s);
/*
** Function to set user function to handle errors.
*/
void lua_errorfunction (void (*fn) (char *s))
{
usererror = fn;
}
/*
** Function to get the next character from the input file
*/
static int fileinput (void)
{
int c = fgetc (fp);
return (c == EOF ? 0 : c);
}
/*
** Function to unget the next character from to input file
*/
static void fileunput (int c)
{
ungetc (c, fp);
}
/*
** Function to get the next character from the input string
*/
static int stringinput (void)
{
st++;
return (*(st-1));
}
/*
** Function to unget the next character from to input string
*/
static void stringunput (int c)
{
st--;
}
/*
** Function to open a file to be input unit.
** Return 0 on success or 1 on error.
*/
int lua_openfile (char *fn)
{
lua_linenumber = 1;
lua_setinput (fileinput);
lua_setunput (fileunput);
fp = fopen (fn, "r");
if (fp == NULL) return 1;
if (lua_addfile (fn)) return 1;
return 0;
}
/*
** Function to close an opened file
*/
void lua_closefile (void)
{
if (fp != NULL)
{
fclose (fp);
fp = NULL;
}
}
/*
** Function to open a string to be input unit
*/
int lua_openstring (char *s)
{
lua_linenumber = 1;
lua_setinput (stringinput);
lua_setunput (stringunput);
st = s;
{
char sn[64];
sprintf (sn, "String: %10.10s...", s);
if (lua_addfile (sn)) return 1;
}
return 0;
}
/*
** Call user function to handle error messages, if registred. Or report error
** using standard function (fprintf).
*/
void lua_error (char *s)
{
if (usererror != NULL) usererror (s);
else fprintf (stderr, "lua: %s\n", s);
}
/*
** Called to execute SETFUNCTION opcode, this function pushs a function into
** function stack. Return 0 on success or 1 on error.
*/
int lua_pushfunction (int file, int function)
{
if (nfuncstack >= MAXFUNCSTACK-1)
{
lua_error ("function stack overflow");
return 1;
}
funcstack[nfuncstack].file = file;
funcstack[nfuncstack].function = function;
nfuncstack++;
return 0;
}
/*
** Called to execute RESET opcode, this function pops a function from
** function stack.
*/
void lua_popfunction (void)
{
nfuncstack--;
}
/*
** Report bug building a message and sending it to lua_error function.
*/
void lua_reportbug (char *s)
{
char msg[1024];
strcpy (msg, s);
if (lua_debugline != 0)
{
int i;
if (nfuncstack > 0)
{
sprintf (strchr(msg,0),
"\n\tin statement begining at line %d in function \"%s\" of file \"%s\"",
lua_debugline, s_name(funcstack[nfuncstack-1].function),
lua_file[funcstack[nfuncstack-1].file]);
sprintf (strchr(msg,0), "\n\tactive stack\n");
for (i=nfuncstack-1; i>=0; i--)
sprintf (strchr(msg,0), "\t-> function \"%s\" of file \"%s\"\n",
s_name(funcstack[i].function),
lua_file[funcstack[i].file]);
}
else
{
sprintf (strchr(msg,0),
"\n\tin statement begining at line %d of file \"%s\"",
lua_debugline, lua_filename());
}
}
lua_error (msg);
}

24
inout.h Normal file
View File

@@ -0,0 +1,24 @@
/*
** inout.h
**
** Waldemar Celes Filho
** TeCGraf - PUC-Rio
** 11 May 93
*/
#ifndef inout_h
#define inout_h
extern int lua_linenumber;
extern int lua_debug;
extern int lua_debugline;
int lua_openfile (char *fn);
void lua_closefile (void);
int lua_openstring (char *s);
int lua_pushfunction (int file, int function);
void lua_popfunction (void);
void lua_reportbug (char *s);
#endif

401
iolib.c Normal file
View File

@@ -0,0 +1,401 @@
/*
** iolib.c
** Input/output library to LUA
**
** Waldemar Celes Filho
** TeCGraf - PUC-Rio
** 19 May 93
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#ifdef __GNUC__
#include <floatingpoint.h>
#endif
#include "lua.h"
static FILE *in=stdin, *out=stdout;
/*
** Open a file to read.
** LUA interface:
** status = readfrom (filename)
** where:
** status = 1 -> success
** status = 0 -> error
*/
static void io_readfrom (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart input */
{
if (in != stdin)
{
fclose (in);
in = stdin;
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'readfrom`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"r");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (in != stdin) fclose (in);
in = fp;
lua_pushnumber (1);
}
}
}
}
/*
** Open a file to write.
** LUA interface:
** status = writeto (filename)
** where:
** status = 1 -> success
** status = 0 -> error
*/
static void io_writeto (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* restore standart output */
{
if (out != stdout)
{
fclose (out);
out = stdout;
}
lua_pushnumber (1);
}
else
{
if (!lua_isstring (o))
{
lua_error ("incorrect argument to function 'writeto`");
lua_pushnumber (0);
}
else
{
FILE *fp = fopen (lua_getstring(o),"w");
if (fp == NULL)
{
lua_pushnumber (0);
}
else
{
if (out != stdout) fclose (out);
out = fp;
lua_pushnumber (1);
}
}
}
}
/*
** Read a variable. On error put nil on stack.
** LUA interface:
** variable = read ([format])
**
** O formato pode ter um dos seguintes especificadores:
**
** s ou S -> para string
** f ou F, g ou G, e ou E -> para reais
** i ou I -> para inteiros
**
** Estes especificadores podem vir seguidos de numero que representa
** o numero de campos a serem lidos.
*/
static void io_read (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL) /* free format */
{
int c;
char s[256];
while (isspace(c=fgetc(in)))
;
if (c == '\"')
{
if (fscanf (in, "%[^\"]\"", s) != 1)
{
lua_pushnil ();
return;
}
}
else if (c == '\'')
{
if (fscanf (in, "%[^\']\'", s) != 1)
{
lua_pushnil ();
return;
}
}
else
{
char *ptr;
double d;
ungetc (c, in);
if (fscanf (in, "%s", s) != 1)
{
lua_pushnil ();
return;
}
d = strtod (s, &ptr);
if (!(*ptr))
{
lua_pushnumber (d);
return;
}
}
lua_pushstring (s);
return;
}
else /* formatted */
{
char *e = lua_getstring(o);
char t;
int m=0;
while (isspace(*e)) e++;
t = *e++;
while (isdigit(*e))
m = m*10 + (*e++ - '0');
if (m > 0)
{
char f[80];
char s[256];
sprintf (f, "%%%ds", m);
fscanf (in, f, s);
switch (tolower(t))
{
case 'i':
{
long int l;
sscanf (s, "%ld", &l);
lua_pushnumber(l);
}
break;
case 'f': case 'g': case 'e':
{
float f;
sscanf (s, "%f", &f);
lua_pushnumber(f);
}
break;
default:
lua_pushstring(s);
break;
}
}
else
{
switch (tolower(t))
{
case 'i':
{
long int l;
fscanf (in, "%ld", &l);
lua_pushnumber(l);
}
break;
case 'f': case 'g': case 'e':
{
float f;
fscanf (in, "%f", &f);
lua_pushnumber(f);
}
break;
default:
{
char s[256];
fscanf (in, "%s", s);
lua_pushstring(s);
}
break;
}
}
}
}
/*
** Write a variable. On error put 0 on stack, otherwise put 1.
** LUA interface:
** status = write (variable [,format])
**
** O formato pode ter um dos seguintes especificadores:
**
** s ou S -> para string
** f ou F, g ou G, e ou E -> para reais
** i ou I -> para inteiros
**
** Estes especificadores podem vir seguidos de:
**
** [?][m][.n]
**
** onde:
** ? -> indica justificacao
** < = esquerda
** | = centro
** > = direita (default)
** m -> numero maximo de campos (se exceder estoura)
** n -> indica precisao para
** reais -> numero de casas decimais
** inteiros -> numero minimo de digitos
** string -> nao se aplica
*/
static char *buildformat (char *e, lua_Object o)
{
static char buffer[512];
static char f[80];
char *string = &buffer[255];
char t, j='r';
int m=0, n=0, l;
while (isspace(*e)) e++;
t = *e++;
if (*e == '<' || *e == '|' || *e == '>') j = *e++;
while (isdigit(*e))
m = m*10 + (*e++ - '0');
e++; /* skip point */
while (isdigit(*e))
n = n*10 + (*e++ - '0');
sprintf(f,"%%");
if (j == '<' || j == '|') sprintf(strchr(f,0),"-");
if (m != 0) sprintf(strchr(f,0),"%d", m);
if (n != 0) sprintf(strchr(f,0),".%d", n);
sprintf(strchr(f,0), "%c", t);
switch (tolower(t))
{
case 'i': t = 'i';
sprintf (string, f, (long int)lua_getnumber(o));
break;
case 'f': case 'g': case 'e': t = 'f';
sprintf (string, f, (float)lua_getnumber(o));
break;
case 's': t = 's';
sprintf (string, f, lua_getstring(o));
break;
default: return "";
}
l = strlen(string);
if (m!=0 && l>m)
{
int i;
for (i=0; i<m; i++)
string[i] = '*';
string[i] = 0;
}
else if (m!=0 && j=='|')
{
int i=l-1;
while (isspace(string[i])) i--;
string -= (m-i) / 2;
i=0;
while (string[i]==0) string[i++] = ' ';
string[l] = 0;
}
return string;
}
static void io_write (void)
{
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (o1 == NULL) /* new line */
{
fprintf (out, "\n");
lua_pushnumber(1);
}
else if (o2 == NULL) /* free format */
{
int status=0;
if (lua_isnumber(o1))
status = fprintf (out, "%g", lua_getnumber(o1));
else if (lua_isstring(o1))
status = fprintf (out, "%s", lua_getstring(o1));
lua_pushnumber(status);
}
else /* formated */
{
if (!lua_isstring(o2))
{
lua_error ("incorrect format to function `write'");
lua_pushnumber(0);
return;
}
lua_pushnumber(fprintf (out, "%s", buildformat(lua_getstring(o2),o1)));
}
}
/*
** Execute a executable program using "sustem".
** On error put 0 on stack, otherwise put 1.
*/
void io_execute (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
system(lua_getstring(o));
lua_pushnumber (1);
}
return;
}
/*
** Remove a file.
** On error put 0 on stack, otherwise put 1.
*/
void io_remove (void)
{
lua_Object o = lua_getparam (1);
if (o == NULL || !lua_isstring (o))
{
lua_error ("incorrect argument to function 'execute`");
lua_pushnumber (0);
}
else
{
if (remove(lua_getstring(o)) == 0)
lua_pushnumber (1);
else
lua_pushnumber (0);
}
return;
}
/*
** Open io library
*/
void iolib_open (void)
{
lua_register ("readfrom", io_readfrom);
lua_register ("writeto", io_writeto);
lua_register ("read", io_read);
lua_register ("write", io_write);
lua_register ("execute", io_execute);
lua_register ("remove", io_remove);
}

693
lapi.c
View File

@@ -1,693 +0,0 @@
/*
** $Id: lapi.c,v 1.46 1999/06/17 17:04:03 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <string.h>
#include "lapi.h"
#include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lua.h"
#include "luadebug.h"
#include "lvm.h"
char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
"$Authors: " LUA_AUTHORS " $";
TObject *luaA_Address (lua_Object o) {
return (o != LUA_NOOBJECT) ? Address(o) : NULL;
}
static lua_Type normalized_type (TObject *o)
{
int t = ttype(o);
switch (t) {
case LUA_T_PMARK:
return LUA_T_PROTO;
case LUA_T_CMARK:
return LUA_T_CPROTO;
case LUA_T_CLMARK:
return LUA_T_CLOSURE;
default:
return t;
}
}
static void set_normalized (TObject *d, TObject *s)
{
d->value = s->value;
d->ttype = normalized_type(s);
}
static TObject *luaA_protovalue (TObject *o)
{
return (normalized_type(o) == LUA_T_CLOSURE) ? protovalue(o) : o;
}
void luaA_packresults (void)
{
luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top);
incr_top;
}
int luaA_passresults (void) {
L->Cstack.base = L->Cstack.lua2C; /* position of first result */
return L->Cstack.num;
}
static void checkCparams (int nParams)
{
if (L->stack.top-L->stack.stack < L->Cstack.base+nParams)
lua_error("API error - wrong number of arguments in C2lua stack");
}
static lua_Object put_luaObject (TObject *o) {
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
L->stack.stack[L->Cstack.base++] = *o;
return L->Cstack.base; /* this is +1 real position (see Ref) */
}
static lua_Object put_luaObjectonTop (void) {
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
L->stack.stack[L->Cstack.base++] = *(--L->stack.top);
return L->Cstack.base; /* this is +1 real position (see Ref) */
}
static void top2LC (int n) {
/* Put the 'n' elements on the top as the Lua2C contents */
L->Cstack.base = (L->stack.top-L->stack.stack); /* new base */
L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */
L->Cstack.num = n; /* number of results */
}
lua_Object lua_pop (void) {
checkCparams(1);
return put_luaObjectonTop();
}
/*
** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
** 'number' must be 1 to get the first parameter.
*/
lua_Object lua_lua2C (int number)
{
if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
/* Ref(L->stack.stack+(L->Cstack.lua2C+number-1)) ==
L->stack.stack+(L->Cstack.lua2C+number-1)-L->stack.stack+1 == */
return L->Cstack.lua2C+number;
}
int lua_callfunction (lua_Object function)
{
if (function == LUA_NOOBJECT)
return 1;
else {
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
set_normalized(L->stack.stack+L->Cstack.base, Address(function));
return luaD_protectedrun();
}
}
lua_Object lua_gettagmethod (int tag, char *event)
{
return put_luaObject(luaT_gettagmethod(tag, event));
}
lua_Object lua_settagmethod (int tag, char *event)
{
checkCparams(1);
luaT_settagmethod(tag, event, L->stack.top-1);
return put_luaObjectonTop();
}
lua_Object lua_seterrormethod (void) {
lua_Object temp;
checkCparams(1);
temp = lua_getglobal("_ERRORMESSAGE");
lua_setglobal("_ERRORMESSAGE");
return temp;
}
lua_Object lua_gettable (void)
{
checkCparams(2);
luaV_gettable();
return put_luaObjectonTop();
}
lua_Object lua_rawgettable (void) {
checkCparams(2);
if (ttype(L->stack.top-2) != LUA_T_ARRAY)
lua_error("indexed expression not a table in rawgettable");
*(L->stack.top-2) = *luaH_get(avalue(L->stack.top-2), L->stack.top-1);
--L->stack.top;
return put_luaObjectonTop();
}
void lua_settable (void) {
checkCparams(3);
luaV_settable(L->stack.top-3);
L->stack.top -= 2; /* pop table and index */
}
void lua_rawsettable (void) {
checkCparams(3);
luaV_rawsettable(L->stack.top-3);
}
lua_Object lua_createtable (void)
{
TObject o;
luaC_checkGC();
avalue(&o) = luaH_new(0);
ttype(&o) = LUA_T_ARRAY;
return put_luaObject(&o);
}
lua_Object lua_getglobal (char *name)
{
luaD_checkstack(2); /* may need that to call T.M. */
luaV_getglobal(luaS_new(name));
return put_luaObjectonTop();
}
lua_Object lua_rawgetglobal (char *name)
{
TaggedString *ts = luaS_new(name);
return put_luaObject(&ts->u.s.globalval);
}
void lua_setglobal (char *name)
{
checkCparams(1);
luaD_checkstack(2); /* may need that to call T.M. */
luaV_setglobal(luaS_new(name));
}
void lua_rawsetglobal (char *name)
{
TaggedString *ts = luaS_new(name);
checkCparams(1);
luaS_rawsetglobal(ts, --L->stack.top);
}
int lua_isnil (lua_Object o)
{
return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_NIL);
}
int lua_istable (lua_Object o)
{
return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_ARRAY);
}
int lua_isuserdata (lua_Object o)
{
return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_USERDATA);
}
int lua_iscfunction (lua_Object o)
{
return (lua_tag(o) == LUA_T_CPROTO);
}
int lua_isnumber (lua_Object o)
{
return (o!= LUA_NOOBJECT) && (tonumber(Address(o)) == 0);
}
int lua_isstring (lua_Object o)
{
int t = lua_tag(o);
return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
}
int lua_isfunction (lua_Object o)
{
int t = lua_tag(o);
return (t == LUA_T_PROTO) || (t == LUA_T_CPROTO);
}
double lua_getnumber (lua_Object object)
{
if (object == LUA_NOOBJECT) return 0.0;
if (tonumber(Address(object))) return 0.0;
else return (nvalue(Address(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)
return NULL;
else return tsvalue(Address(object))->u.d.v;
}
lua_CFunction lua_getcfunction (lua_Object object)
{
if (!lua_iscfunction(object))
return NULL;
else return fvalue(luaA_protovalue(Address(object)));
}
void lua_pushnil (void)
{
ttype(L->stack.top) = LUA_T_NIL;
incr_top;
}
void lua_pushnumber (double n)
{
ttype(L->stack.top) = LUA_T_NUMBER;
nvalue(L->stack.top) = n;
incr_top;
}
void lua_pushlstring (char *s, long len)
{
tsvalue(L->stack.top) = luaS_newlstr(s, len);
ttype(L->stack.top) = LUA_T_STRING;
incr_top;
luaC_checkGC();
}
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");
checkCparams(n);
ttype(L->stack.top) = LUA_T_CPROTO;
fvalue(L->stack.top) = fn;
incr_top;
luaV_closure(n);
luaC_checkGC();
}
void lua_pushusertag (void *u, int tag)
{
if (tag < 0 && tag != LUA_ANYTAG)
luaT_realtag(tag); /* error if tag is not valid */
tsvalue(L->stack.top) = luaS_createudata(u, tag);
ttype(L->stack.top) = LUA_T_USERDATA;
incr_top;
luaC_checkGC();
}
void luaA_pushobject (TObject *o)
{
*L->stack.top = *o;
incr_top;
}
void lua_pushobject (lua_Object o) {
if (o == LUA_NOOBJECT)
lua_error("API error - attempt to push a NOOBJECT");
set_normalized(L->stack.top, Address(o));
incr_top;
}
int lua_tag (lua_Object lo)
{
if (lo == LUA_NOOBJECT)
return LUA_T_NIL;
else {
TObject *o = Address(lo);
int t;
switch (t = ttype(o)) {
case LUA_T_USERDATA:
return o->value.ts->u.d.tag;
case LUA_T_ARRAY:
return o->value.a->htag;
case LUA_T_PMARK:
return LUA_T_PROTO;
case LUA_T_CMARK:
return LUA_T_CPROTO;
case LUA_T_CLOSURE: case LUA_T_CLMARK:
return o->value.cl->consts[0].ttype;
#ifdef DEBUG
case LUA_T_LINE:
LUA_INTERNALERROR("invalid type");
#endif
default:
return t;
}
}
}
void lua_settag (int tag)
{
checkCparams(1);
luaT_realtag(tag);
switch (ttype(L->stack.top-1)) {
case LUA_T_ARRAY:
(L->stack.top-1)->value.a->htag = tag;
break;
case LUA_T_USERDATA:
(L->stack.top-1)->value.ts->u.d.tag = tag;
break;
default:
luaL_verror("cannot change the tag of a %.20s",
luaO_typename(L->stack.top-1));
}
L->stack.top--;
}
TaggedString *luaA_nextvar (TaggedString *g) {
if (g == NULL)
g = (TaggedString *)L->rootglobal.next; /* first variable */
else {
/* check whether name is in global var list */
luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
g = (TaggedString *)g->head.next; /* get next */
}
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
g = (TaggedString *)g->head.next;
if (g) {
ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g;
incr_top;
luaA_pushobject(&g->u.s.globalval);
}
return g;
}
char *lua_nextvar (char *varname) {
TaggedString *g = (varname == NULL) ? NULL : luaS_new(varname);
g = luaA_nextvar(g);
if (g) {
top2LC(2);
return g->str;
}
else {
top2LC(0);
return NULL;
}
}
int luaA_next (Hash *t, int i) {
int tsize = nhash(t);
for (; i<tsize; i++) {
Node *n = node(t, i);
if (ttype(val(n)) != LUA_T_NIL) {
luaA_pushobject(ref(n));
luaA_pushobject(val(n));
return i+1; /* index to be used next time */
}
}
return 0; /* no more elements */
}
int lua_next (lua_Object o, int i) {
TObject *t = Address(o);
if (ttype(t) != LUA_T_ARRAY)
lua_error("API error - object is not a table in `lua_next'");
i = luaA_next(avalue(t), i);
top2LC((i==0) ? 0 : 2);
return i;
}
/*
** {======================================================
** To manipulate some state information
** =======================================================
*/
lua_State *lua_setstate (lua_State *st) {
lua_State *old = lua_state;
lua_state = st;
return old;
}
lua_LHFunction lua_setlinehook (lua_LHFunction func) {
lua_LHFunction old = L->linehook;
L->linehook = func;
return old;
}
lua_CHFunction lua_setcallhook (lua_CHFunction func) {
lua_CHFunction old = L->callhook;
L->callhook = func;
return old;
}
int lua_setdebug (int debug) {
int old = L->debug;
L->debug = debug;
return old;
}
/* }====================================================== */
/*
** {======================================================
** Debug interface
** =======================================================
*/
lua_Function lua_stackedfunction (int level)
{
StkId i;
for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) {
int t = L->stack.stack[i].ttype;
if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
if (level-- == 0)
return Ref(L->stack.stack+i);
}
return LUA_NOOBJECT;
}
int lua_nups (lua_Function func) {
TObject *o = luaA_Address(func);
return (!o || normalized_type(o) != LUA_T_CLOSURE) ? 0 : o->value.cl->nelems;
}
int lua_currentline (lua_Function func)
{
TObject *f = Address(func);
return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ?
(f+1)->value.i : -1;
}
lua_Object lua_getlocal (lua_Function func, int local_number, char **name) {
/* check whether func is a Lua function */
if (lua_tag(func) != LUA_T_PROTO)
return LUA_NOOBJECT;
else {
TObject *f = Address(func);
TProtoFunc *fp = luaA_protovalue(f)->value.tf;
*name = luaF_getlocalname(fp, local_number, lua_currentline(func));
if (*name) {
/* if "*name", there must be a LUA_T_LINE */
/* therefore, f+2 points to function base */
return put_luaObject((f+2)+(local_number-1));
}
else
return LUA_NOOBJECT;
}
}
int lua_setlocal (lua_Function func, int local_number)
{
/* check whether func is a Lua function */
if (lua_tag(func) != LUA_T_PROTO)
return 0;
else {
TObject *f = Address(func);
TProtoFunc *fp = luaA_protovalue(f)->value.tf;
char *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
checkCparams(1);
--L->stack.top;
if (name) {
/* if "name", there must be a LUA_T_LINE */
/* therefore, f+2 points to function base */
*((f+2)+(local_number-1)) = *L->stack.top;
return 1;
}
else
return 0;
}
}
void lua_funcinfo (lua_Object func, char **source, int *linedefined) {
if (!lua_isfunction(func))
lua_error("API error - `funcinfo' called with a non-function value");
else {
TObject *f = luaA_protovalue(Address(func));
if (normalized_type(f) == LUA_T_PROTO) {
*source = tfvalue(f)->source->str;
*linedefined = tfvalue(f)->lineDefined;
}
else {
*source = "(C)";
*linedefined = -1;
}
}
}
static int checkfunc (TObject *o)
{
return luaO_equalObj(o, L->stack.top);
}
char *lua_getobjname (lua_Object o, char **name)
{ /* try to find a name for given function */
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
if ((*name = luaS_travsymbol(checkfunc)) != NULL)
return "global";
else if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
return "tag-method";
else return "";
}
/* }====================================================== */
/*
** {======================================================
** BLOCK mechanism
** =======================================================
*/
#ifndef MAX_C_BLOCKS
#define MAX_C_BLOCKS 1000 /* arbitrary limit */
#endif
void lua_beginblock (void) {
luaM_growvector(L->Cblocks, L->numCblocks, 1, struct C_Lua_Stack,
"too many nested blocks", MAX_C_BLOCKS);
L->Cblocks[L->numCblocks] = L->Cstack;
L->numCblocks++;
}
void lua_endblock (void) {
--L->numCblocks;
L->Cstack = L->Cblocks[L->numCblocks];
luaD_adjusttop(L->Cstack.base);
}
int lua_ref (int lock) {
int ref;
checkCparams(1);
ref = luaC_ref(L->stack.top-1, lock);
L->stack.top--;
return ref;
}
lua_Object lua_getref (int ref) {
TObject *o = luaC_getref(ref);
return (o ? put_luaObject(o) : LUA_NOOBJECT);
}
/* }====================================================== */
#ifdef LUA_COMPAT2_5
/*
** API: set a function as a fallback
*/
static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults) {
luaD_openstack(nParams);
(L->stack.top-nParams)->ttype = LUA_T_CPROTO;
(L->stack.top-nParams)->value.f = f;
luaD_calln(nParams, nResults);
}
lua_Object lua_setfallback (char *name, lua_CFunction fallback) {
lua_pushstring(name);
lua_pushcfunction(fallback);
do_unprotectedrun(luaT_setfallback, 2, 1);
return put_luaObjectonTop();
}
#endif

22
lapi.h
View File

@@ -1,22 +0,0 @@
/*
** $Id: lapi.h,v 1.3 1999/02/22 19:13:12 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
#ifndef lapi_h
#define lapi_h
#include "lua.h"
#include "lobject.h"
TObject *luaA_Address (lua_Object o);
void luaA_pushobject (TObject *o);
void luaA_packresults (void);
int luaA_passresults (void);
TaggedString *luaA_nextvar (TaggedString *g);
int luaA_next (Hash *t, int i);
#endif

133
lauxlib.c
View File

@@ -1,133 +0,0 @@
/*
** $Id: lauxlib.c,v 1.16 1999/03/10 14:19:41 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 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.
*/
#include "lauxlib.h"
#include "lua.h"
#include "luadebug.h"
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) {
lua_Function f = lua_stackedfunction(0);
char *funcname;
lua_getobjname(f, &funcname);
numarg -= lua_nups(f);
if (funcname == NULL)
funcname = "?";
if (extramsg == NULL)
luaL_verror("bad argument #%d to function `%.50s'", numarg, funcname);
else
luaL_verror("bad argument #%d to function `%.50s' (%.100s)",
numarg, funcname, extramsg);
}
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_lstr (int numArg, char *def, long *len)
{
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
luaL_check_lstr(numArg, len);
}
double luaL_check_number (int numArg)
{
lua_Object o = lua_getparam(numArg);
luaL_arg_check(lua_isnumber(o), numArg, "number expected");
return lua_getnumber(o);
}
double luaL_opt_number (int numArg, double def)
{
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
luaL_check_number(numArg);
}
lua_Object luaL_tablearg (int arg)
{
lua_Object o = lua_getparam(arg);
luaL_arg_check(lua_istable(o), arg, "table expected");
return o;
}
lua_Object luaL_functionarg (int arg)
{
lua_Object o = lua_getparam(arg);
luaL_arg_check(lua_isfunction(o), arg, "function expected");
return o;
}
lua_Object luaL_nonnullarg (int numArg)
{
lua_Object o = lua_getparam(numArg);
luaL_arg_check(o != LUA_NOOBJECT, numArg, "value expected");
return o;
}
void luaL_openlib (struct luaL_reg *l, int n)
{
int i;
lua_open(); /* make sure lua is already open */
for (i=0; i<n; i++)
lua_register(l[i].name, l[i].func);
}
void luaL_verror (char *fmt, ...)
{
char buff[500];
va_list argp;
va_start(argp, fmt);
vsprintf(buff, fmt, argp);
va_end(argp);
lua_error(buff);
}
void luaL_chunkid (char *out, char *source, int len) {
len -= 13; /* 13 = strlen("string ''...\0") */
if (*source == '@')
sprintf(out, "file `%.*s'", len, source+1);
else if (*source == '(')
strcpy(out, "(C code)");
else {
char *b = strchr(source , '\n'); /* stop string at first new line */
int lim = (b && (b-source)<len) ? b-source : len;
sprintf(out, "string `%.*s'", lim, source);
strcpy(out+lim+(13-5), "...'"); /* 5 = strlen("...'\0") */
}
}
void luaL_filesource (char *out, char *filename, int len) {
if (filename == NULL) filename = "(stdin)";
sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */
}

View File

@@ -1,53 +0,0 @@
/*
** $Id: lauxlib.h,v 1.11 1999/03/04 21:17:26 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
#ifndef auxlib_h
#define auxlib_h
#include "lua.h"
struct luaL_reg {
char *name;
lua_CFunction func;
};
#define luaL_arg_check(cond,numarg,extramsg) if (!(cond)) \
luaL_argerror(numarg,extramsg)
void luaL_openlib (struct luaL_reg *l, int n);
void luaL_argerror (int numarg, char *extramsg);
#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);
#define luaL_check_int(n) ((int)luaL_check_number(n))
#define luaL_check_long(n) ((long)luaL_check_number(n))
double luaL_opt_number (int numArg, double def);
#define luaL_opt_int(n,d) ((int)luaL_opt_number(n,d))
#define luaL_opt_long(n,d) ((long)luaL_opt_number(n,d))
lua_Object luaL_functionarg (int arg);
lua_Object luaL_tablearg (int arg);
lua_Object luaL_nonnullarg (int numArg);
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[]);
void luaL_chunkid (char *out, char *source, int len);
void luaL_filesource (char *out, char *filename, int len);
#endif

View File

@@ -1,75 +0,0 @@
/*
** $Id: lbuffer.c,v 1.8 1999/02/25 19:20:40 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include "lauxlib.h"
#include "lmem.h"
#include "lstate.h"
/*-------------------------------------------------------
** Auxiliary buffer
-------------------------------------------------------*/
#define EXTRABUFF 32
#define openspace(size) if (L->Mbuffnext+(size) > L->Mbuffsize) Openspace(size)
static void Openspace (int size) {
lua_State *l = L; /* to optimize */
size += EXTRABUFF;
l->Mbuffsize = l->Mbuffnext+size;
luaM_growvector(l->Mbuffer, l->Mbuffnext, size, char, arrEM, MAX_INT);
}
char *luaL_openspace (int size) {
openspace(size);
return L->Mbuffer+L->Mbuffnext;
}
void luaL_addchar (int c) {
openspace(1);
L->Mbuffer[L->Mbuffnext++] = (char)c;
}
void luaL_resetbuffer (void) {
L->Mbuffnext = L->Mbuffbase;
}
void luaL_addsize (int n) {
L->Mbuffnext += n;
}
int luaL_getsize (void) {
return L->Mbuffnext-L->Mbuffbase;
}
int luaL_newbuffer (int size) {
int old = L->Mbuffbase;
openspace(size);
L->Mbuffbase = L->Mbuffnext;
return old;
}
void luaL_oldbuffer (int old) {
L->Mbuffnext = L->Mbuffbase;
L->Mbuffbase = old;
}
char *luaL_buffer (void) {
return L->Mbuffer+L->Mbuffbase;
}

View File

@@ -1,736 +0,0 @@
/*
** $Id: lbuiltin.c,v 1.58 1999/05/27 20:21:03 roberto Exp roberto $
** Built-in functions
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lapi.h"
#include "lauxlib.h"
#include "lbuiltin.h"
#include "ldo.h"
#include "lfunc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lua.h"
#include "lundump.h"
#include "lvm.h"
/*
** {======================================================
** Auxiliary functions
** =======================================================
*/
static void pushtagstring (TaggedString *s) {
TObject o;
o.ttype = LUA_T_STRING;
o.value.ts = s;
luaA_pushobject(&o);
}
static real getsize (Hash *h) {
real max = 0;
int i;
for (i = 0; i<nhash(h); i++) {
Node *n = h->node+i;
if (ttype(ref(n)) == LUA_T_NUMBER &&
ttype(val(n)) != LUA_T_NIL &&
nvalue(ref(n)) > max)
max = nvalue(ref(n));
}
return max;
}
static real getnarg (Hash *a) {
TObject index;
TObject *value;
/* value = table.n */
ttype(&index) = LUA_T_STRING;
tsvalue(&index) = luaS_new("n");
value = luaH_get(a, &index);
return (ttype(value) == LUA_T_NUMBER) ? nvalue(value) : getsize(a);
}
static Hash *gethash (int arg) {
return avalue(luaA_Address(luaL_tablearg(arg)));
}
/* }====================================================== */
/*
** {======================================================
** Functions that use only the official API
** =======================================================
*/
/*
** If your system does not support "stderr", redefine this function, or
** redefine _ERRORMESSAGE so that it won't need _ALERT.
*/
static void luaB_alert (void) {
fputs(luaL_check_string(1), stderr);
}
/*
** Standard implementation of _ERRORMESSAGE.
** The library "iolib" redefines _ERRORMESSAGE for better error information.
*/
static void error_message (void) {
lua_Object al = lua_rawgetglobal("_ALERT");
if (lua_isfunction(al)) { /* avoid error loop if _ALERT is not defined */
char buff[600];
sprintf(buff, "lua error: %.500s\n", luaL_check_string(1));
lua_pushstring(buff);
lua_callfunction(al);
}
}
/*
** If your system does not support "stdout", just remove this function.
** If you need, you can define your own "print" function, following this
** model but changing "fputs" to put the strings at a proper place
** (a console window or a log file, for instance).
*/
#ifndef MAXPRINT
#define MAXPRINT 40 /* arbitrary limit */
#endif
static void luaB_print (void) {
lua_Object args[MAXPRINT];
lua_Object obj;
int n = 0;
int i;
while ((obj = lua_getparam(n+1)) != LUA_NOOBJECT) {
luaL_arg_check(n < MAXPRINT, n+1, "too many arguments");
args[n++] = obj;
}
for (i=0; i<n; i++) {
lua_pushobject(args[i]);
if (lua_call("tostring"))
lua_error("error in `tostring' called by `print'");
obj = lua_getresult(1);
if (!lua_isstring(obj))
lua_error("`tostring' must return a string to `print'");
if (i>0) fputs("\t", stdout);
fputs(lua_getstring(obj), stdout);
}
fputs("\n", stdout);
}
static void luaB_tonumber (void) {
int base = luaL_opt_int(2, 10);
if (base == 10) { /* standard conversion */
lua_Object o = lua_getparam(1);
if (lua_isnumber(o)) lua_pushnumber(lua_getnumber(o));
else lua_pushnil(); /* not a number */
}
else {
char *s = luaL_check_string(1);
long n;
luaL_arg_check(0 <= base && base <= 36, 2, "base out of range");
n = strtol(s, &s, base);
while (isspace((unsigned char)*s)) s++; /* skip trailing spaces */
if (*s) lua_pushnil(); /* invalid format: return nil */
else lua_pushnumber(n);
}
}
static void luaB_error (void) {
lua_error(lua_getstring(lua_getparam(1)));
}
static void luaB_setglobal (void) {
char *n = luaL_check_string(1);
lua_Object value = luaL_nonnullarg(2);
lua_pushobject(value);
lua_setglobal(n);
lua_pushobject(value); /* return given value */
}
static void luaB_rawsetglobal (void) {
char *n = luaL_check_string(1);
lua_Object value = luaL_nonnullarg(2);
lua_pushobject(value);
lua_rawsetglobal(n);
lua_pushobject(value); /* return given value */
}
static void luaB_getglobal (void) {
lua_pushobject(lua_getglobal(luaL_check_string(1)));
}
static void luaB_rawgetglobal (void) {
lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
}
static void luaB_luatag (void) {
lua_pushnumber(lua_tag(lua_getparam(1)));
}
static void luaB_settag (void) {
lua_Object o = luaL_tablearg(1);
lua_pushobject(o);
lua_settag(luaL_check_int(2));
lua_pushobject(o); /* return first argument */
}
static void luaB_newtag (void) {
lua_pushnumber(lua_newtag());
}
static void luaB_copytagmethods (void) {
lua_pushnumber(lua_copytagmethods(luaL_check_int(1),
luaL_check_int(2)));
}
static void luaB_rawgettable (void) {
lua_pushobject(luaL_nonnullarg(1));
lua_pushobject(luaL_nonnullarg(2));
lua_pushobject(lua_rawgettable());
}
static void luaB_rawsettable (void) {
lua_pushobject(luaL_nonnullarg(1));
lua_pushobject(luaL_nonnullarg(2));
lua_pushobject(luaL_nonnullarg(3));
lua_rawsettable();
}
static void luaB_settagmethod (void) {
lua_Object nf = luaL_nonnullarg(3);
lua_pushobject(nf);
lua_pushobject(lua_settagmethod(luaL_check_int(1), luaL_check_string(2)));
}
static void luaB_gettagmethod (void) {
lua_pushobject(lua_gettagmethod(luaL_check_int(1), luaL_check_string(2)));
}
static void luaB_seterrormethod (void) {
lua_Object nf = luaL_functionarg(1);
lua_pushobject(nf);
lua_pushobject(lua_seterrormethod());
}
static void luaB_collectgarbage (void) {
lua_pushnumber(lua_collectgarbage(luaL_opt_int(1, 0)));
}
/* }====================================================== */
/*
** {======================================================
** Functions that could use only the official API but
** do not, for efficiency.
** =======================================================
*/
static void luaB_dostring (void) {
long l;
char *s = luaL_check_lstr(1, &l);
if (*s == ID_CHUNK)
lua_error("`dostring' cannot run pre-compiled code");
if (lua_dobuffer(s, l, luaL_opt_string(2, s)) == 0)
if (luaA_passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
static void luaB_dofile (void) {
char *fname = luaL_opt_string(1, NULL);
if (lua_dofile(fname) == 0)
if (luaA_passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
static void luaB_call (void) {
lua_Object f = luaL_nonnullarg(1);
Hash *arg = gethash(2);
char *options = luaL_opt_string(3, "");
lua_Object err = lua_getparam(4);
int narg = (int)getnarg(arg);
int i, status;
if (err != LUA_NOOBJECT) { /* set new error method */
lua_pushobject(err);
err = lua_seterrormethod();
}
/* push arg[1...n] */
luaD_checkstack(narg);
for (i=0; i<narg; i++)
*(L->stack.top++) = *luaH_getint(arg, i+1);
status = lua_callfunction(f);
if (err != LUA_NOOBJECT) { /* restore old error method */
lua_pushobject(err);
lua_seterrormethod();
}
if (status != 0) { /* error in call? */
if (strchr(options, 'x')) {
lua_pushnil();
return; /* return nil to signal the error */
}
else
lua_error(NULL);
}
else { /* no errors */
if (strchr(options, 'p'))
luaA_packresults();
else
luaA_passresults();
}
}
static void luaB_nextvar (void) {
TObject *o = luaA_Address(luaL_nonnullarg(1));
TaggedString *g;
if (ttype(o) == LUA_T_NIL)
g = NULL;
else {
luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
g = tsvalue(o);
}
if (!luaA_nextvar(g))
lua_pushnil();
}
static void luaB_next (void) {
Hash *a = gethash(1);
TObject *k = luaA_Address(luaL_nonnullarg(2));
int i = (ttype(k) == LUA_T_NIL) ? 0 : luaH_pos(a, k)+1;
if (luaA_next(a, i) == 0)
lua_pushnil();
}
static void luaB_tostring (void) {
lua_Object obj = lua_getparam(1);
TObject *o = luaA_Address(obj);
char buff[64];
switch (ttype(o)) {
case LUA_T_NUMBER:
lua_pushstring(lua_getstring(obj));
return;
case LUA_T_STRING:
lua_pushobject(obj);
return;
case LUA_T_ARRAY:
sprintf(buff, "table: %p", (void *)o->value.a);
break;
case LUA_T_CLOSURE:
sprintf(buff, "function: %p", (void *)o->value.cl);
break;
case LUA_T_PROTO:
sprintf(buff, "function: %p", (void *)o->value.tf);
break;
case LUA_T_CPROTO:
sprintf(buff, "function: %p", (void *)o->value.f);
break;
case LUA_T_USERDATA:
sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
break;
case LUA_T_NIL:
lua_pushstring("nil");
return;
default:
LUA_INTERNALERROR("invalid type");
}
lua_pushstring(buff);
}
static void luaB_type (void) {
lua_Object o = luaL_nonnullarg(1);
lua_pushstring(luaO_typename(luaA_Address(o)));
lua_pushnumber(lua_tag(o));
}
/* }====================================================== */
/*
** {======================================================
** "Extra" functions
** These functions can be written in Lua, so you can
** delete them if you need a tiny Lua implementation.
** If you delete them, remove their entries in array
** "builtin_funcs".
** =======================================================
*/
static void luaB_assert (void) {
lua_Object p = lua_getparam(1);
if (p == LUA_NOOBJECT || lua_isnil(p))
luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
}
static void luaB_foreachi (void) {
Hash *t = gethash(1);
int i;
int n = (int)getnarg(t);
TObject f;
/* 'f' cannot be a pointer to TObject, because it is on the stack, and the
stack may be reallocated by the call. Moreover, some C compilers do not
initialize structs, so we must do the assignment after the declaration */
f = *luaA_Address(luaL_functionarg(2));
luaD_checkstack(3); /* for f, ref, and val */
for (i=1; i<=n; i++) {
*(L->stack.top++) = f;
ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i;
*(L->stack.top++) = *luaH_getint(t, i);
luaD_calln(2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL)
return;
L->stack.top--;
}
}
static void luaB_foreach (void) {
Hash *a = gethash(1);
int i;
TObject f; /* see comment in 'foreachi' */
f = *luaA_Address(luaL_functionarg(2));
luaD_checkstack(3); /* for f, ref, and val */
for (i=0; i<a->nhash; i++) {
Node *nd = &(a->node[i]);
if (ttype(val(nd)) != LUA_T_NIL) {
*(L->stack.top++) = f;
*(L->stack.top++) = *ref(nd);
*(L->stack.top++) = *val(nd);
luaD_calln(2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL)
return;
L->stack.top--; /* remove result */
}
}
}
static void luaB_foreachvar (void) {
GCnode *g;
TObject f; /* see comment in 'foreachi' */
f = *luaA_Address(luaL_functionarg(1));
luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
for (g = L->rootglobal.next; g; g = g->next) {
TaggedString *s = (TaggedString *)g;
if (s->u.s.globalval.ttype != LUA_T_NIL) {
pushtagstring(s); /* keep (extra) s on stack to avoid GC */
*(L->stack.top++) = f;
pushtagstring(s);
*(L->stack.top++) = s->u.s.globalval;
luaD_calln(2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL) {
L->stack.top--;
*(L->stack.top-1) = *L->stack.top; /* remove extra s */
return;
}
L->stack.top-=2; /* remove result and extra s */
}
}
}
static void luaB_getn (void) {
lua_pushnumber(getnarg(gethash(1)));
}
static void luaB_tinsert (void) {
Hash *a = gethash(1);
lua_Object v = lua_getparam(3);
int n = (int)getnarg(a);
int pos;
if (v != LUA_NOOBJECT)
pos = luaL_check_int(2);
else { /* called with only 2 arguments */
v = luaL_nonnullarg(2);
pos = n+1;
}
luaV_setn(a, n+1); /* a.n = n+1 */
for ( ;n>=pos; n--)
luaH_move(a, n, n+1); /* a[n+1] = a[n] */
luaH_setint(a, pos, luaA_Address(v)); /* a[pos] = v */
}
static void luaB_tremove (void) {
Hash *a = gethash(1);
int n = (int)getnarg(a);
int pos = luaL_opt_int(2, n);
if (n <= 0) return; /* table is "empty" */
luaA_pushobject(luaH_getint(a, pos)); /* result = a[pos] */
for ( ;pos<n; pos++)
luaH_move(a, pos+1, pos); /* a[pos] = a[pos+1] */
luaV_setn(a, n-1); /* a.n = n-1 */
luaH_setint(a, n, &luaO_nilobject); /* a[n] = nil */
}
/* {
** Quicksort
*/
static void swap (Hash *a, int i, int j) {
TObject temp;
temp = *luaH_getint(a, i);
luaH_move(a, j, i);
luaH_setint(a, j, &temp);
}
static int sort_comp (lua_Object f, TObject *a, TObject *b) {
/* notice: the caller (auxsort) must check stack space */
if (f != LUA_NOOBJECT) {
*(L->stack.top) = *luaA_Address(f);
*(L->stack.top+1) = *a;
*(L->stack.top+2) = *b;
L->stack.top += 3;
luaD_calln(2, 1);
}
else { /* a < b? */
*(L->stack.top) = *a;
*(L->stack.top+1) = *b;
L->stack.top += 2;
luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
}
return ttype(--(L->stack.top)) != LUA_T_NIL;
}
static void auxsort (Hash *a, int l, int u, lua_Object f) {
while (l < u) { /* for tail recursion */
TObject *P;
int i, j;
/* sort elements a[l], a[(l+u)/2] and a[u] */
if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[l]>a[u]? */
swap(a, l, u);
if (u-l == 1) break; /* only 2 elements */
i = (l+u)/2;
P = luaH_getint(a, i);
if (sort_comp(f, P, luaH_getint(a, l))) /* a[l]>a[i]? */
swap(a, l, i);
else if (sort_comp(f, luaH_getint(a, u), P)) /* a[i]>a[u]? */
swap(a, i, u);
if (u-l == 2) break; /* only 3 elements */
P = L->stack.top++;
*P = *luaH_getint(a, i); /* save pivot on stack (for GC) */
swap(a, i, u-1); /* put median element as pivot (a[u-1]) */
/* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
i = l; j = u-1;
for (;;) {
/* invariant: a[l..i] <= P <= a[j..u] */
while (sort_comp(f, luaH_getint(a, ++i), P)) /* stop when a[i] >= P */
if (i>u) lua_error("invalid order function for sorting");
while (sort_comp(f, P, luaH_getint(a, --j))) /* stop when a[j] <= P */
if (j<l) lua_error("invalid order function for sorting");
if (j<i) break;
swap(a, i, j);
}
swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */
L->stack.top--; /* remove pivot from stack */
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
/* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
if (i-l < u-i) {
j=l; i=i-1; l=i+2;
}
else {
j=i+1; i=u; u=j-2;
}
auxsort(a, j, i, f); /* call recursively the smaller one */
} /* repeat the routine for the larger one */
}
static void luaB_sort (void) {
lua_Object t = lua_getparam(1);
Hash *a = gethash(1);
int n = (int)getnarg(a);
lua_Object func = lua_getparam(2);
luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2,
"function expected");
luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */
auxsort(a, 1, n, func);
lua_pushobject(t);
}
/* }}===================================================== */
/*
** ====================================================== */
#ifdef DEBUG
/*
** {======================================================
** some DEBUG functions
** =======================================================
*/
static void mem_query (void) {
lua_pushnumber(totalmem);
lua_pushnumber(numblocks);
}
static void query_strings (void) {
lua_pushnumber(L->string_root[luaL_check_int(1)].nuse);
}
static void countlist (void) {
char *s = luaL_check_string(1);
GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next :
(s[0]=='p') ? L->rootproto.next : L->rootglobal.next;
int i=0;
while (l) {
i++;
l = l->next;
}
lua_pushnumber(i);
}
static void testC (void) {
#define getnum(s) ((*s++) - '0')
#define getname(s) (nome[0] = *s++, nome)
static int locks[10];
lua_Object reg[10];
char nome[2];
char *s = luaL_check_string(1);
nome[1] = 0;
for (;;) {
switch (*s++) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
lua_pushnumber(*(s-1) - '0');
break;
case 'c': reg[getnum(s)] = lua_createtable(); break;
case 'C': { lua_CFunction f = lua_getcfunction(lua_getglobal(getname(s)));
lua_pushcclosure(f, getnum(s));
break;
}
case 'P': reg[getnum(s)] = lua_pop(); break;
case 'g': { int n=getnum(s); reg[n]=lua_getglobal(getname(s)); break; }
case 'G': { int n = getnum(s);
reg[n] = lua_rawgetglobal(getname(s));
break;
}
case 'l': locks[getnum(s)] = lua_ref(1); break;
case 'L': locks[getnum(s)] = lua_ref(0); break;
case 'r': { int n=getnum(s); reg[n]=lua_getref(locks[getnum(s)]); break; }
case 'u': lua_unref(locks[getnum(s)]); break;
case 'p': { int n = getnum(s); reg[n] = lua_getparam(getnum(s)); break; }
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 'i': reg[getnum(s)] = lua_gettable(); break;
case 'I': reg[getnum(s)] = lua_rawgettable(); break;
case 't': lua_settable(); break;
case 'T': lua_rawsettable(); break;
case 'N' : lua_pushstring(lua_nextvar(lua_getstring(reg[getnum(s)])));
break;
case 'n' : { int n=getnum(s);
n=lua_next(reg[n], (int)lua_getnumber(reg[getnum(s)]));
lua_pushnumber(n); break;
}
default: luaL_verror("unknown command in `testC': %c", *(s-1));
}
if (*s == 0) return;
if (*s++ != ' ') lua_error("missing ` ' between commands in `testC'");
}
}
/* }====================================================== */
#endif
static struct luaL_reg builtin_funcs[] = {
#ifdef LUA_COMPAT2_5
{"setfallback", luaT_setfallback},
#endif
#ifdef DEBUG
{"testC", testC},
{"totalmem", mem_query},
{"count", countlist},
{"querystr", query_strings},
#endif
{"_ALERT", luaB_alert},
{"_ERRORMESSAGE", error_message},
{"call", luaB_call},
{"collectgarbage", luaB_collectgarbage},
{"copytagmethods", luaB_copytagmethods},
{"dofile", luaB_dofile},
{"dostring", luaB_dostring},
{"error", luaB_error},
{"getglobal", luaB_getglobal},
{"gettagmethod", luaB_gettagmethod},
{"newtag", luaB_newtag},
{"next", luaB_next},
{"nextvar", luaB_nextvar},
{"print", luaB_print},
{"rawgetglobal", luaB_rawgetglobal},
{"rawgettable", luaB_rawgettable},
{"rawsetglobal", luaB_rawsetglobal},
{"rawsettable", luaB_rawsettable},
{"seterrormethod", luaB_seterrormethod},
{"setglobal", luaB_setglobal},
{"settag", luaB_settag},
{"settagmethod", luaB_settagmethod},
{"tag", luaB_luatag},
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
{"type", luaB_type},
/* "Extra" functions */
{"assert", luaB_assert},
{"foreach", luaB_foreach},
{"foreachi", luaB_foreachi},
{"foreachvar", luaB_foreachvar},
{"getn", luaB_getn},
{"sort", luaB_sort},
{"tinsert", luaB_tinsert},
{"tremove", luaB_tremove}
};
#define INTFUNCSIZE (sizeof(builtin_funcs)/sizeof(builtin_funcs[0]))
void luaB_predefine (void) {
/* pre-register mem error messages, to avoid loop when error arises */
luaS_newfixedstring(tableEM);
luaS_newfixedstring(memEM);
luaL_openlib(builtin_funcs, (sizeof(builtin_funcs)/sizeof(builtin_funcs[0])));
lua_pushstring(LUA_VERSION);
lua_setglobal("_VERSION");
}

View File

@@ -1,14 +0,0 @@
/*
** $Id: $
** Built-in functions
** See Copyright Notice in lua.h
*/
#ifndef lbuiltin_h
#define lbuiltin_h
void luaB_predefine (void);
#endif

217
ldblib.c
View File

@@ -1,217 +0,0 @@
/*
** $Id: ldblib.c,v 1.4 1999/02/04 17:47:59 roberto Exp roberto $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "lua.h"
#include "luadebug.h"
#include "lualib.h"
static void settabss (lua_Object t, char *i, char *v) {
lua_pushobject(t);
lua_pushstring(i);
lua_pushstring(v);
lua_settable();
}
static void settabsi (lua_Object t, char *i, int v) {
lua_pushobject(t);
lua_pushstring(i);
lua_pushnumber(v);
lua_settable();
}
static lua_Object getfuncinfo (lua_Object func) {
lua_Object result = lua_createtable();
char *str;
int line;
lua_funcinfo(func, &str, &line);
if (line == -1) /* C function? */
settabss(result, "kind", "C");
else if (line == 0) { /* "main"? */
settabss(result, "kind", "chunk");
settabss(result, "source", str);
}
else { /* Lua function */
settabss(result, "kind", "Lua");
settabsi(result, "def_line", line);
settabss(result, "source", str);
}
if (line != 0) { /* is it not a "main"? */
char *kind = lua_getobjname(func, &str);
if (*kind) {
settabss(result, "name", str);
settabss(result, "where", kind);
}
}
return result;
}
static void getstack (void) {
lua_Object func = lua_stackedfunction(luaL_check_int(1));
if (func == LUA_NOOBJECT) /* level out of range? */
return;
else {
lua_Object result = getfuncinfo(func);
int currline = lua_currentline(func);
if (currline > 0)
settabsi(result, "current", currline);
lua_pushobject(result);
lua_pushstring("func");
lua_pushobject(func);
lua_settable(); /* result.func = func */
lua_pushobject(result);
}
}
static void funcinfo (void) {
lua_pushobject(getfuncinfo(luaL_functionarg(1)));
}
static int findlocal (lua_Object func, int arg) {
lua_Object v = lua_getparam(arg);
if (lua_isnumber(v))
return (int)lua_getnumber(v);
else {
char *name = luaL_check_string(arg);
int i = 0;
int result = -1;
char *vname;
while (lua_getlocal(func, ++i, &vname) != LUA_NOOBJECT) {
if (strcmp(name, vname) == 0)
result = i; /* keep looping to get the last var with this name */
}
if (result == -1)
luaL_verror("no local variable `%.50s' at given level", name);
return result;
}
}
static void getlocal (void) {
lua_Object func = lua_stackedfunction(luaL_check_int(1));
lua_Object val;
char *name;
if (func == LUA_NOOBJECT) /* level out of range? */
return; /* return nil */
else if (lua_getparam(2) != LUA_NOOBJECT) { /* 2nd argument? */
if ((val = lua_getlocal(func, findlocal(func, 2), &name)) != LUA_NOOBJECT) {
lua_pushobject(val);
lua_pushstring(name);
}
/* else return nil */
}
else { /* collect all locals in a table */
lua_Object result = lua_createtable();
int i;
for (i=1; ;i++) {
if ((val = lua_getlocal(func, i, &name)) == LUA_NOOBJECT)
break;
lua_pushobject(result);
lua_pushstring(name);
lua_pushobject(val);
lua_settable(); /* result[name] = value */
}
lua_pushobject(result);
}
}
static void setlocal (void) {
lua_Object func = lua_stackedfunction(luaL_check_int(1));
int numvar;
luaL_arg_check(func != LUA_NOOBJECT, 1, "level out of range");
numvar = findlocal(func, 2);
lua_pushobject(luaL_nonnullarg(3));
if (!lua_setlocal(func, numvar))
lua_error("no such local variable");
}
static int linehook = -1; /* Lua reference to line hook function */
static int callhook = -1; /* Lua reference to call hook function */
static void dohook (int ref) {
lua_LHFunction oldlinehook = lua_setlinehook(NULL);
lua_CHFunction oldcallhook = lua_setcallhook(NULL);
lua_callfunction(lua_getref(ref));
lua_setlinehook(oldlinehook);
lua_setcallhook(oldcallhook);
}
static void linef (int line) {
lua_pushnumber(line);
dohook(linehook);
}
static void callf (lua_Function func, char *file, int line) {
if (func != LUA_NOOBJECT) {
lua_pushobject(func);
lua_pushstring(file);
lua_pushnumber(line);
}
dohook(callhook);
}
static void setcallhook (void) {
lua_Object f = lua_getparam(1);
lua_unref(callhook);
if (f == LUA_NOOBJECT) {
callhook = -1;
lua_setcallhook(NULL);
}
else {
lua_pushobject(f);
callhook = lua_ref(1);
lua_setcallhook(callf);
}
}
static void setlinehook (void) {
lua_Object f = lua_getparam(1);
lua_unref(linehook);
if (f == LUA_NOOBJECT) {
linehook = -1;
lua_setlinehook(NULL);
}
else {
lua_pushobject(f);
linehook = lua_ref(1);
lua_setlinehook(linef);
}
}
static struct luaL_reg dblib[] = {
{"funcinfo", funcinfo},
{"getlocal", getlocal},
{"getstack", getstack},
{"setcallhook", setcallhook},
{"setlinehook", setlinehook},
{"setlocal", setlocal}
};
void lua_dblibopen (void) {
luaL_openlib(dblib, (sizeof(dblib)/sizeof(dblib[0])));
}

385
ldo.c
View File

@@ -1,385 +0,0 @@
/*
** $Id: ldo.c,v 1.44 1999/06/17 17:04:03 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltm.h"
#include "lua.h"
#include "luadebug.h"
#include "lundump.h"
#include "lvm.h"
#include "lzio.h"
#ifndef STACK_LIMIT
#define STACK_LIMIT 6000 /* arbitrary limit */
#endif
#define STACK_UNIT 128
#ifdef DEBUG
#undef STACK_UNIT
#define STACK_UNIT 2
#endif
void luaD_init (void) {
L->stack.stack = luaM_newvector(STACK_UNIT, TObject);
L->stack.top = L->stack.stack;
L->stack.last = L->stack.stack+(STACK_UNIT-1);
}
void luaD_checkstack (int n) {
struct Stack *S = &L->stack;
if (S->last-S->top <= n) {
StkId top = S->top-S->stack;
int stacksize = (S->last-S->stack)+STACK_UNIT+n;
luaM_reallocvector(S->stack, stacksize, TObject);
S->last = S->stack+(stacksize-1);
S->top = S->stack + top;
if (stacksize >= STACK_LIMIT) { /* stack overflow? */
if (lua_stackedfunction(100) == LUA_NOOBJECT) /* 100 funcs on stack? */
lua_error("Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */
else
lua_error("stack size overflow");
}
}
}
/*
** Adjust stack. Set top to the given value, pushing NILs if needed.
*/
void luaD_adjusttop (StkId newtop) {
int diff = newtop-(L->stack.top-L->stack.stack);
if (diff <= 0)
L->stack.top += diff;
else {
luaD_checkstack(diff);
while (diff--)
ttype(L->stack.top++) = LUA_T_NIL;
}
}
/*
** Open a hole below "nelems" from the L->stack.top.
*/
void luaD_openstack (int nelems) {
luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems,
nelems*sizeof(TObject));
incr_top;
}
void luaD_lineHook (int line) {
struct C_Lua_Stack oldCLS = L->Cstack;
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
L->Cstack.num = 0;
(*L->linehook)(line);
L->stack.top = L->stack.stack+old_top;
L->Cstack = oldCLS;
}
void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn) {
struct C_Lua_Stack oldCLS = L->Cstack;
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
L->Cstack.num = 0;
if (isreturn)
(*L->callhook)(LUA_NOOBJECT, "(return)", 0);
else {
TObject *f = L->stack.stack+base-1;
if (tf)
(*L->callhook)(Ref(f), tf->source->str, tf->lineDefined);
else
(*L->callhook)(Ref(f), "(C)", -1);
}
L->stack.top = L->stack.stack+old_top;
L->Cstack = oldCLS;
}
/*
** Call a C function.
** Cstack.num is the number of arguments; Cstack.lua2C points to the
** first argument. Returns an index to the first result from C.
*/
static StkId callC (lua_CFunction f, StkId base) {
struct C_Lua_Stack *cls = &L->Cstack;
struct C_Lua_Stack oldCLS = *cls;
StkId firstResult;
int numarg = (L->stack.top-L->stack.stack) - base;
cls->num = numarg;
cls->lua2C = base;
cls->base = base+numarg; /* == top-stack */
if (L->callhook)
luaD_callHook(base, NULL, 0);
(*f)(); /* do the actual call */
if (L->callhook) /* func may have changed callhook */
luaD_callHook(base, NULL, 1);
firstResult = cls->base;
*cls = oldCLS;
return firstResult;
}
static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base) {
TObject *pbase;
int nup = cl->nelems; /* number of upvalues */
luaD_checkstack(nup);
pbase = L->stack.stack+base; /* care: previous call may change this */
/* open space for upvalues as extra arguments */
luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject));
/* copy upvalues into stack */
memcpy(pbase, cl->consts+1, nup*sizeof(TObject));
L->stack.top += nup;
return callC(f, base);
}
void luaD_callTM (TObject *f, int nParams, int nResults) {
luaD_openstack(nParams);
*(L->stack.top-nParams-1) = *f;
luaD_calln(nParams, nResults);
}
/*
** Call a function (C or Lua). The parameters must be on the stack,
** between [top-nArgs,top). The function to be called is right below the
** arguments.
** When returns, the results are on the stack, between [top-nArgs-1,top).
** The number of results is nResults, unless nResults=MULT_RET.
*/
void luaD_calln (int nArgs, int nResults) {
struct Stack *S = &L->stack; /* to optimize */
StkId base = (S->top-S->stack)-nArgs;
TObject *func = S->stack+base-1;
StkId firstResult;
int i;
switch (ttype(func)) {
case LUA_T_CPROTO:
ttype(func) = LUA_T_CMARK;
firstResult = callC(fvalue(func), base);
break;
case LUA_T_PROTO:
ttype(func) = LUA_T_PMARK;
firstResult = luaV_execute(NULL, tfvalue(func), base);
break;
case LUA_T_CLOSURE: {
Closure *c = clvalue(func);
TObject *proto = &(c->consts[0]);
ttype(func) = LUA_T_CLMARK;
firstResult = (ttype(proto) == LUA_T_CPROTO) ?
callCclosure(c, fvalue(proto), base) :
luaV_execute(c, tfvalue(proto), base);
break;
}
default: { /* func is not a function */
/* Check the tag method for invalid functions */
TObject *im = luaT_getimbyObj(func, IM_FUNCTION);
if (ttype(im) == LUA_T_NIL)
lua_error("call expression not a function");
luaD_callTM(im, (S->top-S->stack)-(base-1), nResults);
return;
}
}
/* adjust the number of results */
if (nResults == MULT_RET)
nResults = (S->top-S->stack)-firstResult;
else
luaD_adjusttop(firstResult+nResults);
/* move results to base-1 (to erase parameters and function) */
base--;
for (i=0; i<nResults; i++)
*(S->stack+base+i) = *(S->stack+firstResult+i);
S->top -= firstResult-base;
}
/*
** Traverse all objects on L->stack.stack
*/
void luaD_travstack (int (*fn)(TObject *))
{
StkId i;
for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--)
fn(L->stack.stack+i);
}
static void message (char *s) {
TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
ttype(em) == LUA_T_CLOSURE) {
*L->stack.top = *em;
incr_top;
lua_pushstring(s);
luaD_calln(1, 0);
}
}
/*
** Reports an error, and jumps up to the available recover label
*/
void lua_error (char *s) {
if (s) message(s);
if (L->errorJmp)
longjmp(L->errorJmp->b, 1);
else {
message("exit(1). Unable to recover.\n");
exit(1);
}
}
/*
** Execute a protected call. Assumes that function is at L->Cstack.base and
** parameters are on top of it. Leave nResults on the stack.
*/
int luaD_protectedrun (void) {
volatile struct C_Lua_Stack oldCLS = L->Cstack;
struct lua_longjmp myErrorJmp;
volatile int status;
struct lua_longjmp *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp.b) == 0) {
StkId base = L->Cstack.base;
luaD_calln((L->stack.top-L->stack.stack)-base-1, MULT_RET);
L->Cstack.lua2C = base; /* position of the new results */
L->Cstack.num = (L->stack.top-L->stack.stack) - base;
L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
status = 0;
}
else { /* an error occurred: restore L->Cstack and L->stack.top */
L->Cstack = oldCLS;
L->stack.top = L->stack.stack+L->Cstack.base;
status = 1;
}
L->errorJmp = oldErr;
return status;
}
/*
** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
*/
static int protectedparser (ZIO *z, int bin) {
volatile struct C_Lua_Stack oldCLS = L->Cstack;
struct lua_longjmp myErrorJmp;
volatile int status;
TProtoFunc *volatile tf;
struct lua_longjmp *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp.b) == 0) {
tf = bin ? luaU_undump1(z) : luaY_parser(z);
status = 0;
}
else { /* an error occurred: restore L->Cstack and L->stack.top */
L->Cstack = oldCLS;
L->stack.top = L->stack.stack+L->Cstack.base;
tf = NULL;
status = 1;
}
L->errorJmp = oldErr;
if (status) return 1; /* error code */
if (tf == NULL) return 2; /* 'natural' end */
luaD_adjusttop(L->Cstack.base+1); /* one slot for the pseudo-function */
L->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO;
L->stack.stack[L->Cstack.base].value.tf = tf;
luaV_closure(0);
return 0;
}
static int do_main (ZIO *z, int bin) {
int status;
int debug = L->debug; /* save debug status */
do {
long old_blocks = (luaC_checkGC(), L->nblocks);
status = protectedparser(z, bin);
if (status == 1) return 1; /* error */
else if (status == 2) return 0; /* 'natural' end */
else {
unsigned long newelems2 = 2*(L->nblocks-old_blocks);
L->GCthreshold += newelems2;
status = luaD_protectedrun();
L->GCthreshold -= newelems2;
}
} while (bin && status == 0);
L->debug = debug; /* restore debug status */
return status;
}
void luaD_gcIM (TObject *o)
{
TObject *im = luaT_getimbyObj(o, IM_GC);
if (ttype(im) != LUA_T_NIL) {
*L->stack.top = *o;
incr_top;
luaD_callTM(im, 1, 0);
}
}
#define MAXFILENAME 260 /* maximum part of a file name kept */
int lua_dofile (char *filename) {
ZIO z;
int status;
int c;
int bin;
char source[MAXFILENAME];
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
if (f == NULL)
return 2;
c = fgetc(f);
ungetc(c, f);
bin = (c == ID_CHUNK);
if (bin)
f = freopen(filename, "rb", f); /* set binary mode */
luaL_filesource(source, filename, sizeof(source));
luaZ_Fopen(&z, f, source);
status = do_main(&z, bin);
if (f != stdin)
fclose(f);
return status;
}
int lua_dostring (char *str) {
return lua_dobuffer(str, strlen(str), str);
}
int lua_dobuffer (char *buff, int size, char *name) {
ZIO z;
if (!name) name = "?";
luaZ_mopen(&z, buff, size, name);
return do_main(&z, buff[0]==ID_CHUNK);
}

46
ldo.h
View File

@@ -1,46 +0,0 @@
/*
** $Id: ldo.h,v 1.5 1998/07/12 16:14:34 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
#ifndef ldo_h
#define ldo_h
#include "lobject.h"
#include "lstate.h"
#define MULT_RET 255
/*
** macro to increment stack top.
** There must be always an empty slot at the L->stack.top
*/
#define incr_top { if (L->stack.top >= L->stack.last) luaD_checkstack(1); \
L->stack.top++; }
/* macros to convert from lua_Object to (TObject *) and back */
#define Address(lo) ((lo)+L->stack.stack-1)
#define Ref(st) ((st)-L->stack.stack+1)
void luaD_init (void);
void luaD_adjusttop (StkId newtop);
void luaD_openstack (int nelems);
void luaD_lineHook (int line);
void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn);
void luaD_calln (int nArgs, int nResults);
void luaD_callTM (TObject *f, int nParams, int nResults);
int luaD_protectedrun (void);
void luaD_gcIM (TObject *o);
void luaD_travstack (int (*fn)(TObject *));
void luaD_checkstack (int n);
#endif

923
lex_yy.c Normal file
View File

@@ -0,0 +1,923 @@
# include "stdio.h"
# define U(x) x
# define NLSTATE yyprevious=YYNEWLINE
# define BEGIN yybgin = yysvec + 1 +
# define INITIAL 0
# define YYLERR yysvec
# define YYSTATE (yyestate-yysvec-1)
# define YYOPTIM 1
# define YYLMAX BUFSIZ
# define output(c) putc(c,yyout)
# define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar)
# define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;}
# define yymore() (yymorfg=1)
# define ECHO fprintf(yyout, "%s",yytext)
# define REJECT { nstr = yyreject(); goto yyfussy;}
int yyleng; extern char yytext[];
int yymorfg;
extern char *yysptr, yysbuf[];
int yytchar;
FILE *yyin = {stdin}, *yyout = {stdout};
extern int yylineno;
struct yysvf {
struct yywork *yystoff;
struct yysvf *yyother;
int *yystops;};
struct yysvf *yyestate;
extern struct yysvf yysvec[], *yybgin;
#include <stdlib.h>
#include <string.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "y_tab.h"
#undef input
#undef unput
static Input input;
static Unput unput;
void lua_setinput (Input fn)
{
input = fn;
}
void lua_setunput (Unput fn)
{
unput = fn;
}
char *lua_lasttext (void)
{
return yytext;
}
# define YYNEWLINE 10
yylex(){
int nstr; extern int yyprevious;
while((nstr = yylook()) >= 0)
yyfussy: switch(nstr){
case 0:
if(yywrap()) return(0); break;
case 1:
;
break;
case 2:
{yylval.vInt = 1; return DEBUG;}
break;
case 3:
{yylval.vInt = 0; return DEBUG;}
break;
case 4:
lua_linenumber++;
break;
case 5:
;
break;
case 6:
return LOCAL;
break;
case 7:
return IF;
break;
case 8:
return THEN;
break;
case 9:
return ELSE;
break;
case 10:
return ELSEIF;
break;
case 11:
return WHILE;
break;
case 12:
return DO;
break;
case 13:
return REPEAT;
break;
case 14:
return UNTIL;
break;
case 15:
{
yylval.vWord = lua_nfile-1;
return FUNCTION;
}
break;
case 16:
return END;
break;
case 17:
return RETURN;
break;
case 18:
return LOCAL;
break;
case 19:
return NIL;
break;
case 20:
return AND;
break;
case 21:
return OR;
break;
case 22:
return NOT;
break;
case 23:
return NE;
break;
case 24:
return LE;
break;
case 25:
return GE;
break;
case 26:
return CONC;
break;
case 27:
case 28:
{
yylval.vWord = lua_findenclosedconstant (yytext);
return STRING;
}
break;
case 29:
case 30:
case 31:
case 32:
{
yylval.vFloat = atof(yytext);
return NUMBER;
}
break;
case 33:
{
yylval.vWord = lua_findsymbol (yytext);
return NAME;
}
break;
case 34:
return *yytext;
break;
case -1:
break;
default:
fprintf(yyout,"bad switch yylook %d",nstr);
} return(0); }
/* end of yylex */
int yyvstop[] = {
0,
1,
0,
1,
0,
34,
0,
1,
34,
0,
4,
0,
34,
0,
34,
0,
34,
0,
34,
0,
29,
34,
0,
34,
0,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
33,
34,
0,
34,
0,
34,
0,
1,
0,
27,
0,
28,
0,
5,
0,
26,
0,
30,
0,
29,
0,
29,
0,
24,
0,
25,
0,
33,
0,
33,
0,
12,
33,
0,
33,
0,
33,
0,
33,
0,
7,
33,
0,
33,
0,
33,
0,
33,
0,
21,
33,
0,
33,
0,
33,
0,
33,
0,
33,
0,
23,
0,
29,
30,
0,
31,
0,
20,
33,
0,
33,
0,
16,
33,
0,
33,
0,
33,
0,
19,
33,
0,
22,
33,
0,
33,
0,
33,
0,
33,
0,
33,
0,
33,
0,
32,
0,
9,
33,
0,
33,
0,
33,
0,
33,
0,
33,
0,
8,
33,
0,
33,
0,
33,
0,
31,
32,
0,
33,
0,
33,
0,
6,
18,
33,
0,
33,
0,
33,
0,
14,
33,
0,
11,
33,
0,
10,
33,
0,
33,
0,
13,
33,
0,
17,
33,
0,
2,
0,
33,
0,
15,
33,
0,
3,
0,
0};
# define YYTYPE char
struct yywork { YYTYPE verify, advance; } yycrank[] = {
0,0, 0,0, 1,3, 0,0,
0,0, 0,0, 0,0, 0,0,
0,0, 0,0, 1,4, 1,5,
6,29, 4,28, 0,0, 0,0,
0,0, 0,0, 7,31, 0,0,
6,29, 6,29, 0,0, 0,0,
0,0, 0,0, 7,31, 7,31,
0,0, 0,0, 0,0, 0,0,
0,0, 0,0, 0,0, 1,6,
4,28, 0,0, 0,0, 0,0,
1,7, 0,0, 0,0, 0,0,
1,3, 6,30, 1,8, 1,9,
0,0, 1,10, 6,29, 7,31,
8,33, 0,0, 6,29, 0,0,
7,32, 0,0, 0,0, 6,29,
7,31, 1,11, 0,0, 1,12,
2,27, 7,31, 1,13, 11,39,
12,40, 1,13, 26,56, 0,0,
0,0, 2,8, 2,9, 0,0,
6,29, 0,0, 0,0, 6,29,
0,0, 0,0, 7,31, 0,0,
0,0, 7,31, 0,0, 0,0,
2,11, 0,0, 2,12, 0,0,
0,0, 0,0, 0,0, 0,0,
0,0, 0,0, 1,14, 0,0,
0,0, 1,15, 1,16, 1,17,
0,0, 22,52, 1,18, 18,47,
23,53, 1,19, 42,63, 1,20,
1,21, 25,55, 14,42, 1,22,
15,43, 1,23, 1,24, 16,44,
1,25, 16,45, 17,46, 19,48,
21,51, 2,14, 20,49, 1,26,
2,15, 2,16, 2,17, 24,54,
20,50, 2,18, 44,64, 45,65,
2,19, 46,66, 2,20, 2,21,
27,57, 48,67, 2,22, 49,68,
2,23, 2,24, 50,69, 2,25,
52,70, 53,72, 27,58, 54,73,
52,71, 9,34, 2,26, 9,35,
9,35, 9,35, 9,35, 9,35,
9,35, 9,35, 9,35, 9,35,
9,35, 10,36, 55,74, 10,37,
10,37, 10,37, 10,37, 10,37,
10,37, 10,37, 10,37, 10,37,
10,37, 57,75, 58,76, 64,80,
66,81, 67,82, 70,83, 71,84,
72,85, 73,86, 74,87, 10,38,
10,38, 38,61, 10,38, 38,61,
75,88, 76,89, 38,62, 38,62,
38,62, 38,62, 38,62, 38,62,
38,62, 38,62, 38,62, 38,62,
80,92, 81,93, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
82,94, 83,95, 84,96, 10,38,
10,38, 86,97, 10,38, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 87,98, 88,99, 60,79,
60,79, 13,41, 60,79, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 13,41, 13,41, 13,41,
13,41, 33,33, 89,100, 60,79,
60,79, 92,101, 60,79, 93,102,
95,103, 33,33, 33,0, 96,104,
99,105, 100,106, 102,107, 106,108,
107,109, 35,35, 35,35, 35,35,
35,35, 35,35, 35,35, 35,35,
35,35, 35,35, 35,35, 108,110,
0,0, 0,0, 0,0, 0,0,
0,0, 0,0, 33,33, 0,0,
0,0, 35,59, 35,59, 33,33,
35,59, 0,0, 0,0, 33,33,
0,0, 0,0, 0,0, 0,0,
33,33, 0,0, 0,0, 0,0,
0,0, 36,60, 36,60, 36,60,
36,60, 36,60, 36,60, 36,60,
36,60, 36,60, 36,60, 0,0,
0,0, 33,33, 0,0, 0,0,
33,33, 35,59, 35,59, 0,0,
35,59, 36,38, 36,38, 59,77,
36,38, 59,77, 0,0, 0,0,
59,78, 59,78, 59,78, 59,78,
59,78, 59,78, 59,78, 59,78,
59,78, 59,78, 61,62, 61,62,
61,62, 61,62, 61,62, 61,62,
61,62, 61,62, 61,62, 61,62,
0,0, 0,0, 0,0, 0,0,
0,0, 36,38, 36,38, 0,0,
36,38, 77,78, 77,78, 77,78,
77,78, 77,78, 77,78, 77,78,
77,78, 77,78, 77,78, 79,90,
0,0, 79,90, 0,0, 0,0,
79,91, 79,91, 79,91, 79,91,
79,91, 79,91, 79,91, 79,91,
79,91, 79,91, 90,91, 90,91,
90,91, 90,91, 90,91, 90,91,
90,91, 90,91, 90,91, 90,91,
0,0};
struct yysvf yysvec[] = {
0, 0, 0,
yycrank+-1, 0, yyvstop+1,
yycrank+-28, yysvec+1, yyvstop+3,
yycrank+0, 0, yyvstop+5,
yycrank+4, 0, yyvstop+7,
yycrank+0, 0, yyvstop+10,
yycrank+-11, 0, yyvstop+12,
yycrank+-17, 0, yyvstop+14,
yycrank+7, 0, yyvstop+16,
yycrank+107, 0, yyvstop+18,
yycrank+119, 0, yyvstop+20,
yycrank+6, 0, yyvstop+23,
yycrank+7, 0, yyvstop+25,
yycrank+158, 0, yyvstop+27,
yycrank+4, yysvec+13, yyvstop+30,
yycrank+5, yysvec+13, yyvstop+33,
yycrank+11, yysvec+13, yyvstop+36,
yycrank+5, yysvec+13, yyvstop+39,
yycrank+5, yysvec+13, yyvstop+42,
yycrank+12, yysvec+13, yyvstop+45,
yycrank+21, yysvec+13, yyvstop+48,
yycrank+10, yysvec+13, yyvstop+51,
yycrank+4, yysvec+13, yyvstop+54,
yycrank+4, yysvec+13, yyvstop+57,
yycrank+21, yysvec+13, yyvstop+60,
yycrank+9, yysvec+13, yyvstop+63,
yycrank+9, 0, yyvstop+66,
yycrank+40, 0, yyvstop+68,
yycrank+0, yysvec+4, yyvstop+70,
yycrank+0, yysvec+6, 0,
yycrank+0, 0, yyvstop+72,
yycrank+0, yysvec+7, 0,
yycrank+0, 0, yyvstop+74,
yycrank+-280, 0, yyvstop+76,
yycrank+0, 0, yyvstop+78,
yycrank+249, 0, yyvstop+80,
yycrank+285, 0, yyvstop+82,
yycrank+0, yysvec+10, yyvstop+84,
yycrank+146, 0, 0,
yycrank+0, 0, yyvstop+86,
yycrank+0, 0, yyvstop+88,
yycrank+0, yysvec+13, yyvstop+90,
yycrank+10, yysvec+13, yyvstop+92,
yycrank+0, yysvec+13, yyvstop+94,
yycrank+19, yysvec+13, yyvstop+97,
yycrank+35, yysvec+13, yyvstop+99,
yycrank+27, yysvec+13, yyvstop+101,
yycrank+0, yysvec+13, yyvstop+103,
yycrank+42, yysvec+13, yyvstop+106,
yycrank+35, yysvec+13, yyvstop+108,
yycrank+30, yysvec+13, yyvstop+110,
yycrank+0, yysvec+13, yyvstop+112,
yycrank+36, yysvec+13, yyvstop+115,
yycrank+48, yysvec+13, yyvstop+117,
yycrank+35, yysvec+13, yyvstop+119,
yycrank+61, yysvec+13, yyvstop+121,
yycrank+0, 0, yyvstop+123,
yycrank+76, 0, 0,
yycrank+67, 0, 0,
yycrank+312, 0, 0,
yycrank+183, yysvec+36, yyvstop+125,
yycrank+322, 0, 0,
yycrank+0, yysvec+61, yyvstop+128,
yycrank+0, yysvec+13, yyvstop+130,
yycrank+78, yysvec+13, yyvstop+133,
yycrank+0, yysvec+13, yyvstop+135,
yycrank+81, yysvec+13, yyvstop+138,
yycrank+84, yysvec+13, yyvstop+140,
yycrank+0, yysvec+13, yyvstop+142,
yycrank+0, yysvec+13, yyvstop+145,
yycrank+81, yysvec+13, yyvstop+148,
yycrank+66, yysvec+13, yyvstop+150,
yycrank+74, yysvec+13, yyvstop+152,
yycrank+80, yysvec+13, yyvstop+154,
yycrank+78, yysvec+13, yyvstop+156,
yycrank+94, 0, 0,
yycrank+93, 0, 0,
yycrank+341, 0, 0,
yycrank+0, yysvec+77, yyvstop+158,
yycrank+356, 0, 0,
yycrank+99, yysvec+13, yyvstop+160,
yycrank+89, yysvec+13, yyvstop+163,
yycrank+108, yysvec+13, yyvstop+165,
yycrank+120, yysvec+13, yyvstop+167,
yycrank+104, yysvec+13, yyvstop+169,
yycrank+0, yysvec+13, yyvstop+171,
yycrank+113, yysvec+13, yyvstop+174,
yycrank+148, yysvec+13, yyvstop+176,
yycrank+133, 0, 0,
yycrank+181, 0, 0,
yycrank+366, 0, 0,
yycrank+0, yysvec+90, yyvstop+178,
yycrank+183, yysvec+13, yyvstop+181,
yycrank+182, yysvec+13, yyvstop+183,
yycrank+0, yysvec+13, yyvstop+185,
yycrank+172, yysvec+13, yyvstop+189,
yycrank+181, yysvec+13, yyvstop+191,
yycrank+0, yysvec+13, yyvstop+193,
yycrank+0, yysvec+13, yyvstop+196,
yycrank+189, 0, 0,
yycrank+195, 0, 0,
yycrank+0, yysvec+13, yyvstop+199,
yycrank+183, yysvec+13, yyvstop+202,
yycrank+0, yysvec+13, yyvstop+204,
yycrank+0, yysvec+13, yyvstop+207,
yycrank+0, 0, yyvstop+210,
yycrank+178, 0, 0,
yycrank+186, yysvec+13, yyvstop+212,
yycrank+204, 0, 0,
yycrank+0, yysvec+13, yyvstop+214,
yycrank+0, 0, yyvstop+217,
0, 0, 0};
struct yywork *yytop = yycrank+423;
struct yysvf *yybgin = yysvec+1;
char yymatch[] = {
00 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
01 ,011 ,012 ,01 ,01 ,01 ,01 ,01 ,
01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
011 ,01 ,'"' ,01 ,01 ,01 ,01 ,047 ,
01 ,01 ,01 ,'+' ,01 ,'+' ,01 ,01 ,
'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,
'0' ,'0' ,01 ,01 ,01 ,01 ,01 ,01 ,
01 ,'A' ,'A' ,'A' ,'D' ,'D' ,'A' ,'D' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,'A' ,
01 ,'A' ,'A' ,'A' ,'D' ,'D' ,'A' ,'D' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,01 ,
0};
char yyextra[] = {
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0};
#ifndef lint
static char ncform_sccsid[] = "@(#)ncform 1.6 88/02/08 SMI"; /* from S5R2 1.2 */
#endif
int yylineno =1;
# define YYU(x) x
# define NLSTATE yyprevious=YYNEWLINE
char yytext[YYLMAX];
struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp;
char yysbuf[YYLMAX];
char *yysptr = yysbuf;
int *yyfnd;
extern struct yysvf *yyestate;
int yyprevious = YYNEWLINE;
yylook(){
register struct yysvf *yystate, **lsp;
register struct yywork *yyt;
struct yysvf *yyz;
int yych, yyfirst;
struct yywork *yyr;
# ifdef LEXDEBUG
int debug;
# endif
char *yylastch;
/* start off machines */
# ifdef LEXDEBUG
debug = 0;
# endif
yyfirst=1;
if (!yymorfg)
yylastch = yytext;
else {
yymorfg=0;
yylastch = yytext+yyleng;
}
for(;;){
lsp = yylstate;
yyestate = yystate = yybgin;
if (yyprevious==YYNEWLINE) yystate++;
for (;;){
# ifdef LEXDEBUG
if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1);
# endif
yyt = yystate->yystoff;
if(yyt == yycrank && !yyfirst){ /* may not be any transitions */
yyz = yystate->yyother;
if(yyz == 0)break;
if(yyz->yystoff == yycrank)break;
}
*yylastch++ = yych = input();
yyfirst=0;
tryagain:
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"char ");
allprint(yych);
putchar('\n');
}
# endif
yyr = yyt;
if ( (int)yyt > (int)yycrank){
yyt = yyr + yych;
if (yyt <= yytop && yyt->verify+yysvec == yystate){
if(yyt->advance+yysvec == YYLERR) /* error transitions */
{unput(*--yylastch);break;}
*lsp++ = yystate = yyt->advance+yysvec;
goto contin;
}
}
# ifdef YYOPTIM
else if((int)yyt < (int)yycrank) { /* r < yycrank */
yyt = yyr = yycrank+(yycrank-yyt);
# ifdef LEXDEBUG
if(debug)fprintf(yyout,"compressed state\n");
# endif
yyt = yyt + yych;
if(yyt <= yytop && yyt->verify+yysvec == yystate){
if(yyt->advance+yysvec == YYLERR) /* error transitions */
{unput(*--yylastch);break;}
*lsp++ = yystate = yyt->advance+yysvec;
goto contin;
}
yyt = yyr + YYU(yymatch[yych]);
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"try fall back character ");
allprint(YYU(yymatch[yych]));
putchar('\n');
}
# endif
if(yyt <= yytop && yyt->verify+yysvec == yystate){
if(yyt->advance+yysvec == YYLERR) /* error transition */
{unput(*--yylastch);break;}
*lsp++ = yystate = yyt->advance+yysvec;
goto contin;
}
}
if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){
# ifdef LEXDEBUG
if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1);
# endif
goto tryagain;
}
# endif
else
{unput(*--yylastch);break;}
contin:
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"state %d char ",yystate-yysvec-1);
allprint(yych);
putchar('\n');
}
# endif
;
}
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1);
allprint(yych);
putchar('\n');
}
# endif
while (lsp-- > yylstate){
*yylastch-- = 0;
if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){
yyolsp = lsp;
if(yyextra[*yyfnd]){ /* must backup */
while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){
lsp--;
unput(*yylastch--);
}
}
yyprevious = YYU(*yylastch);
yylsp = lsp;
yyleng = yylastch-yytext+1;
yytext[yyleng] = 0;
# ifdef LEXDEBUG
if(debug){
fprintf(yyout,"\nmatch ");
sprint(yytext);
fprintf(yyout," action %d\n",*yyfnd);
}
# endif
return(*yyfnd++);
}
unput(*yylastch);
}
if (yytext[0] == 0 /* && feof(yyin) */)
{
yysptr=yysbuf;
return(0);
}
yyprevious = yytext[0] = input();
if (yyprevious>0)
output(yyprevious);
yylastch=yytext;
# ifdef LEXDEBUG
if(debug)putchar('\n');
# endif
}
}
yyback(p, m)
int *p;
{
if (p==0) return(0);
while (*p)
{
if (*p++ == m)
return(1);
}
return(0);
}
/* the following are only used in the lex library */
yyinput(){
return(input());
}
yyoutput(c)
int c; {
output(c);
}
yyunput(c)
int c; {
unput(c);
}

98
lfunc.c
View File

@@ -1,98 +0,0 @@
/*
** $Id: lfunc.c,v 1.9 1998/06/19 16:14:09 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include "lfunc.h"
#include "lmem.h"
#include "lstate.h"
#define gcsizeproto(p) 5 /* approximate "weight" for a prototype */
#define gcsizeclosure(c) 1 /* approximate "weight" for a closure */
Closure *luaF_newclosure (int nelems)
{
Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject));
luaO_insertlist(&(L->rootcl), (GCnode *)c);
L->nblocks += gcsizeclosure(c);
c->nelems = nelems;
return c;
}
TProtoFunc *luaF_newproto (void)
{
TProtoFunc *f = luaM_new(TProtoFunc);
f->code = NULL;
f->lineDefined = 0;
f->source = NULL;
f->consts = NULL;
f->nconsts = 0;
f->locvars = NULL;
luaO_insertlist(&(L->rootproto), (GCnode *)f);
L->nblocks += gcsizeproto(f);
return f;
}
static void freefunc (TProtoFunc *f)
{
luaM_free(f->code);
luaM_free(f->locvars);
luaM_free(f->consts);
luaM_free(f);
}
void luaF_freeproto (TProtoFunc *l)
{
while (l) {
TProtoFunc *next = (TProtoFunc *)l->head.next;
L->nblocks -= gcsizeproto(l);
freefunc(l);
l = next;
}
}
void luaF_freeclosure (Closure *l)
{
while (l) {
Closure *next = (Closure *)l->head.next;
L->nblocks -= gcsizeclosure(l);
luaM_free(l);
l = next;
}
}
/*
** Look for n-th local variable at line "line" in function "func".
** Returns NULL if not found.
*/
char *luaF_getlocalname (TProtoFunc *func, int local_number, int line)
{
int count = 0;
char *varname = NULL;
LocVar *lv = func->locvars;
if (lv == NULL)
return NULL;
for (; lv->line != -1 && lv->line < line; lv++) {
if (lv->varname) { /* register */
if (++count == local_number)
varname = lv->varname->str;
}
else /* unregister */
if (--count < local_number)
varname = NULL;
}
return varname;
}

23
lfunc.h
View File

@@ -1,23 +0,0 @@
/*
** $Id: lfunc.h,v 1.4 1997/11/19 17:29:23 roberto Exp roberto $
** Lua Function structures
** See Copyright Notice in lua.h
*/
#ifndef lfunc_h
#define lfunc_h
#include "lobject.h"
TProtoFunc *luaF_newproto (void);
Closure *luaF_newclosure (int nelems);
void luaF_freeproto (TProtoFunc *l);
void luaF_freeclosure (Closure *l);
char *luaF_getlocalname (TProtoFunc *func, int local_number, int line);
#endif

275
lgc.c
View File

@@ -1,275 +0,0 @@
/*
** $Id: lgc.c,v 1.22 1999/02/26 15:48:55 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lua.h"
static int markobject (TObject *o);
/*
** =======================================================
** REF mechanism
** =======================================================
*/
int luaC_ref (TObject *o, int lock) {
int ref;
if (ttype(o) == LUA_T_NIL)
ref = -1; /* special ref for nil */
else {
for (ref=0; ref<L->refSize; ref++)
if (L->refArray[ref].status == FREE)
break;
if (ref == L->refSize) { /* no more empty spaces? */
luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT);
L->refSize++;
}
L->refArray[ref].o = *o;
L->refArray[ref].status = lock ? LOCK : HOLD;
}
return ref;
}
void lua_unref (int ref)
{
if (ref >= 0 && ref < L->refSize)
L->refArray[ref].status = FREE;
}
TObject* luaC_getref (int ref)
{
if (ref == -1)
return &luaO_nilobject;
if (ref >= 0 && ref < L->refSize &&
(L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD))
return &L->refArray[ref].o;
else
return NULL;
}
static void travlock (void)
{
int i;
for (i=0; i<L->refSize; i++)
if (L->refArray[i].status == LOCK)
markobject(&L->refArray[i].o);
}
static int ismarked (TObject *o)
{
/* valid only for locked objects */
switch (o->ttype) {
case LUA_T_STRING: case LUA_T_USERDATA:
return o->value.ts->head.marked;
case LUA_T_ARRAY:
return o->value.a->head.marked;
case LUA_T_CLOSURE:
return o->value.cl->head.marked;
case LUA_T_PROTO:
return o->value.tf->head.marked;
#ifdef DEBUG
case LUA_T_LINE: case LUA_T_CLMARK:
case LUA_T_CMARK: case LUA_T_PMARK:
LUA_INTERNALERROR("invalid type");
#endif
default: /* nil, number or cproto */
return 1;
}
}
static void invalidaterefs (void)
{
int i;
for (i=0; i<L->refSize; i++)
if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o))
L->refArray[i].status = COLLECTED;
}
void luaC_hashcallIM (Hash *l)
{
TObject t;
ttype(&t) = LUA_T_ARRAY;
for (; l; l=(Hash *)l->head.next) {
avalue(&t) = l;
luaD_gcIM(&t);
}
}
void luaC_strcallIM (TaggedString *l)
{
TObject o;
ttype(&o) = LUA_T_USERDATA;
for (; l; l=(TaggedString *)l->head.next)
if (l->constindex == -1) { /* is userdata? */
tsvalue(&o) = l;
luaD_gcIM(&o);
}
}
static GCnode *listcollect (GCnode *l)
{
GCnode *frees = NULL;
while (l) {
GCnode *next = l->next;
l->marked = 0;
while (next && !next->marked) {
l->next = next->next;
next->next = frees;
frees = next;
next = l->next;
}
l = next;
}
return frees;
}
static void strmark (TaggedString *s)
{
if (!s->head.marked)
s->head.marked = 1;
}
static void protomark (TProtoFunc *f) {
if (!f->head.marked) {
int i;
f->head.marked = 1;
strmark(f->source);
for (i=0; i<f->nconsts; i++)
markobject(&f->consts[i]);
}
}
static void closuremark (Closure *f)
{
if (!f->head.marked) {
int i;
f->head.marked = 1;
for (i=f->nelems; i>=0; i--)
markobject(&f->consts[i]);
}
}
static void hashmark (Hash *h)
{
if (!h->head.marked) {
int i;
h->head.marked = 1;
for (i=0; i<nhash(h); i++) {
Node *n = node(h,i);
if (ttype(ref(n)) != LUA_T_NIL) {
markobject(&n->ref);
markobject(&n->val);
}
}
}
}
static void globalmark (void)
{
TaggedString *g;
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 */
}
}
}
static int markobject (TObject *o)
{
switch (ttype(o)) {
case LUA_T_USERDATA: case LUA_T_STRING:
strmark(tsvalue(o));
break;
case LUA_T_ARRAY:
hashmark(avalue(o));
break;
case LUA_T_CLOSURE: case LUA_T_CLMARK:
closuremark(o->value.cl);
break;
case LUA_T_PROTO: case LUA_T_PMARK:
protomark(o->value.tf);
break;
default: break; /* numbers, cprotos, etc */
}
return 0;
}
static void markall (void)
{
luaD_travstack(markobject); /* mark stack objects */
globalmark(); /* mark global variable values and names */
travlock(); /* mark locked objects */
luaT_travtagmethods(markobject); /* mark fallbacks */
}
long lua_collectgarbage (long limit)
{
unsigned long recovered = L->nblocks; /* to subtract nblocks after gc */
Hash *freetable;
TaggedString *freestr;
TProtoFunc *freefunc;
Closure *freeclos;
markall();
invalidaterefs();
freestr = luaS_collector();
freetable = (Hash *)listcollect(&(L->roottable));
freefunc = (TProtoFunc *)listcollect(&(L->rootproto));
freeclos = (Closure *)listcollect(&(L->rootcl));
L->GCthreshold *= 4; /* to avoid GC during GC */
luaC_hashcallIM(freetable); /* GC tag methods for tables */
luaC_strcallIM(freestr); /* GC tag methods for userdata */
luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
luaH_free(freetable);
luaS_free(freestr);
luaF_freeproto(freefunc);
luaF_freeclosure(freeclos);
recovered = recovered-L->nblocks;
L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
return recovered;
}
void luaC_checkGC (void)
{
if (L->nblocks >= L->GCthreshold)
lua_collectgarbage(0);
}

21
lgc.h
View File

@@ -1,21 +0,0 @@
/*
** $Id: lgc.h,v 1.3 1997/11/19 17:29:23 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
#ifndef lgc_h
#define lgc_h
#include "lobject.h"
void luaC_checkGC (void);
TObject* luaC_getref (int ref);
int luaC_ref (TObject *o, int lock);
void luaC_hashcallIM (Hash *l);
void luaC_strcallIM (TaggedString *l);
#endif

17
linit.c
View File

@@ -1,17 +0,0 @@
/*
** $Id: linit.c,v 1.1 1999/01/08 16:47:44 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/
#include "lua.h"
#include "lualib.h"
void lua_userinit (void) {
lua_iolibopen();
lua_strlibopen();
lua_mathlibopen();
lua_dblibopen();
}

583
liolib.c
View File

@@ -1,583 +0,0 @@
/*
** $Id: liolib.c,v 1.40 1999/05/14 12:24:04 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "lauxlib.h"
#include "lua.h"
#include "luadebug.h"
#include "lualib.h"
#ifndef OLD_ANSI
#include <locale.h>
#else
/* no support for locale and for strerror: fake them */
#define setlocale(a,b) 0
#define LC_ALL 0
#define LC_COLLATE 0
#define LC_CTYPE 0
#define LC_MONETARY 0
#define LC_NUMERIC 0
#define LC_TIME 0
#define strerror(e) "(no error message provided by operating system)"
#endif
#define IOTAG 1
#define FIRSTARG 2 /* 1st is upvalue */
#define CLOSEDTAG(tag) ((tag)-1) /* assume that CLOSEDTAG = iotag-1 */
#define FINPUT "_INPUT"
#define FOUTPUT "_OUTPUT"
#ifdef POPEN
FILE *popen();
int pclose();
#define CLOSEFILE(f) {if (pclose(f) == -1) fclose(f);}
#else
/* no support for popen */
#define popen(x,y) NULL /* that is, popen always fails */
#define CLOSEFILE(f) {fclose(f);}
#endif
static void pushresult (int i) {
if (i)
lua_pushuserdata(NULL);
else {
lua_pushnil();
lua_pushstring(strerror(errno));
lua_pushnumber(errno);
}
}
/*
** {======================================================
** FILE Operations
** =======================================================
*/
static int gettag (void) {
return (int)lua_getnumber(lua_getparam(IOTAG));
}
static int ishandle (lua_Object f) {
if (lua_isuserdata(f)) {
int tag = gettag();
if (lua_tag(f) == CLOSEDTAG(tag))
lua_error("cannot access a closed file");
return lua_tag(f) == tag;
}
else return 0;
}
static FILE *getfilebyname (char *name) {
lua_Object f = lua_getglobal(name);
if (!ishandle(f))
luaL_verror("global variable `%.50s' is not a file handle", name);
return lua_getuserdata(f);
}
static FILE *getfile (int arg) {
lua_Object f = lua_getparam(arg);
return (ishandle(f)) ? lua_getuserdata(f) : NULL;
}
static FILE *getnonullfile (int arg) {
FILE *f = getfile(arg);
luaL_arg_check(f, arg, "invalid file handle");
return f;
}
static FILE *getfileparam (char *name, int *arg) {
FILE *f = getfile(*arg);
if (f) {
(*arg)++;
return f;
}
else
return getfilebyname(name);
}
static void closefile (FILE *f) {
if (f != stdin && f != stdout) {
int tag = gettag();
CLOSEFILE(f);
lua_pushusertag(f, tag);
lua_settag(CLOSEDTAG(tag));
}
}
static void io_close (void) {
closefile(getnonullfile(FIRSTARG));
}
static void gc_close (void) {
FILE *f = getnonullfile(FIRSTARG);
if (f != stdin && f != stdout && f != stderr) {
CLOSEFILE(f);
}
}
static void io_open (void) {
FILE *f = fopen(luaL_check_string(FIRSTARG), luaL_check_string(FIRSTARG+1));
if (f) lua_pushusertag(f, gettag());
else pushresult(0);
}
static void setfile (FILE *f, char *name, int tag) {
lua_pushusertag(f, tag);
lua_setglobal(name);
}
static void setreturn (FILE *f, char *name) {
if (f == NULL)
pushresult(0);
else {
int tag = gettag();
setfile(f, name, tag);
lua_pushusertag(f, tag);
}
}
static void io_readfrom (void) {
FILE *current;
lua_Object f = lua_getparam(FIRSTARG);
if (f == LUA_NOOBJECT) {
closefile(getfilebyname(FINPUT));
current = stdin;
}
else if (lua_tag(f) == gettag()) /* deprecated option */
current = lua_getuserdata(f);
else {
char *s = luaL_check_string(FIRSTARG);
current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
}
setreturn(current, FINPUT);
}
static void io_writeto (void) {
FILE *current;
lua_Object f = lua_getparam(FIRSTARG);
if (f == LUA_NOOBJECT) {
closefile(getfilebyname(FOUTPUT));
current = stdout;
}
else if (lua_tag(f) == gettag()) /* deprecated option */
current = lua_getuserdata(f);
else {
char *s = luaL_check_string(FIRSTARG);
current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w");
}
setreturn(current, FOUTPUT);
}
static void io_appendto (void) {
FILE *current = fopen(luaL_check_string(FIRSTARG), "a");
setreturn(current, FOUTPUT);
}
/*
** {======================================================
** READ
** =======================================================
*/
/*
** We cannot lookahead without need, because this can lock stdin.
** This flag signals when we need to read a next char.
*/
#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
static int read_pattern (FILE *f, char *p) {
int inskip = 0; /* {skip} level */
int c = NEED_OTHER;
while (*p != '\0') {
switch (*p) {
case '{':
inskip++;
p++;
continue;
case '}':
if (!inskip) lua_error("unbalanced braces in read pattern");
inskip--;
p++;
continue;
default: {
char *ep = luaI_classend(p); /* get what is next */
int m; /* match result */
if (c == NEED_OTHER) c = getc(f);
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
if (m) {
if (!inskip) luaL_addchar(c);
c = NEED_OTHER;
}
switch (*ep) {
case '+': /* repetition (1 or more) */
if (!m) goto break_while; /* pattern fails? */
/* else go through */
case '*': /* repetition (0 or more) */
while (m) { /* reads the same item until it fails */
c = getc(f);
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
if (m && !inskip) luaL_addchar(c);
}
/* go through to continue reading the pattern */
case '?': /* optional */
p = ep+1; /* continues reading the pattern */
continue;
default:
if (!m) goto break_while; /* pattern fails? */
p = ep; /* else continues reading the pattern */
}
}
}
} break_while:
if (c != NEED_OTHER) ungetc(c, f);
return (*p == '\0');
}
static int read_number (FILE *f) {
double d;
if (fscanf(f, "%lf", &d) == 1) {
lua_pushnumber(d);
return 1;
}
else return 0; /* read fails */
}
#define HUNK_LINE 1024
#define HUNK_FILE BUFSIZ
static int read_line (FILE *f) {
/* equivalent to: return read_pattern(f, "[^\n]*{\n}"); */
int n;
char *b;
do {
b = luaL_openspace(HUNK_LINE);
if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */
n = strlen(b);
luaL_addsize(n);
} while (b[n-1] != '\n');
luaL_addsize(-1); /* remove '\n' */
return 1;
}
static void read_file (FILE *f) {
/* equivalent to: return read_pattern(f, ".*"); */
int n;
do {
char *b = luaL_openspace(HUNK_FILE);
n = fread(b, sizeof(char), HUNK_FILE, f);
luaL_addsize(n);
} while (n==HUNK_FILE);
}
static void io_read (void) {
static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL};
int arg = FIRSTARG;
FILE *f = getfileparam(FINPUT, &arg);
char *p = luaL_opt_string(arg++, "*l");
do { /* repeat for each part */
long l;
int success;
luaL_resetbuffer();
switch (luaL_findstring(p, options)) {
case 0: /* number */
if (!read_number(f)) return; /* read fails */
continue; /* number is already pushed; avoid the "pushstring" */
case 1: /* line */
success = read_line(f);
break;
case 2: case 3: /* file */
read_file(f);
success = 1; /* always success */
break;
case 4: /* word */
success = read_pattern(f, "{%s*}%S+");
break;
default:
success = read_pattern(f, p);
}
l = luaL_getsize();
if (!success && l==0) return; /* read fails */
lua_pushlstring(luaL_buffer(), l);
} while ((p = luaL_opt_string(arg++, NULL)) != NULL);
}
/* }====================================================== */
static void io_write (void) {
int arg = FIRSTARG;
FILE *f = getfileparam(FOUTPUT, &arg);
int status = 1;
char *s;
long l;
while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL)
status = status && ((long)fwrite(s, 1, l, f) == l);
pushresult(status);
}
static void io_seek (void) {
static int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static char *modenames[] = {"set", "cur", "end", NULL};
FILE *f = getnonullfile(FIRSTARG);
int op = luaL_findstring(luaL_opt_string(FIRSTARG+1, "cur"), modenames);
long offset = luaL_opt_long(FIRSTARG+2, 0);
luaL_arg_check(op != -1, FIRSTARG+1, "invalid mode");
op = fseek(f, offset, mode[op]);
if (op)
pushresult(0); /* error */
else
lua_pushnumber(ftell(f));
}
static void io_flush (void) {
FILE *f = getfile(FIRSTARG);
luaL_arg_check(f || lua_getparam(FIRSTARG) == LUA_NOOBJECT, FIRSTARG,
"invalid file handle");
pushresult(fflush(f) == 0);
}
/* }====================================================== */
/*
** {======================================================
** Other O.S. Operations
** =======================================================
*/
static void io_execute (void) {
lua_pushnumber(system(luaL_check_string(1)));
}
static void io_remove (void) {
pushresult(remove(luaL_check_string(1)) == 0);
}
static void io_rename (void) {
pushresult(rename(luaL_check_string(1),
luaL_check_string(2)) == 0);
}
static void io_tmpname (void) {
lua_pushstring(tmpnam(NULL));
}
static void io_getenv (void) {
lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
}
static void io_clock (void) {
lua_pushnumber(((double)clock())/CLOCKS_PER_SEC);
}
static void io_date (void) {
char b[256];
char *s = luaL_opt_string(1, "%c");
struct tm *tm;
time_t t;
time(&t); tm = localtime(&t);
if (strftime(b,sizeof(b),s,tm))
lua_pushstring(b);
else
lua_error("invalid `date' format");
}
static void setloc (void) {
static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC,
LC_TIME};
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)));
}
static void io_exit (void) {
lua_Object o = lua_getparam(1);
exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
}
/* }====================================================== */
static void io_debug (void) {
for (;;) {
char buffer[250];
fprintf(stderr, "lua_debug> ");
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
strcmp(buffer, "cont\n") == 0)
return;
lua_dostring(buffer);
}
}
#define MESSAGESIZE 150
#define MAXMESSAGE (MESSAGESIZE*10)
#define MAXSRC 60
static void errorfb (void) {
char buff[MAXMESSAGE];
int level = 1; /* skip level 0 (it's this function) */
lua_Object func;
sprintf(buff, "lua error: %.200s\n", lua_getstring(lua_getparam(1)));
while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
char *name;
int currentline;
char *chunkname;
char buffchunk[MAXSRC];
int linedefined;
lua_funcinfo(func, &chunkname, &linedefined);
luaL_chunkid(buffchunk, chunkname, sizeof(buffchunk));
if (level == 2) strcat(buff, "Active Stack:\n");
strcat(buff, " ");
if (strlen(buff) > MAXMESSAGE-MESSAGESIZE) {
strcat(buff, "...\n");
break; /* buffer is full */
}
switch (*lua_getobjname(func, &name)) {
case 'g':
sprintf(buff+strlen(buff), "function `%.50s'", name);
break;
case 't':
sprintf(buff+strlen(buff), "`%.50s' tag method", name);
break;
default: {
if (linedefined == 0)
sprintf(buff+strlen(buff), "main of %.70s", buffchunk);
else if (linedefined < 0)
sprintf(buff+strlen(buff), "%.70s", buffchunk);
else
sprintf(buff+strlen(buff), "function <%d:%.70s>",
linedefined, buffchunk);
chunkname = NULL;
}
}
if ((currentline = lua_currentline(func)) > 0)
sprintf(buff+strlen(buff), " at line %d", currentline);
if (chunkname)
sprintf(buff+strlen(buff), " [%.70s]", buffchunk);
strcat(buff, "\n");
}
func = lua_rawgetglobal("_ALERT");
if (lua_isfunction(func)) { /* avoid error loop if _ALERT is not defined */
lua_pushstring(buff);
lua_callfunction(func);
}
}
static struct luaL_reg iolib[] = {
{"_ERRORMESSAGE", errorfb},
{"clock", io_clock},
{"date", io_date},
{"debug", io_debug},
{"execute", io_execute},
{"exit", io_exit},
{"getenv", io_getenv},
{"remove", io_remove},
{"rename", io_rename},
{"setlocale", setloc},
{"tmpname", io_tmpname}
};
static struct luaL_reg iolibtag[] = {
{"appendto", io_appendto},
{"closefile", io_close},
{"flush", io_flush},
{"openfile", io_open},
{"read", io_read},
{"readfrom", io_readfrom},
{"seek", io_seek},
{"write", io_write},
{"writeto", io_writeto}
};
static void openwithtags (void) {
int i;
int iotag = lua_newtag();
lua_newtag(); /* alloc CLOSEDTAG: assume that CLOSEDTAG = iotag-1 */
for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) {
/* put iotag as upvalue for these functions */
lua_pushnumber(iotag);
lua_pushcclosure(iolibtag[i].func, 1);
lua_setglobal(iolibtag[i].name);
}
/* predefined file handles */
setfile(stdin, FINPUT, iotag);
setfile(stdout, FOUTPUT, iotag);
setfile(stdin, "_STDIN", iotag);
setfile(stdout, "_STDOUT", iotag);
setfile(stderr, "_STDERR", iotag);
/* close file when collected */
lua_pushnumber(iotag);
lua_pushcclosure(gc_close, 1);
lua_settagmethod(iotag, "gc");
}
void lua_iolibopen (void) {
/* register lib functions */
luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
openwithtags();
}

437
llex.c
View File

@@ -1,437 +0,0 @@
/*
** $Id: llex.c,v 1.35 1999/05/14 12:24:04 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <string.h>
#include "lauxlib.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "luadebug.h"
#include "lzio.h"
#define next(LS) (LS->current = zgetc(LS->lex_z))
#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]);
ts->head.marked = FIRST_RESERVED+i; /* reserved word (always > 255) */
}
}
#define MAXSRC 80
void luaX_syntaxerror (LexState *ls, char *s, char *token) {
char buff[MAXSRC];
luaL_chunkid(buff, zname(ls->lex_z), sizeof(buff));
if (token[0] == '\0')
token = "<eof>";
luaL_verror("%.100s;\n last token read: `%.50s' at line %d in %.80s",
s, token, ls->linenumber, buff);
}
void luaX_error (LexState *ls, char *s) {
save('\0');
luaX_syntaxerror(ls, s, luaL_buffer());
}
void luaX_token2str (int token, char *s) {
if (token < 255) {
s[0] = (char)token;
s[1] = '\0';
}
else
strcpy(s, reserved[token-FIRST_RESERVED]);
}
static void luaX_invalidchar (LexState *ls, int c) {
char buff[8];
sprintf(buff, "0x%02X", c);
luaX_syntaxerror(ls, "invalid control char", buff);
}
static void firstline (LexState *LS)
{
int c = zgetc(LS->lex_z);
if (c == '#')
while ((c=zgetc(LS->lex_z)) != '\n' && c != EOZ) /* skip first line */;
zungetc(LS->lex_z);
}
void luaX_setinput (LexState *LS, ZIO *z)
{
LS->current = '\n';
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();
}
/*
** =======================================================
** PRAGMAS
** =======================================================
*/
#ifndef PRAGMASIZE
#define PRAGMASIZE 80 /* arbitrary limit */
#endif
static void skipspace (LexState *LS) {
while (LS->current == ' ' || LS->current == '\t' || LS->current == '\r')
next(LS);
}
static int checkcond (LexState *LS, char *buff) {
static char *opts[] = {"nil", "1", NULL};
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 {
luaX_syntaxerror(LS, "invalid $if condition", buff);
return 0; /* to avoid warnings */
}
}
static void readname (LexState *LS, char *buff) {
int i = 0;
skipspace(LS);
while (isalnum(LS->current) || LS->current == '_') {
if (i >= PRAGMASIZE) {
buff[PRAGMASIZE] = 0;
luaX_syntaxerror(LS, "pragma too long", buff);
}
buff[i++] = (char)LS->current;
next(LS);
}
buff[i] = 0;
}
static void inclinenumber (LexState *LS);
static void ifskip (LexState *LS) {
while (LS->ifstate[LS->iflevel].skip) {
if (LS->current == '\n')
inclinenumber(LS);
else if (LS->current == EOZ)
luaX_error(LS, "input ends inside a $if");
else next(LS);
}
}
static void inclinenumber (LexState *LS) {
static char *pragmas [] =
{"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL};
next(LS); /* skip '\n' */
++LS->linenumber;
if (LS->current == '$') { /* is a pragma? */
char buff[PRAGMASIZE+1];
int ifnot = 0;
int skip = LS->ifstate[LS->iflevel].skip;
next(LS); /* skip $ */
readname(LS, buff);
switch (luaL_findstring(buff, pragmas)) {
case 0: /* debug */
if (!skip) L->debug = 1;
break;
case 1: /* nodebug */
if (!skip) L->debug = 0;
break;
case 2: /* endinput */
if (!skip) {
LS->current = EOZ;
LS->iflevel = 0; /* to allow $endinput inside a $if */
}
break;
case 3: /* end */
if (LS->iflevel-- == 0)
luaX_syntaxerror(LS, "unmatched $end", "$end");
break;
case 4: /* ifnot */
ifnot = 1;
/* go through */
case 5: /* if */
if (LS->iflevel == MAX_IFS-1)
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(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)
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:
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 */
luaX_syntaxerror(LS, "invalid pragma format", buff);
ifskip(LS);
}
}
/*
** =======================================================
** LEXICAL ANALIZER
** =======================================================
*/
static int read_long_string (LexState *LS) {
int cont = 0;
for (;;) {
switch (LS->current) {
case EOZ:
luaX_error(LS, "unfinished long string");
return EOS; /* to avoid warnings */
case '[':
save_and_next(LS);
if (LS->current == '[') {
cont++;
save_and_next(LS);
}
continue;
case ']':
save_and_next(LS);
if (LS->current == ']') {
if (cont == 0) goto endloop;
cont--;
save_and_next(LS);
}
continue;
case '\n':
save('\n');
inclinenumber(LS);
continue;
default:
save_and_next(LS);
}
} endloop:
save_and_next(LS); /* skip the second ']' */
LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+2),
L->Mbuffnext-L->Mbuffbase-4);
return STRING;
}
int luaX_lex (LexState *LS) {
luaL_resetbuffer();
for (;;) {
switch (LS->current) {
case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
next(LS);
continue;
case '\n':
inclinenumber(LS);
continue;
case '-':
save_and_next(LS);
if (LS->current != '-') return '-';
do { next(LS); } while (LS->current != '\n' && LS->current != EOZ);
luaL_resetbuffer();
continue;
case '[':
save_and_next(LS);
if (LS->current != '[') return '[';
else {
save_and_next(LS); /* pass the second '[' */
return read_long_string(LS);
}
case '=':
save_and_next(LS);
if (LS->current != '=') return '=';
else { save_and_next(LS); return EQ; }
case '<':
save_and_next(LS);
if (LS->current != '=') return '<';
else { save_and_next(LS); return LE; }
case '>':
save_and_next(LS);
if (LS->current != '=') return '>';
else { save_and_next(LS); return GE; }
case '~':
save_and_next(LS);
if (LS->current != '=') return '~';
else { save_and_next(LS); return NE; }
case '"':
case '\'': {
int del = LS->current;
save_and_next(LS);
while (LS->current != del) {
switch (LS->current) {
case EOZ:
case '\n':
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 '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 : {
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 != (unsigned char)c)
luaX_error(LS, "escape sequence too large");
save(c);
}
else { /* handles \, ", ', and ? */
save(LS->current);
next(LS);
}
break;
}
}
break;
default:
save_and_next(LS);
}
}
save_and_next(LS); /* skip delimiter */
LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+1),
L->Mbuffnext-L->Mbuffbase-2);
return STRING;
}
case '.':
save_and_next(LS);
if (LS->current == '.')
{
save_and_next(LS);
if (LS->current == '.')
{
save_and_next(LS);
return DOTS; /* ... */
}
else return CONC; /* .. */
}
else if (!isdigit(LS->current)) return '.';
goto fraction; /* LS->current is a digit: goes through to number */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
do {
save_and_next(LS);
} while (isdigit(LS->current));
if (LS->current == '.') {
save_and_next(LS);
if (LS->current == '.') {
save('.');
luaX_error(LS,
"ambiguous syntax (decimal point x string concatenation)");
}
}
fraction:
while (isdigit(LS->current))
save_and_next(LS);
if (toupper(LS->current) == 'E') {
save_and_next(LS); /* read 'E' */
save_and_next(LS); /* read '+', '-' or first digit */
while (isdigit(LS->current))
save_and_next(LS);
}
save('\0');
LS->seminfo.r = luaO_str2d(L->Mbuffer+L->Mbuffbase);
if (LS->seminfo.r < 0)
luaX_error(LS, "invalid numeric format");
return NUMBER;
case EOZ:
if (LS->iflevel > 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;
}
else { /* identifier or reserved word */
TaggedString *ts;
do {
save_and_next(LS);
} while (isalnum(LS->current) || LS->current == '_');
save('\0');
ts = luaS_new(L->Mbuffer+L->Mbuffbase);
if (ts->head.marked >= FIRST_RESERVED)
return ts->head.marked; /* reserved word */
LS->seminfo.ts = ts;
return NAME;
}
}
}
}

64
llex.h
View File

@@ -1,64 +0,0 @@
/*
** $Id: llex.h,v 1.11 1999/02/25 19:13:56 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
#ifndef llex_h
#define llex_h
#include "lobject.h"
#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};
#ifndef MAX_IFS
#define MAX_IFS 5 /* arbitrary limit */
#endif
/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
struct ifState {
int elsepart; /* true if it's in the $else part */
int condition; /* true if $if condition is true */
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 iflevel; /* level of nested $if's (for lexical analysis) */
struct ifState ifstate[MAX_IFS];
} LexState;
void luaX_init (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 (int token, char *s);
#endif

View File

@@ -1,203 +0,0 @@
/*
** $Id: lmathlib.c,v 1.16 1999/02/19 17:33:35 roberto Exp roberto $
** Lua standard mathematical library
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <math.h>
#include "lauxlib.h"
#include "lua.h"
#include "lualib.h"
#undef PI
#define PI (3.14159265358979323846)
#define RADIANS_PER_DEGREE (PI/180.0)
/*
** If you want Lua to operate in radians (instead of degrees),
** define RADIANS
*/
#ifdef RADIANS
#define FROMRAD(a) (a)
#define TORAD(a) (a)
#else
#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
#define TORAD(a) ((a)*RADIANS_PER_DEGREE)
#endif
static void math_abs (void) {
lua_pushnumber(fabs(luaL_check_number(1)));
}
static void math_sin (void) {
lua_pushnumber(sin(TORAD(luaL_check_number(1))));
}
static void math_cos (void) {
lua_pushnumber(cos(TORAD(luaL_check_number(1))));
}
static void math_tan (void) {
lua_pushnumber(tan(TORAD(luaL_check_number(1))));
}
static void math_asin (void) {
lua_pushnumber(FROMRAD(asin(luaL_check_number(1))));
}
static void math_acos (void) {
lua_pushnumber(FROMRAD(acos(luaL_check_number(1))));
}
static void math_atan (void) {
lua_pushnumber(FROMRAD(atan(luaL_check_number(1))));
}
static void math_atan2 (void) {
lua_pushnumber(FROMRAD(atan2(luaL_check_number(1), luaL_check_number(2))));
}
static void math_ceil (void) {
lua_pushnumber(ceil(luaL_check_number(1)));
}
static void math_floor (void) {
lua_pushnumber(floor(luaL_check_number(1)));
}
static void math_mod (void) {
lua_pushnumber(fmod(luaL_check_number(1), luaL_check_number(2)));
}
static void math_sqrt (void) {
lua_pushnumber(sqrt(luaL_check_number(1)));
}
static void math_pow (void) {
lua_pushnumber(pow(luaL_check_number(1), luaL_check_number(2)));
}
static void math_log (void) {
lua_pushnumber(log(luaL_check_number(1)));
}
static void math_log10 (void) {
lua_pushnumber(log10(luaL_check_number(1)));
}
static void math_exp (void) {
lua_pushnumber(exp(luaL_check_number(1)));
}
static void math_deg (void) {
lua_pushnumber(luaL_check_number(1)/RADIANS_PER_DEGREE);
}
static void math_rad (void) {
lua_pushnumber(luaL_check_number(1)*RADIANS_PER_DEGREE);
}
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_int(2)));
}
static void math_min (void) {
int i = 1;
double dmin = luaL_check_number(i);
while (lua_getparam(++i) != LUA_NOOBJECT) {
double d = luaL_check_number(i);
if (d < dmin)
dmin = d;
}
lua_pushnumber(dmin);
}
static void math_max (void) {
int i = 1;
double dmax = luaL_check_number(i);
while (lua_getparam(++i) != LUA_NOOBJECT) {
double d = luaL_check_number(i);
if (d > dmax)
dmax = d;
}
lua_pushnumber(dmax);
}
static void math_random (void) {
/* the '%' avoids the (rare) case of r==1, and is needed also because on
some systems (SunOS!) "rand()" may return a value bigger than RAND_MAX */
double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
int l = luaL_opt_int(1, 0);
if (l == 0)
lua_pushnumber(r);
else {
int u = luaL_opt_int(2, 0);
if (u == 0) {
u = l;
l = 1;
}
luaL_arg_check(l<=u, 1, "interval is empty");
lua_pushnumber((int)(r*(u-l+1))+l);
}
}
static void math_randomseed (void) {
srand(luaL_check_int(1));
}
static struct luaL_reg mathlib[] = {
{"abs", math_abs},
{"sin", math_sin},
{"cos", math_cos},
{"tan", math_tan},
{"asin", math_asin},
{"acos", math_acos},
{"atan", math_atan},
{"atan2", math_atan2},
{"ceil", math_ceil},
{"floor", math_floor},
{"mod", math_mod},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
{"sqrt", math_sqrt},
{"min", math_min},
{"max", math_max},
{"log", math_log},
{"log10", math_log10},
{"exp", math_exp},
{"deg", math_deg},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed}
};
/*
** Open math library
*/
void lua_mathlibopen (void) {
luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
lua_pushcfunction(math_pow);
lua_pushnumber(0); /* to get its tag */
lua_settagmethod(lua_tag(lua_pop()), "pow");
lua_pushnumber(PI); lua_setglobal("PI");
}

140
lmem.c
View File

@@ -1,140 +0,0 @@
/*
** $Id: lmem.c,v 1.16 1999/05/20 20:43:06 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include "lmem.h"
#include "lstate.h"
#include "lua.h"
/*
** real ANSI systems do not need these tests;
** but some systems (Sun OS) are not that ANSI...
*/
#ifdef OLD_ANSI
#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
#define free(b) if (b) (free)(b)
#endif
#define MINSIZE 8 /* minimum size for "growing" vectors */
static unsigned long power2 (unsigned long n) {
unsigned long p = MINSIZE;
while (p<=n) p<<=1;
return p;
}
void *luaM_growaux (void *block, unsigned long nelems, int inc, int size,
char *errormsg, unsigned long limit) {
unsigned long newn = nelems+inc;
if (newn >= limit) lua_error(errormsg);
if ((newn ^ nelems) <= nelems || /* still the same power of 2 limit? */
(nelems > 0 && newn < MINSIZE)) /* or block already is MINSIZE? */
return block; /* do not need to reallocate */
else /* it crossed a power of 2 boundary; grow to next power */
return luaM_realloc(block, power2(newn)*size);
}
#ifndef DEBUG
/*
** generic allocation routine.
*/
void *luaM_realloc (void *block, unsigned long size) {
size_t s = (size_t)size;
if (s != size)
lua_error("memory allocation error: block too big");
if (size == 0) {
free(block); /* block may be NULL, that is OK for free */
return NULL;
}
block = realloc(block, s);
if (block == NULL)
lua_error(memEM);
return block;
}
#else
/* DEBUG */
#include <string.h>
#define HEADER (sizeof(double))
#define MARKSIZE 16
#define MARK 55
#define blocksize(b) ((unsigned long *)((char *)(b) - HEADER))
unsigned long numblocks = 0;
unsigned long totalmem = 0;
static void *checkblock (void *block) {
if (block == NULL)
return NULL;
else {
unsigned long *b = blocksize(block);
unsigned long size = *b;
int i;
for (i=0;i<MARKSIZE;i++)
LUA_ASSERT(*(((char *)b)+HEADER+size+i) == MARK+i, "corrupted block");
numblocks--;
totalmem -= size;
return b;
}
}
static void freeblock (void *block) {
if (block)
memset(block, -1, *blocksize(block)); /* erase block */
free(checkblock(block));
}
void *luaM_realloc (void *block, unsigned long size) {
unsigned long realsize = HEADER+size+MARKSIZE;
if (realsize != (size_t)realsize)
lua_error("memory allocation error: block too big");
if (size == 0) {
freeblock(block);
return NULL;
}
else {
char *newblock = malloc(realsize);
int i;
if (block) {
unsigned long oldsize = *blocksize(block);
if (oldsize > size) oldsize = size;
memcpy(newblock+HEADER, block, oldsize);
freeblock(block); /* erase (and check) old copy */
}
if (newblock == NULL)
lua_error(memEM);
totalmem += size;
numblocks++;
*(unsigned long *)newblock = size;
for (i=0;i<MARKSIZE;i++)
*(newblock+HEADER+size+i) = MARK+i;
return newblock+HEADER;
}
}
#endif

41
lmem.h
View File

@@ -1,41 +0,0 @@
/*
** $Id: lmem.h,v 1.7 1999/02/25 15:16:26 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#ifndef lmem_h
#define lmem_h
#include <stdlib.h>
/* memory error messages */
#define codeEM "code size overflow"
#define constantEM "constant table overflow"
#define refEM "reference table overflow"
#define tableEM "table overflow"
#define memEM "not enough memory"
#define arrEM "internal array bigger than `int' limit"
void *luaM_realloc (void *oldblock, unsigned long size);
void *luaM_growaux (void *block, unsigned long nelems, int inc, int size,
char *errormsg, unsigned long limit);
#define luaM_free(b) luaM_realloc((b), 0)
#define luaM_malloc(t) luaM_realloc(NULL, (t))
#define luaM_new(t) ((t *)luaM_malloc(sizeof(t)))
#define luaM_newvector(n,t) ((t *)luaM_malloc((n)*sizeof(t)))
#define luaM_growvector(v,nelems,inc,t,e,l) \
((v)=(t *)luaM_growaux(v,nelems,inc,sizeof(t),e,l))
#define luaM_reallocvector(v,n,t) ((v)=(t *)luaM_realloc(v,(n)*sizeof(t)))
#ifdef DEBUG
extern unsigned long numblocks;
extern unsigned long totalmem;
#endif
#endif

129
lobject.c
View File

@@ -1,129 +0,0 @@
/*
** $Id: lobject.c,v 1.18 1999/02/26 15:48:30 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdlib.h>
#include "lobject.h"
#include "lua.h"
char *luaO_typenames[] = { /* ORDER LUA_T */
"userdata", "number", "string", "table", "function", "function",
"nil", "function", "mark", "mark", "mark", "line", NULL
};
TObject luaO_nilobject = {LUA_T_NIL, {NULL}};
/* hash dimensions values */
static long dimensions[] =
{5L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L,
12853L, 25717L, 51437L, 102811L, 205619L, 411233L, 822433L,
1644817L, 3289613L, 6579211L, 13158023L, MAX_INT};
int luaO_redimension (int oldsize)
{
int i;
for (i=0; dimensions[i]<MAX_INT; i++) {
if (dimensions[i] > oldsize)
return dimensions[i];
}
lua_error("tableEM");
return 0; /* to avoid warnings */
}
int luaO_equalval (TObject *t1, TObject *t2) {
switch (ttype(t1)) {
case LUA_T_NIL: return 1;
case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2);
case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
case LUA_T_PROTO: return tfvalue(t1) == tfvalue(t2);
case LUA_T_CPROTO: return fvalue(t1) == fvalue(t2);
case LUA_T_CLOSURE: return t1->value.cl == t2->value.cl;
default:
LUA_INTERNALERROR("invalid type");
return 0; /* UNREACHABLE */
}
}
void luaO_insertlist (GCnode *root, GCnode *node)
{
node->next = root->next;
root->next = node;
node->marked = 0;
}
#ifdef OLD_ANSI
void luaO_memup (void *dest, void *src, int size) {
while (size--)
((char *)dest)[size]=((char *)src)[size];
}
void luaO_memdown (void *dest, void *src, int size) {
int i;
for (i=0; i<size; i++)
((char *)dest)[i]=((char *)src)[i];
}
#endif
static double expten (unsigned int e) {
double exp = 10.0;
double res = 1.0;
for (; e; e>>=1) {
if (e & 1) res *= exp;
exp *= exp;
}
return res;
}
double luaO_str2d (char *s) { /* LUA_NUMBER */
double a = 0.0;
int point = 0;
while (isdigit((unsigned char)*s)) {
a = 10.0*a + (*(s++)-'0');
}
if (*s == '.') {
s++;
while (isdigit((unsigned char)*s)) {
a = 10.0*a + (*(s++)-'0');
point++;
}
}
if (toupper((unsigned char)*s) == 'E') {
int e = 0;
int sig = 1;
s++;
if (*s == '-') {
s++;
sig = -1;
}
else if (*s == '+') s++;
if (!isdigit((unsigned char)*s)) return -1; /* no digit in the exponent? */
do {
e = 10*e + (*(s++)-'0');
} while (isdigit((unsigned char)*s));
point -= sig*e;
}
while (isspace((unsigned char)*s)) s++;
if (*s != '\0') return -1; /* invalid trailing characters? */
if (point > 0)
a /= expten(point);
else if (point < 0)
a *= expten(-point);
return a;
}

204
lobject.h
View File

@@ -1,204 +0,0 @@
/*
** $Id: lobject.h,v 1.27 1999/03/04 21:17:26 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
#ifndef lobject_h
#define lobject_h
#include <limits.h>
#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 LUA_NUM_TYPE
#define LUA_NUM_TYPE double
#endif
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_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */
/*
** Lua TYPES
** WARNING: if you change the order of this enumeration,
** grep "ORDER LUA_T"
*/
typedef enum {
LUA_T_USERDATA = 0, /* tag default for userdata */
LUA_T_NUMBER = -1, /* fixed tag for numbers */
LUA_T_STRING = -2, /* fixed tag for strings */
LUA_T_ARRAY = -3, /* tag default for tables (or arrays) */
LUA_T_PROTO = -4, /* fixed tag for functions */
LUA_T_CPROTO = -5, /* fixed tag for Cfunctions */
LUA_T_NIL = -6, /* last "pre-defined" tag */
LUA_T_CLOSURE = -7,
LUA_T_CLMARK = -8, /* mark for closures */
LUA_T_PMARK = -9, /* mark for Lua prototypes */
LUA_T_CMARK = -10, /* mark for C prototypes */
LUA_T_LINE = -11
} lua_Type;
#define NUM_TAGS 7
typedef union {
lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */
real n; /* LUA_T_NUMBER */
struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */
struct TProtoFunc *tf; /* LUA_T_PROTO, LUA_T_PMARK */
struct Closure *cl; /* LUA_T_CLOSURE, LUA_T_CLMARK */
struct Hash *a; /* LUA_T_ARRAY */
int i; /* LUA_T_LINE */
} Value;
typedef struct TObject {
lua_Type ttype;
Value value;
} TObject;
/*
** generic header for garbage collector lists
*/
typedef struct GCnode {
struct GCnode *next;
int marked;
} GCnode;
/*
** String headers for string table
*/
typedef struct TaggedString {
GCnode head;
unsigned long hash;
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
union {
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 */
} d;
} u;
char str[1]; /* \0 byte already reserved */
} TaggedString;
/*
** Function Prototypes
*/
typedef struct TProtoFunc {
GCnode head;
struct TObject *consts;
int nconsts;
Byte *code; /* ends with opcode ENDCODE */
int lineDefined;
TaggedString *source;
struct LocVar *locvars; /* ends with line = -1 */
} TProtoFunc;
typedef struct LocVar {
TaggedString *varname; /* NULL signals end of scope */
int line;
} LocVar;
/* Macros to access structure members */
#define ttype(o) ((o)->ttype)
#define nvalue(o) ((o)->value.n)
#define svalue(o) ((o)->value.ts->str)
#define tsvalue(o) ((o)->value.ts)
#define clvalue(o) ((o)->value.cl)
#define avalue(o) ((o)->value.a)
#define fvalue(o) ((o)->value.f)
#define tfvalue(o) ((o)->value.tf)
#define protovalue(o) ((o)->value.cl->consts)
/*
** Closures
*/
typedef struct Closure {
GCnode head;
int nelems; /* not included the first one (always the prototype) */
TObject consts[1]; /* at least one for prototype */
} Closure;
typedef struct node {
TObject ref;
TObject val;
} Node;
typedef struct Hash {
GCnode head;
Node *node;
int nhash;
int nuse;
int htag;
} Hash;
extern char *luaO_typenames[];
#define luaO_typename(o) luaO_typenames[-ttype(o)]
extern TObject luaO_nilobject;
#define luaO_equalObj(t1,t2) ((ttype(t1) != ttype(t2)) ? 0 \
: luaO_equalval(t1,t2))
int luaO_equalval (TObject *t1, TObject *t2);
int luaO_redimension (int oldsize);
void luaO_insertlist (GCnode *root, GCnode *node);
double luaO_str2d (char *s);
#ifdef OLD_ANSI
void luaO_memup (void *dest, void *src, int size);
void luaO_memdown (void *dest, void *src, int size);
#else
#include <string.h>
#define luaO_memup(d,s,n) memmove(d,s,n)
#define luaO_memdown(d,s,n) memmove(d,s,n)
#endif
#endif

View File

@@ -1,138 +0,0 @@
/*
** $Id: lopcodes.h,v 1.32 1999/03/10 14:09:45 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
#ifndef lopcodes_h
#define lopcodes_h
/*
** NOTICE: variants of the same opcode must be consecutive: First, those
** with word parameter, then with byte parameter.
*/
typedef enum {
/* name parm before after side effect
-----------------------------------------------------------------------------*/
ENDCODE,/* - - (return) */
RETCODE,/* b - (return) */
CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
TAILCALL,/* b c v_c...v_1 f (return) f(v1,...,v_c) */
PUSHNIL,/* b - nil_0...nil_b */
POP,/* b a_b...a_1 - */
PUSHNUMBERW,/* w - (float)w */
PUSHNUMBER,/* b - (float)b */
PUSHNUMBERNEGW,/* w - (float)-w */
PUSHNUMBERNEG,/* b - (float)-b */
PUSHCONSTANTW,/*w - CNST[w] */
PUSHCONSTANT,/* b - CNST[b] */
PUSHUPVALUE,/* b - Closure[b] */
PUSHLOCAL,/* b - LOC[b] */
GETGLOBALW,/* w - VAR[CNST[w]] */
GETGLOBAL,/* b - VAR[CNST[b]] */
GETTABLE,/* - i t t[i] */
GETDOTTEDW,/* w t t[CNST[w]] */
GETDOTTED,/* b t t[CNST[b]] */
PUSHSELFW,/* w t t t[CNST[w]] */
PUSHSELF,/* b t t t[CNST[b]] */
CREATEARRAYW,/* w - newarray(size = w) */
CREATEARRAY,/* b - newarray(size = b) */
SETLOCAL,/* b x - LOC[b]=x */
SETGLOBALW,/* w x - VAR[CNST[w]]=x */
SETGLOBAL,/* b x - VAR[CNST[b]]=x */
SETTABLEPOP,/* - v i t - t[i]=v */
SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
SETLISTW,/* w c v_c...v_1 t t t[i+w*FPF]=v_i */
SETLIST,/* b c v_c...v_1 t t t[i+b*FPF]=v_i */
SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */
NEQOP,/* - y x (x~=y)? 1 : nil */
EQOP,/* - y x (x==y)? 1 : nil */
LTOP,/* - y x (x<y)? 1 : nil */
LEOP,/* - y x (x<y)? 1 : nil */
GTOP,/* - y x (x>y)? 1 : nil */
GEOP,/* - y x (x>=y)? 1 : nil */
ADDOP,/* - y x x+y */
SUBOP,/* - y x x-y */
MULTOP,/* - y x x*y */
DIVOP,/* - y x x/y */
POWOP,/* - y x x^y */
CONCOP,/* - y x x..y */
MINUSOP,/* - x -x */
NOTOP,/* - x (x==nil)? 1 : nil */
ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */
ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */
ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */
ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */
JMPW,/* w - - PC+=w */
JMP,/* b - - PC+=b */
IFFJMPW,/* w x - (x==nil)? PC+=w */
IFFJMP,/* b x - (x==nil)? PC+=b */
IFTUPJMPW,/* w x - (x!=nil)? PC-=w */
IFTUPJMP,/* b x - (x!=nil)? PC-=b */
IFFUPJMPW,/* w x - (x==nil)? PC-=w */
IFFUPJMP,/* b x - (x==nil)? PC-=b */
CLOSUREW,/* w c v_c...v_1 closure(CNST[w], v_c...v_1) */
CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
SETLINEW,/* w - - LINE=w */
SETLINE,/* b - - LINE=b */
LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */
LONGARG,/* b (add b*(1<<16) to arg of next instruction) */
CHECKSTACK /* b (assert #temporaries == b; only for internal debuging!) */
} OpCode;
#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */
#define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) */
#define ZEROVARARG 128
/* maximum value of an arg of 3 bytes; must fit in an "int" */
#if MAX_INT < (1<<24)
#define MAX_ARG MAX_INT
#else
#define MAX_ARG ((1<<24)-1)
#endif
/* maximum value of a word of 2 bytes; cannot be bigger than MAX_ARG */
#if MAX_ARG < (1<<16)
#define MAX_WORD MAX_ARG
#else
#define MAX_WORD ((1<<16)-1)
#endif
/* maximum value of a byte */
#define MAX_BYTE ((1<<8)-1)
#endif

1391
lparser.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +0,0 @@
/*
** $Id: lparser.h,v 1.2 1997/12/22 20:57:18 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
#ifndef lparser_h
#define lparser_h
#include "lobject.h"
#include "lzio.h"
void luaY_codedebugline (int line);
TProtoFunc *luaY_parser (ZIO *z);
void luaY_error (char *s);
void luaY_syntaxerror (char *s, char *token);
#endif

View File

@@ -1,86 +0,0 @@
/*
** $Id: lstate.c,v 1.11 1999/05/11 14:19:32 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
#include "lbuiltin.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
lua_State *lua_state = NULL;
void lua_open (void)
{
if (lua_state) return;
lua_state = luaM_new(lua_State);
L->Cstack.base = 0;
L->Cstack.lua2C = 0;
L->Cstack.num = 0;
L->errorJmp = NULL;
L->Mbuffer = NULL;
L->Mbuffbase = 0;
L->Mbuffsize = 0;
L->Mbuffnext = 0;
L->Cblocks = NULL;
L->numCblocks = 0;
L->debug = 0;
L->callhook = NULL;
L->linehook = NULL;
L->rootproto.next = NULL;
L->rootproto.marked = 0;
L->rootcl.next = NULL;
L->rootcl.marked = 0;
L->rootglobal.next = NULL;
L->rootglobal.marked = 0;
L->roottable.next = NULL;
L->roottable.marked = 0;
L->IMtable = NULL;
L->refArray = NULL;
L->refSize = 0;
L->GCthreshold = GARBAGE_BLOCK;
L->nblocks = 0;
luaD_init();
luaS_init();
luaX_init();
luaT_init();
luaB_predefine();
}
void lua_close (void)
{
TaggedString *alludata = luaS_collectudata();
L->GCthreshold = MAX_INT; /* to avoid GC during GC */
luaC_hashcallIM((Hash *)L->roottable.next); /* GC t.methods for tables */
luaC_strcallIM(alludata); /* GC tag methods for userdata */
luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
luaH_free((Hash *)L->roottable.next);
luaF_freeproto((TProtoFunc *)L->rootproto.next);
luaF_freeclosure((Closure *)L->rootcl.next);
luaS_free(alludata);
luaS_freeall();
luaM_free(L->stack.stack);
luaM_free(L->IMtable);
luaM_free(L->refArray);
luaM_free(L->Mbuffer);
luaM_free(L->Cblocks);
luaM_free(L);
L = NULL;
#ifdef DEBUG
printf("total de blocos: %ld\n", numblocks);
printf("total de memoria: %ld\n", totalmem);
#endif
}

View File

@@ -1,94 +0,0 @@
/*
** $Id: lstate.h,v 1.18 1999/05/11 14:19:32 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
#ifndef lstate_h
#define lstate_h
#include <setjmp.h>
#include "lobject.h"
#include "lua.h"
#include "luadebug.h"
#define GARBAGE_BLOCK 150
typedef int StkId; /* index to stack elements */
/*
** "jmp_buf" may be an array, so it is better to make sure it has an
** address (and not that it *is* an address...)
*/
struct lua_longjmp {
jmp_buf b;
};
struct Stack {
TObject *top;
TObject *stack;
TObject *last;
};
struct C_Lua_Stack {
StkId base; /* when Lua calls C or C calls Lua, points to */
/* the first slot after the last parameter. */
StkId lua2C; /* points to first element of "array" lua2C */
int num; /* size of "array" lua2C */
};
typedef struct stringtable {
int size;
int nuse; /* number of elements (including EMPTYs) */
TaggedString **hash;
} stringtable;
enum Status {LOCK, HOLD, FREE, COLLECTED};
struct ref {
TObject o;
enum Status status;
};
struct lua_State {
/* thread-specific state */
struct Stack stack; /* Lua stack */
struct C_Lua_Stack Cstack; /* C2lua struct */
struct lua_longjmp *errorJmp; /* current error recover point */
char *Mbuffer; /* global buffer */
int Mbuffbase; /* current first position of Mbuffer */
int Mbuffsize; /* size of Mbuffer */
int Mbuffnext; /* next position to fill in Mbuffer */
struct C_Lua_Stack *Cblocks;
int numCblocks; /* number of nested Cblocks */
int debug;
lua_CHFunction callhook;
lua_LHFunction linehook;
/* global state */
GCnode rootproto; /* list of all prototypes */
GCnode rootcl; /* list of all closures */
GCnode roottable; /* list of all tables */
GCnode rootglobal; /* list of strings with global values */
stringtable *string_root; /* array of hash tables for strings and udata */
struct IM *IMtable; /* table for tag methods */
int last_tag; /* last used tag in IMtable */
struct ref *refArray; /* locked objects */
int refSize; /* size of refArray */
unsigned long GCthreshold;
unsigned long nblocks; /* number of 'blocks' currently allocated */
};
#define L lua_state
#endif

298
lstring.c
View File

@@ -1,298 +0,0 @@
/*
** $Id: lstring.c,v 1.18 1999/02/08 16:28:48 roberto Exp roberto $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
#include <string.h>
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "lua.h"
#define NUM_HASHSTR 31
#define NUM_HASHUDATA 31
#define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA)
#define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */
static TaggedString EMPTY = {{NULL, 2}, 0L, 0,
{{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
void luaS_init (void) {
int i;
L->string_root = luaM_newvector(NUM_HASHS, stringtable);
for (i=0; i<NUM_HASHS; i++) {
L->string_root[i].size = 0;
L->string_root[i].nuse = 0;
L->string_root[i].hash = NULL;
}
}
static unsigned long hash_s (char *s, long l) {
unsigned long h = 0; /* seed */
while (l--)
h = h ^ ((h<<5)+(h>>2)+(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++;
return luaO_redimension((realuse+1)*2); /* +1 is the new element */
}
static void grow (stringtable *tb) {
int ns = newsize(tb);
TaggedString **newhash = luaM_newvector(ns, TaggedString *);
int 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) {
unsigned long h = tb->hash[i]->hash;
int h1 = h%ns;
while (newhash[h1]) {
h1 += (h&(ns-2)) + 1; /* double hashing */
if (h1 >= ns) h1 -= ns;
}
newhash[h1] = tb->hash[i];
tb->nuse++;
}
}
luaM_free(tb->hash);
tb->size = ns;
tb->hash = newhash;
}
static TaggedString *newone_s (char *str, long l, unsigned long h) {
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 *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_s(str, l);
int size = tb->size;
int j = -1;
int h1;
if ((long)tb->nuse*3 >= (long)size*2) {
grow(tb);
size = tb->size;
}
h1 = h%size;
while ((ts = tb->hash[h1]) != NULL) {
if (ts == &EMPTY)
j = h1;
else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
return ts;
h1 += (h&(size-2)) + 1; /* double hashing */
if (h1 >= size) h1 -= size;
}
/* not found */
if (j != -1) /* is there an EMPTY space? */
h1 = j;
else
tb->nuse++;
ts = tb->hash[h1] = 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 j = -1;
int h1;
if ((long)tb->nuse*3 >= (long)size*2) {
grow(tb);
size = tb->size;
}
h1 = h%size;
while ((ts = tb->hash[h1]) != NULL) {
if (ts == &EMPTY)
j = h1;
else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)
return ts;
h1 += (h&(size-2)) + 1; /* double hashing */
if (h1 >= size) h1 -= size;
}
/* not found */
if (j != -1) /* is there an EMPTY space? */
h1 = j;
else
tb->nuse++;
ts = tb->hash[h1] = newone_u(buff, tag, h);
return ts;
}
TaggedString *luaS_createudata (void *udata, int tag) {
int t = ((unsigned)udata%NUM_HASHUDATA)+NUM_HASHSTR;
return insert_u(udata, tag, &L->string_root[t]);
}
TaggedString *luaS_newlstr (char *str, long l) {
int t = (l==0) ? 0 : ((int)((unsigned char)str[0]*l))%NUM_HASHSTR;
return insert_s(str, l, &L->string_root[t]);
}
TaggedString *luaS_new (char *str) {
return luaS_newlstr(str, strlen(str));
}
TaggedString *luaS_newfixedstring (char *str) {
TaggedString *ts = luaS_new(str);
if (ts->head.marked == 0)
ts->head.marked = 2; /* avoid GC */
return ts;
}
void luaS_free (TaggedString *l) {
while (l) {
TaggedString *next = (TaggedString *)l->head.next;
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
luaM_free(l);
l = next;
}
}
/*
** Garbage collection functions.
*/
static void remove_from_list (GCnode *l) {
while (l) {
GCnode *next = l->next;
while (next && !next->marked)
next = l->next = next->next;
l = next;
}
}
TaggedString *luaS_collector (void) {
TaggedString *frees = NULL;
int i;
remove_from_list(&(L->rootglobal));
for (i=0; i<NUM_HASHS; i++) {
stringtable *tb = &L->string_root[i];
int j;
for (j=0; j<tb->size; j++) {
TaggedString *t = tb->hash[j];
if (t == NULL) continue;
if (t->head.marked == 1)
t->head.marked = 0;
else if (!t->head.marked) {
t->head.next = (GCnode *)frees;
frees = t;
tb->hash[j] = &EMPTY;
}
}
}
return frees;
}
TaggedString *luaS_collectudata (void) {
TaggedString *frees = NULL;
int i;
L->rootglobal.next = NULL; /* empty list of globals */
for (i=NUM_HASHSTR; i<NUM_HASHS; i++) {
stringtable *tb = &L->string_root[i];
int j;
for (j=0; j<tb->size; j++) {
TaggedString *t = tb->hash[j];
if (t == NULL || t == &EMPTY)
continue;
LUA_ASSERT(t->constindex == -1, "must be userdata");
t->head.next = (GCnode *)frees;
frees = t;
tb->hash[j] = &EMPTY;
}
}
return frees;
}
void luaS_freeall (void) {
int i;
for (i=0; i<NUM_HASHS; i++) {
stringtable *tb = &L->string_root[i];
int j;
for (j=0; j<tb->size; j++) {
TaggedString *t = tb->hash[j];
if (t == &EMPTY) continue;
luaM_free(t);
}
luaM_free(tb->hash);
}
luaM_free(L->string_root);
}
void luaS_rawsetglobal (TaggedString *ts, TObject *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;
}
}
char *luaS_travsymbol (int (*fn)(TObject *)) {
TaggedString *g;
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
if (fn(&g->u.s.globalval))
return g->str;
return NULL;
}
int luaS_globaldefined (char *name) {
TaggedString *ts = luaS_new(name);
return ts->u.s.globalval.ttype != LUA_T_NIL;
}

View File

@@ -1,28 +0,0 @@
/*
** $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
*/
#ifndef lstring_h
#define lstring_h
#include "lobject.h"
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);
char *luaS_travsymbol (int (*fn)(TObject *));
int luaS_globaldefined (char *name);
TaggedString *luaS_collectudata (void);
void luaS_freeall (void);
#endif

594
lstrlib.c
View File

@@ -1,594 +0,0 @@
/*
** $Id: lstrlib.c,v 1.31 1999/05/14 12:24:04 roberto Exp roberto $
** Standard library for strings and pattern-matching
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "lua.h"
#include "lualib.h"
static void addnchar (char *s, int n)
{
char *b = luaL_openspace(n);
memcpy(b, s, n);
luaL_addsize(n);
}
static void str_len (void)
{
long l;
luaL_check_lstr(1, &l);
lua_pushnumber(l);
}
static void closeandpush (void) {
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) {
long l;
char *s = luaL_check_lstr(1, &l);
long start = posrelat(luaL_check_long(2), l);
long end = posrelat(luaL_opt_long(3, -1), l);
if (start < 1) start = 1;
if (end > l) end = l;
if (start <= end)
lua_pushlstring(s+start-1, end-start+1);
else lua_pushstring("");
}
static void str_lower (void) {
long l;
int i;
char *s = luaL_check_lstr(1, &l);
luaL_resetbuffer();
for (i=0; i<l; i++)
luaL_addchar(tolower((unsigned char)(s[i])));
closeandpush();
}
static void str_upper (void) {
long l;
int i;
char *s = luaL_check_lstr(1, &l);
luaL_resetbuffer();
for (i=0; i<l; i++)
luaL_addchar(toupper((unsigned char)(s[i])));
closeandpush();
}
static void str_rep (void)
{
long l;
char *s = luaL_check_lstr(1, &l);
int n = luaL_check_int(2);
luaL_resetbuffer();
while (n-- > 0)
addnchar(s, l);
closeandpush();
}
static void str_byte (void) {
long l;
char *s = luaL_check_lstr(1, &l);
long pos = posrelat(luaL_opt_long(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((unsigned char)c);
}
closeandpush();
}
/*
** {======================================================
** PATTERN MATCHING
** =======================================================
*/
#ifndef MAX_CAPT
#define MAX_CAPT 32 /* arbitrary limit */
#endif
struct Capture {
char *src_end; /* end ('\0') of source string */
int level; /* total number of captures (finished or unfinished) */
struct {
char *init;
int len; /* -1 signals unfinished capture */
} capture[MAX_CAPT];
};
#define ESC '%'
#define SPECIALS "^$*+?.([%-"
static void push_captures (struct Capture *cap) {
int i;
for (i=0; i<cap->level; i++) {
int l = cap->capture[i].len;
if (l == -1) lua_error("unfinished capture");
lua_pushlstring(cap->capture[i].init, l);
}
}
static int check_cap (int l, struct Capture *cap) {
l -= '1';
if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
lua_error("invalid capture index");
return l;
}
static int capture_to_close (struct Capture *cap) {
int level = cap->level;
for (level--; level>=0; level--)
if (cap->capture[level].len == -1) return level;
lua_error("invalid pattern capture");
return 0; /* to avoid warnings */
}
char *luaI_classend (char *p) {
switch (*p++) {
case ESC:
if (*p == '\0')
luaL_verror("incorrect pattern (ends with `%c')", ESC);
return p+1;
case '[':
if (*p == '^') p++;
if (*p == ']') p++;
p = strchr(p, ']');
if (!p) lua_error("incorrect pattern (missing `]')");
return p+1;
default:
return p;
}
}
static int matchclass (int c, int cl) {
int res;
switch (tolower(cl)) {
case 'a' : res = isalpha(c); break;
case 'c' : res = iscntrl(c); break;
case 'd' : res = isdigit(c); break;
case 'l' : res = islower(c); break;
case 'p' : res = ispunct(c); break;
case 's' : res = isspace(c); break;
case 'u' : res = isupper(c); break;
case 'w' : res = isalnum(c); break;
case 'x' : res = isxdigit(c); break;
case 'z' : res = (c == '\0'); break;
default: return (cl == c);
}
return (islower(cl) ? res : !res);
}
static int matchbracketclass (int c, char *p, char *end) {
int sig = 1;
if (*(p+1) == '^') {
sig = 0;
p++; /* skip the '^' */
}
while (++p < end) {
if (*p == ESC) {
p++;
if ((p < end) && matchclass(c, (unsigned char)*p))
return sig;
}
else if ((*(p+1) == '-') && (p+2 < end)) {
p+=2;
if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p)
return sig;
}
else if ((unsigned char)*p == c) return sig;
}
return !sig;
}
int luaI_singlematch (int c, char *p, char *ep) {
switch (*p) {
case '.': /* matches any char */
return 1;
case ESC:
return matchclass(c, (unsigned char)*(p+1));
case '[':
return matchbracketclass(c, p, ep-1);
default:
return ((unsigned char)*p == c);
}
}
static char *match (char *s, char *p, struct Capture *cap);
static char *matchbalance (char *s, char *p, struct Capture *cap) {
if (*p == 0 || *(p+1) == 0)
lua_error("unbalanced pattern");
if (*s != *p) return NULL;
else {
int b = *p;
int e = *(p+1);
int cont = 1;
while (++s < cap->src_end) {
if (*s == e) {
if (--cont == 0) return s+1;
}
else if (*s == b) cont++;
}
}
return NULL; /* string ends out of balance */
}
static char *max_expand (char *s, char *p, char *ep, struct Capture *cap) {
int i = 0; /* counts maximum expand for item */
while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep))
i++;
/* keeps trying to match mith the maximum repetitions */
while (i>=0) {
char *res = match((s+i), ep+1, cap);
if (res) return res;
i--; /* else didn't match; reduce 1 repetition to try again */
}
return NULL;
}
static char *min_expand (char *s, char *p, char *ep, struct Capture *cap) {
for (;;) {
char *res = match(s, ep+1, cap);
if (res != NULL)
return res;
else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep))
s++; /* try with one more repetition */
else return NULL;
}
}
static char *start_capt (char *s, char *p, struct Capture *cap) {
char *res;
int level = cap->level;
if (level >= MAX_CAPT) lua_error("too many captures");
cap->capture[level].init = s;
cap->capture[level].len = -1;
cap->level = level+1;
if ((res=match(s, p+1, cap)) == NULL) /* match failed? */
cap->level--; /* undo capture */
return res;
}
static char *end_capt (char *s, char *p, struct Capture *cap) {
int l = capture_to_close(cap);
char *res;
cap->capture[l].len = s - cap->capture[l].init; /* close capture */
if ((res = match(s, p+1, cap)) == NULL) /* match failed? */
cap->capture[l].len = -1; /* undo capture */
return res;
}
static char *match_capture (char *s, int level, struct Capture *cap) {
int l = check_cap(level, cap);
int len = cap->capture[l].len;
if (cap->src_end-s >= len &&
memcmp(cap->capture[l].init, s, len) == 0)
return s+len;
else return NULL;
}
static char *match (char *s, char *p, struct Capture *cap) {
init: /* using goto's to optimize tail recursion */
switch (*p) {
case '(': /* start capture */
return start_capt(s, p, cap);
case ')': /* end capture */
return end_capt(s, p, cap);
case ESC: /* may be %[0-9] or %b */
if (isdigit((unsigned char)(*(p+1)))) { /* capture? */
s = match_capture(s, *(p+1), cap);
if (s == NULL) return NULL;
p+=2; goto init; /* else return match(p+2, s, cap) */
}
else if (*(p+1) == 'b') { /* balanced string? */
s = matchbalance(s, p+2, cap);
if (s == NULL) return NULL;
p+=4; goto init; /* else return match(p+4, s, cap); */
}
else goto dflt; /* case default */
case '\0': /* end of pattern */
return s; /* match succeeded */
case '$':
if (*(p+1) == '\0') /* is the '$' the last char in pattern? */
return (s == cap->src_end) ? s : NULL; /* check end of string */
else goto dflt;
default: dflt: { /* it is a pattern item */
char *ep = luaI_classend(p); /* points to what is next */
int m = s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep);
switch (*ep) {
case '?': { /* optional */
char *res;
if (m && ((res=match(s+1, ep+1, cap)) != NULL))
return res;
p=ep+1; goto init; /* else return match(s, ep+1, cap); */
}
case '*': /* 0 or more repetitions */
return max_expand(s, p, ep, cap);
case '+': /* 1 or more repetitions */
return (m ? max_expand(s+1, p, ep, cap) : NULL);
case '-': /* 0 or more repetitions (minimum) */
return min_expand(s, p, ep, cap);
default:
if (!m) return NULL;
s++; p=ep; goto init; /* else return match(s+1, ep, cap); */
}
}
}
}
static void str_find (void) {
long l;
char *s = luaL_check_lstr(1, &l);
char *p = luaL_check_string(2);
long init = posrelat(luaL_opt_long(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 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 {
char *res;
cap.level = 0;
if ((res=match(s1, p, &cap)) != NULL) {
lua_pushnumber(s1-s+1); /* start */
lua_pushnumber(res-s); /* end */
push_captures(&cap);
return;
}
} while (s1++<cap.src_end && !anchor);
}
lua_pushnil(); /* if arrives here, it didn't find */
}
static void add_s (lua_Object newp, struct Capture *cap) {
if (lua_isstring(newp)) {
char *news = lua_getstring(newp);
int l = lua_strlen(newp);
int i;
for (i=0; i<l; i++) {
if (news[i] != ESC)
luaL_addchar(news[i]);
else {
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 { /* is a function */
lua_Object res;
int status;
int oldbuff;
lua_beginblock();
push_captures(cap);
/* function may use buffer, so save it and create a new one */
oldbuff = luaL_newbuffer(0);
status = lua_callfunction(newp);
/* restore old buffer */
luaL_oldbuffer(oldbuff);
if (status != 0) {
lua_endblock();
lua_error(NULL);
}
res = lua_getresult(1);
if (lua_isstring(res))
addnchar(lua_getstring(res), lua_strlen(res));
lua_endblock();
}
}
static void str_gsub (void) {
long srcl;
char *src = luaL_check_lstr(1, &srcl);
char *p = luaL_check_string(2);
lua_Object newp = lua_getparam(3);
int max_s = luaL_opt_int(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) {
char *e;
cap.level = 0;
e = match(src, p, &cap);
if (e) {
n++;
add_s(newp, &cap);
}
if (e && e>src) /* non empty match? */
src = e; /* skip it */
else if (src < cap.src_end)
luaL_addchar(*src++);
else break;
if (anchor) break;
}
addnchar(src, cap.src_end-src);
closeandpush();
lua_pushnumber(n); /* number of substitutions */
}
/* }====================================================== */
static void luaI_addquoted (int arg) {
long l;
char *s = luaL_check_lstr(arg, &l);
luaL_addchar('"');
while (l--) {
switch (*s) {
case '"': case '\\': case '\n':
luaL_addchar('\\');
luaL_addchar(*s);
break;
case '\0': addnchar("\\000", 4); break;
default: luaL_addchar(*s);
}
s++;
}
luaL_addchar('"');
}
/* maximum size of each format specification (such as '%-099.99d') */
#define MAX_FORMAT 20 /* arbitrary limit */
static void str_format (void) {
int arg = 1;
char *strfrmt = luaL_check_string(arg);
luaL_resetbuffer();
while (*strfrmt) {
if (*strfrmt != '%')
luaL_addchar(*strfrmt++);
else if (*++strfrmt == '%')
luaL_addchar(*strfrmt++); /* %% */
else { /* format item */
struct Capture cap;
char form[MAX_FORMAT]; /* to store the format ('%...') */
char *buff; /* to store the formatted item */
char *initf = strfrmt;
form[0] = '%';
if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
arg = *initf - '0';
initf += 2; /* skip the 'n$' */
}
arg++;
cap.src_end = strfrmt+strlen(strfrmt)+1;
cap.level = 0;
strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
strfrmt-initf > MAX_FORMAT-2)
lua_error("invalid format (width or precision too long)");
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
form[strfrmt-initf+2] = 0;
buff = luaL_openspace(512); /* 512 > soid luaI_addquot99.99f', -1e308) */
switch (*strfrmt++) {
case 'c': case 'd': case 'i':
sprintf(buff, form, luaL_check_int(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;
case 'q':
luaI_addquoted(arg);
continue; /* skip the "addsize" at the end */
case 's': {
long l;
char *s = luaL_check_lstr(arg, &l);
if (cap.capture[1].len == 0 && l >= 100) {
/* no precision and string is too big to be formatted;
keep original string */
addnchar(s, l);
continue; /* skip the "addsize" at the end */
}
else {
sprintf(buff, form, s);
break;
}
}
default: /* also treat cases 'pnLlh' */
lua_error("invalid option in `format'");
}
luaL_addsize(strlen(buff));
}
}
closeandpush(); /* push the result */
}
static struct luaL_reg strlib[] = {
{"strlen", str_len},
{"strsub", str_sub},
{"strlower", str_lower},
{"strupper", str_upper},
{"strchar", str_char},
{"strrep", str_rep},
{"ascii", str_byte}, /* for compatibility with 3.0 and earlier */
{"strbyte", str_byte},
{"format", str_format},
{"strfind", str_find},
{"gsub", str_gsub}
};
/*
** Open string library
*/
void strlib_open (void)
{
luaL_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0])));
}

177
ltable.c
View File

@@ -1,177 +0,0 @@
/*
** $Id: ltable.c,v 1.21 1999/02/23 14:57:28 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include "lauxlib.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "ltable.h"
#include "lua.h"
#define gcsize(n) (1+(n/16))
#define nuse(t) ((t)->nuse)
#define nodevector(t) ((t)->node)
#define TagDefault LUA_T_ARRAY;
static long int hashindex (TObject *ref) {
long int h;
switch (ttype(ref)) {
case LUA_T_NUMBER:
h = (long int)nvalue(ref);
break;
case LUA_T_STRING: case LUA_T_USERDATA:
h = (IntPoint)tsvalue(ref);
break;
case LUA_T_ARRAY:
h = (IntPoint)avalue(ref);
break;
case LUA_T_PROTO:
h = (IntPoint)tfvalue(ref);
break;
case LUA_T_CPROTO:
h = (IntPoint)fvalue(ref);
break;
case LUA_T_CLOSURE:
h = (IntPoint)clvalue(ref);
break;
default:
lua_error("unexpected type to index table");
h = 0; /* to avoid warnings */
}
return (h >= 0 ? h : -(h+1));
}
Node *luaH_present (Hash *t, TObject *key) {
int tsize = nhash(t);
long int h = hashindex(key);
int h1 = h%tsize;
Node *n = node(t, h1);
/* keep looking until an entry with "ref" equal to key or nil */
while ((ttype(ref(n)) == ttype(key)) ? !luaO_equalval(key, ref(n))
: ttype(ref(n)) != LUA_T_NIL) {
h1 += (h&(tsize-2)) + 1; /* double hashing */
if (h1 >= tsize) h1 -= tsize;
n = node(t, h1);
}
return n;
}
void luaH_free (Hash *frees) {
while (frees) {
Hash *next = (Hash *)frees->head.next;
L->nblocks -= gcsize(frees->nhash);
luaM_free(nodevector(frees));
luaM_free(frees);
frees = next;
}
}
static Node *hashnodecreate (int nhash) {
Node *v = luaM_newvector(nhash, Node);
int i;
for (i=0; i<nhash; i++)
ttype(ref(&v[i])) = ttype(val(&v[i])) = LUA_T_NIL;
return v;
}
Hash *luaH_new (int nhash) {
Hash *t = luaM_new(Hash);
nhash = luaO_redimension(nhash*3/2);
nodevector(t) = hashnodecreate(nhash);
nhash(t) = nhash;
nuse(t) = 0;
t->htag = TagDefault;
luaO_insertlist(&(L->roottable), (GCnode *)t);
L->nblocks += gcsize(nhash);
return t;
}
static int newsize (Hash *t) {
Node *v = t->node;
int size = nhash(t);
int realuse = 0;
int i;
for (i=0; i<size; i++) {
if (ttype(val(v+i)) != LUA_T_NIL)
realuse++;
}
return luaO_redimension((realuse+1)*2); /* +1 is the new element */
}
static void rehash (Hash *t) {
int nold = nhash(t);
Node *vold = nodevector(t);
int nnew = newsize(t);
int i;
nodevector(t) = hashnodecreate(nnew);
nhash(t) = nnew;
nuse(t) = 0;
for (i=0; i<nold; i++) {
Node *n = vold+i;
if (ttype(val(n)) != LUA_T_NIL) {
*luaH_present(t, ref(n)) = *n; /* copy old node to new hash */
nuse(t)++;
}
}
L->nblocks += gcsize(nnew)-gcsize(nold);
luaM_free(vold);
}
void luaH_set (Hash *t, TObject *ref, TObject *val) {
Node *n = luaH_present(t, ref);
if (ttype(ref(n)) != LUA_T_NIL)
*val(n) = *val;
else {
TObject buff;
buff = *val; /* rehash may invalidate this address */
if ((long)nuse(t)*3L > (long)nhash(t)*2L) {
rehash(t);
n = luaH_present(t, ref);
}
nuse(t)++;
*ref(n) = *ref;
*val(n) = buff;
}
}
int luaH_pos (Hash *t, TObject *r) {
Node *n = luaH_present(t, r);
luaL_arg_check(ttype(val(n)) != LUA_T_NIL, 2, "key not found");
return n-(t->node);
}
void luaH_setint (Hash *t, int ref, TObject *val) {
TObject index;
ttype(&index) = LUA_T_NUMBER;
nvalue(&index) = ref;
luaH_set(t, &index, val);
}
TObject *luaH_getint (Hash *t, int ref) {
TObject index;
ttype(&index) = LUA_T_NUMBER;
nvalue(&index) = ref;
return luaH_get(t, &index);
}

View File

@@ -1,30 +0,0 @@
/*
** $Id: ltable.h,v 1.10 1999/01/25 17:40:10 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
#ifndef ltable_h
#define ltable_h
#include "lobject.h"
#define node(t,i) (&(t)->node[i])
#define ref(n) (&(n)->ref)
#define val(n) (&(n)->val)
#define nhash(t) ((t)->nhash)
#define luaH_get(t,ref) (val(luaH_present((t), (ref))))
#define luaH_move(t,from,to) (luaH_setint(t, to, luaH_getint(t, from)))
Hash *luaH_new (int nhash);
void luaH_free (Hash *frees);
Node *luaH_present (Hash *t, TObject *key);
void luaH_set (Hash *t, TObject *ref, TObject *val);
int luaH_pos (Hash *t, TObject *r);
void luaH_setint (Hash *t, int ref, TObject *val);
TObject *luaH_getint (Hash *t, int ref);
#endif

248
ltm.c
View File

@@ -1,248 +0,0 @@
/*
** $Id: ltm.c,v 1.24 1999/02/26 15:48:55 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <string.h>
#include "lauxlib.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "ltm.h"
char *luaT_eventname[] = { /* ORDER IM */
"gettable", "settable", "index", "getglobal", "setglobal", "add",
"sub", "mul", "div", "pow", "unm", "lt", "le", "gt", "ge",
"concat", "gc", "function", NULL
};
static int luaI_checkevent (char *name, char *list[]) {
int e = luaL_findstring(name, list);
if (e < 0)
luaL_verror("`%.50s' is not a valid event name", name);
return e;
}
/* events in LUA_T_NIL are all allowed, since this is used as a
* 'placeholder' for "default" fallbacks
*/
static char luaT_validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */
{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_PROTO */
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CPROTO */
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
};
static int luaT_validevent (int t, int e) { /* ORDER LUA_T */
return (t < LUA_T_NIL) ? 1 : luaT_validevents[-t][e];
}
static void init_entry (int tag) {
int i;
for (i=0; i<IM_N; i++)
ttype(luaT_getim(tag, i)) = LUA_T_NIL;
}
void luaT_init (void) {
int t;
L->last_tag = -(NUM_TAGS-1);
luaM_growvector(L->IMtable, 0, NUM_TAGS, struct IM, arrEM, MAX_INT);
for (t=L->last_tag; t<=0; t++)
init_entry(t);
}
int lua_newtag (void) {
--L->last_tag;
luaM_growvector(L->IMtable, -(L->last_tag), 1, struct IM, arrEM, MAX_INT);
init_entry(L->last_tag);
return L->last_tag;
}
static void checktag (int tag) {
if (!(L->last_tag <= tag && tag <= 0))
luaL_verror("%d is not a valid tag", tag);
}
void luaT_realtag (int tag) {
if (!(L->last_tag <= tag && tag < LUA_T_NIL))
luaL_verror("tag %d was not created by `newtag'", tag);
}
int lua_copytagmethods (int tagto, int tagfrom) {
int e;
checktag(tagto);
checktag(tagfrom);
for (e=0; e<IM_N; e++) {
if (luaT_validevent(tagto, e))
*luaT_getim(tagto, e) = *luaT_getim(tagfrom, e);
}
return tagto;
}
int luaT_effectivetag (TObject *o) {
int t;
switch (t = ttype(o)) {
case LUA_T_ARRAY:
return o->value.a->htag;
case LUA_T_USERDATA: {
int tag = o->value.ts->u.d.tag;
return (tag >= 0) ? LUA_T_USERDATA : tag;
}
case LUA_T_CLOSURE:
return o->value.cl->consts[0].ttype;
#ifdef DEBUG
case LUA_T_PMARK: case LUA_T_CMARK:
case LUA_T_CLMARK: case LUA_T_LINE:
LUA_INTERNALERROR("invalid type");
#endif
default:
return t;
}
}
TObject *luaT_gettagmethod (int t, char *event) {
int e = luaI_checkevent(event, luaT_eventname);
checktag(t);
if (luaT_validevent(t, e))
return luaT_getim(t,e);
else
return &luaO_nilobject;
}
void luaT_settagmethod (int t, char *event, TObject *func) {
TObject temp;
int e = luaI_checkevent(event, luaT_eventname);
checktag(t);
if (!luaT_validevent(t, e))
luaL_verror("cannot change tag method `%.20s' for type `%.20s'%.20s",
luaT_eventname[e], luaO_typenames[-t],
(t == LUA_T_ARRAY || t == LUA_T_USERDATA) ? " with default tag"
: "");
temp = *func;
*func = *luaT_getim(t,e);
*luaT_getim(t, e) = temp;
}
char *luaT_travtagmethods (int (*fn)(TObject *)) { /* ORDER IM */
int e;
for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) {
int t;
for (t=0; t>=L->last_tag; t--)
if (fn(luaT_getim(t,e)))
return luaT_eventname[e];
}
return NULL;
}
/*
* ===================================================================
* compatibility with old fallback system
*/
#ifdef LUA_COMPAT2_5
#include "lapi.h"
#include "lstring.h"
static void errorFB (void)
{
lua_Object o = lua_getparam(1);
if (lua_isstring(o))
fprintf(stderr, "lua: %s\n", lua_getstring(o));
else
fprintf(stderr, "lua: unknown error\n");
}
static void nilFB (void) { }
static void typeFB (void) {
lua_error("unexpected type");
}
static void fillvalids (IMS e, TObject *func) {
int t;
for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
if (luaT_validevent(t, e))
*luaT_getim(t, e) = *func;
}
void luaT_setfallback (void) {
static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL};
TObject oldfunc;
lua_CFunction replace;
char *name = luaL_check_string(1);
lua_Object func = lua_getparam(2);
luaL_arg_check(lua_isfunction(func), 2, "function expected");
switch (luaL_findstring(name, oldnames)) {
case 0: { /* old error fallback */
TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
oldfunc = *em;
*em = *luaA_Address(func);
replace = errorFB;
break;
}
case 1: /* old getglobal fallback */
oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL);
*luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func);
replace = nilFB;
break;
case 2: { /* old arith fallback */
int i;
oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW);
for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */
fillvalids(i, luaA_Address(func));
replace = typeFB;
break;
}
case 3: { /* old order fallback */
int i;
oldfunc = *luaT_getim(LUA_T_NIL, IM_LT);
for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */
fillvalids(i, luaA_Address(func));
replace = typeFB;
break;
}
default: {
int e;
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;
}
else {
luaL_verror("`%.50s' is not a valid fallback name", name);
replace = NULL; /* to avoid warnings */
}
}
}
if (oldfunc.ttype != LUA_T_NIL)
luaA_pushobject(&oldfunc);
else
lua_pushcfunction(replace);
}
#endif

62
ltm.h
View File

@@ -1,62 +0,0 @@
/*
** $Id: ltm.h,v 1.4 1997/11/26 18:53:45 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
#ifndef ltm_h
#define ltm_h
#include "lobject.h"
#include "lstate.h"
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER IM"
*/
typedef enum {
IM_GETTABLE = 0,
IM_SETTABLE,
IM_INDEX,
IM_GETGLOBAL,
IM_SETGLOBAL,
IM_ADD,
IM_SUB,
IM_MUL,
IM_DIV,
IM_POW,
IM_UNM,
IM_LT,
IM_LE,
IM_GT,
IM_GE,
IM_CONCAT,
IM_GC,
IM_FUNCTION
} IMS;
#define IM_N 18
struct IM {
TObject int_method[IM_N];
};
#define luaT_getim(tag,event) (&L->IMtable[-(tag)].int_method[event])
#define luaT_getimbyObj(o,e) (luaT_getim(luaT_effectivetag(o),(e)))
extern char *luaT_eventname[];
void luaT_init (void);
void luaT_realtag (int tag);
int luaT_effectivetag (TObject *o);
void luaT_settagmethod (int t, char *event, TObject *func);
TObject *luaT_gettagmethod (int t, char *event);
char *luaT_travtagmethods (int (*fn)(TObject *));
void luaT_setfallback (void); /* only if LUA_COMPAT2_5 */
#endif

218
lua.c
View File

@@ -1,188 +1,54 @@
/*
** $Id: lua.c,v 1.20 1999/06/24 19:42:02 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
** lua.c
** Linguagem para Usuarios de Aplicacao
** TeCGraf - PUC-Rio
** 28 Apr 93
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "luadebug.h"
#include "lualib.h"
#ifdef _POSIX_SOURCE
#include <unistd.h>
#else
#define isatty(x) (x==0) /* assume stdin is a tty */
#endif
typedef void (*handler)(int); /* type for signal actions */
static void laction (int i);
static lua_LHFunction old_linehook = NULL;
static lua_CHFunction old_callhook = NULL;
static handler lreset (void) {
return signal(SIGINT, laction);
}
static void lstop (void) {
lua_setlinehook(old_linehook);
lua_setcallhook(old_callhook);
lreset();
lua_error("interrupted!");
}
static void laction (int i) {
signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop,
terminate process (default action) */
old_linehook = lua_setlinehook((lua_LHFunction)lstop);
old_callhook = lua_setcallhook((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,
"Lua: command line options:\n"
" -v print version information\n"
" -d turn debug on\n"
" -e stat dostring `stat'\n"
" -q interactive mode without prompt\n"
" -i interactive mode with prompt\n"
" - executes stdin as a file\n"
" a=b sets global `a' with string `b'\n"
" name dofile `name'\n\n");
}
static void assign (char *arg) {
if (strlen(arg) >= 500)
fprintf(stderr, "lua: shell argument too long");
else {
char buffer[500];
char *eq = strchr(arg, '=');
lua_pushstring(eq+1);
strncpy(buffer, arg, eq-arg);
buffer[eq-arg] = 0;
lua_setglobal(buffer);
}
}
static void manual_input (int prompt) {
int cont = 1;
while (cont) {
char buffer[BUFSIZ];
int i = 0;
lua_beginblock();
if (prompt)
printf("%s", lua_getstring(lua_getglobal("_PROMPT")));
for(;;) {
int c = getchar();
if (c == EOF) {
cont = 0;
break;
}
else if (c == '\n') {
if (i>0 && buffer[i-1] == '\\')
buffer[i-1] = '\n';
else break;
}
else if (i >= BUFSIZ-1) {
fprintf(stderr, "lua: argument line too long\n");
break;
}
else buffer[i++] = (char)c;
}
buffer[i] = '\0';
ldo(lua_dostring, buffer);
lua_endblock();
}
printf("\n");
}
int main (int argc, char *argv[])
void test (void)
{
int i;
lua_open();
lua_pushstring("> "); lua_setglobal("_PROMPT");
lua_userinit();
if (argc < 2) { /* no arguments? */
if (isatty(0)) {
printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT);
manual_input(1);
}
else
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:
ldo(lua_dofile, NULL); /* executes stdin as a file */
break;
case 'i':
manual_input(1);
break;
case 'q':
manual_input(0);
break;
case 'd':
lua_setdebug(1);
break;
case 'v':
printf("%s %s\n(written by %s)\n\n",
LUA_VERSION, LUA_COPYRIGHT, LUA_AUTHORS);
break;
case 'e':
i++;
if (ldo(lua_dostring, argv[i]) != 0) {
fprintf(stderr, "lua: error running argument `%s'\n", argv[i]);
return 1;
}
break;
default:
print_message();
exit(1);
}
}
else if (strchr(argv[i], '='))
assign(argv[i]);
else {
int result = ldo(lua_dofile, argv[i]);
if (result) {
if (result == 2) {
fprintf(stderr, "lua: cannot execute file ");
perror(argv[i]);
}
exit(1);
}
}
}
#ifdef DEBUG
lua_close();
#endif
return 0;
lua_pushobject(lua_getparam(1));
lua_call ("c", 1);
}
static void callfunc (void)
{
lua_Object obj = lua_getparam (1);
if (lua_isstring(obj)) lua_call(lua_getstring(obj),0);
}
static void execstr (void)
{
lua_Object obj = lua_getparam (1);
if (lua_isstring(obj)) lua_dostring(lua_getstring(obj));
}
void main (int argc, char *argv[])
{
int i;
if (argc < 2)
{
puts ("usage: lua filename [functionnames]");
return;
}
lua_register ("callfunc", callfunc);
lua_register ("execstr", execstr);
lua_register ("test", test);
iolib_open ();
strlib_open ();
mathlib_open ();
lua_dofile (argv[1]);
for (i=2; i<argc; i++)
{
lua_call (argv[i],0);
}
}

203
lua.h
View File

@@ -1,193 +1,54 @@
/*
** $Id: lua.h,v 1.31 1999/04/15 12:33:19 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
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** 19 May 93
*/
#ifndef lua_h
#define lua_h
#define LUA_VERSION "Lua 3.2"
#define LUA_COPYRIGHT "Copyright (C) 1994-1999 TeCGraf, PUC-Rio"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
#define LUA_NOOBJECT 0
#define LUA_ANYTAG (-1)
typedef struct lua_State lua_State;
extern lua_State *lua_state;
typedef void (*lua_CFunction) (void);
typedef unsigned int lua_Object;
typedef struct Object *lua_Object;
void lua_open (void);
void lua_close (void);
lua_State *lua_setstate (lua_State *st);
#define lua_register(n,f) (lua_pushcfunction(f), lua_storeglobal(n))
lua_Object lua_settagmethod (int tag, char *event); /* In: new method */
lua_Object lua_gettagmethod (int tag, char *event);
int lua_newtag (void);
int lua_copytagmethods (int tagto, int tagfrom);
void lua_settag (int tag); /* In: object */
void lua_errorfunction (void (*fn) (char *s));
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 */
int lua_dofile (char *filename);
int lua_dostring (char *string);
int lua_call (char *functionname, int nparam);
void lua_beginblock (void);
void lua_endblock (void);
lua_Object lua_lua2C (int number);
#define lua_getparam(_) lua_lua2C(_)
#define lua_getresult(_) lua_lua2C(_)
int lua_isnil (lua_Object object);
int lua_istable (lua_Object object);
int lua_isuserdata (lua_Object object);
int lua_iscfunction (lua_Object object);
int lua_isnumber (lua_Object object);
int lua_isstring (lua_Object object);
int lua_isfunction (lua_Object object);
double lua_getnumber (lua_Object object);
lua_Object lua_getparam (int number);
float lua_getnumber (lua_Object object);
char *lua_getstring (lua_Object object);
long lua_strlen (lua_Object object);
char *lua_copystring (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_pushusertag (void *u, int tag);
void lua_pushobject (lua_Object object);
lua_Object lua_pop (void);
void *lua_getuserdata (lua_Object object);
lua_Object lua_getfield (lua_Object object, char *field);
lua_Object lua_getindexed (lua_Object object, float index);
lua_Object lua_getglobal (char *name);
lua_Object lua_rawgetglobal (char *name);
void lua_setglobal (char *name); /* In: value */
void lua_rawsetglobal (char *name); /* In: value */
void lua_settable (void); /* In: table, index, value */
void lua_rawsettable (void); /* In: table, index, value */
lua_Object lua_gettable (void); /* In: table, index */
lua_Object lua_rawgettable (void); /* In: table, index */
lua_Object lua_pop (void);
int lua_tag (lua_Object object);
int lua_pushnil (void);
int lua_pushnumber (float n);
int lua_pushstring (char *s);
int lua_pushcfunction (lua_CFunction fn);
int lua_pushuserdata (void *u);
int lua_pushobject (lua_Object object);
char *lua_nextvar (char *varname); /* Out: value */
int lua_next (lua_Object o, int i);
/* Out: ref, value */
int lua_storeglobal (char *name);
int lua_storefield (lua_Object object, char *field);
int lua_storeindexed (lua_Object object, float index);
int lua_ref (int lock); /* In: value */
lua_Object lua_getref (int ref);
void lua_unref (int ref);
lua_Object lua_createtable (void);
long lua_collectgarbage (long limit);
/* =============================================================== */
/* some useful macros/functions */
#define lua_call(name) lua_callfunction(lua_getglobal(name))
#define lua_pushref(ref) lua_pushobject(lua_getref(ref))
#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l))
#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n))
#define lua_pushuserdata(u) lua_pushusertag(u, 0)
#define lua_pushcfunction(f) lua_pushcclosure(f, 0)
#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t))
lua_Object lua_seterrormethod (void); /* In: new method */
/* ==========================================================================
** for compatibility with old versions. Avoid using these macros/functions
** If your program does need any of these, define LUA_COMPAT2_5
*/
#ifdef LUA_COMPAT2_5
lua_Object lua_setfallback (char *event, lua_CFunction fallback);
#define lua_storeglobal lua_setglobal
#define lua_type lua_tag
#define lua_lockobject(o) lua_refobject(o,1)
#define lua_lock() lua_ref(1)
#define lua_getlocked lua_getref
#define lua_pushlocked lua_pushref
#define lua_unlock lua_unref
#define lua_pushliteral(o) lua_pushstring(o)
#define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_gettable())
#define lua_getfield(o,f) (lua_pushobject(o), lua_pushstring(f), lua_gettable())
#define lua_copystring(o) (strdup(lua_getstring(o)))
#define lua_getsubscript lua_gettable
#define lua_storesubscript lua_settable
int lua_isnil (lua_Object object);
int lua_isnumber (lua_Object object);
int lua_isstring (lua_Object object);
int lua_istable (lua_Object object);
int lua_iscfunction (lua_Object object);
int lua_isuserdata (lua_Object object);
#endif
#endif
/******************************************************************************
* Copyright (c) 1994-1999 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.
******************************************************************************/

View File

@@ -1,34 +0,0 @@
/*
** $Id: luadebug.h,v 1.5 1999/02/04 17:47:59 roberto Exp roberto $
** Debugging API
** See Copyright Notice in lua.h
*/
#ifndef luadebug_h
#define luadebug_h
#include "lua.h"
typedef lua_Object lua_Function;
typedef void (*lua_LHFunction) (int line);
typedef void (*lua_CHFunction) (lua_Function func, char *file, int line);
lua_Function lua_stackedfunction (int level);
void lua_funcinfo (lua_Object func, char **source, int *linedefined);
int lua_currentline (lua_Function func);
char *lua_getobjname (lua_Object o, char **name);
lua_Object lua_getlocal (lua_Function func, int local_number, char **name);
int lua_setlocal (lua_Function func, int local_number);
int lua_nups (lua_Function func);
lua_LHFunction lua_setlinehook (lua_LHFunction func);
lua_CHFunction lua_setcallhook (lua_CHFunction func);
int lua_setdebug (int debug);
#endif

View File

@@ -1,36 +1,15 @@
/*
** $Id: lualib.h,v 1.5 1999/01/08 16:47:44 roberto Exp roberto $
** Lua standard libraries
** See Copyright Notice in lua.h
** Libraries to use in LUA programs
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** 19 May 93
*/
#ifndef lualib_h
#define lualib_h
#include "lua.h"
void lua_iolibopen (void);
void lua_strlibopen (void);
void lua_mathlibopen (void);
void lua_dblibopen (void);
void lua_userinit (void);
/* To keep compatibility with old versions */
#define iolib_open lua_iolibopen
#define strlib_open lua_strlibopen
#define mathlib_open lua_mathlibopen
/* Auxiliary functions (private) */
char *luaI_classend (char *p);
int luaI_singlematch (int c, char *p, char *ep);
void iolib_open (void);
void strlib_open (void);
void mathlib_open (void);
#endif

239
lundump.c
View File

@@ -1,239 +0,0 @@
/*
** $Id: lundump.c,v 1.21 1999/07/02 19:34:26 lhf Exp $
** load bytecodes from files
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <string.h>
#include "lauxlib.h"
#include "lfunc.h"
#include "lmem.h"
#include "lopcodes.h"
#include "lstring.h"
#include "lundump.h"
#define LoadBlock(b,size,Z) ezread(Z,b,size)
static void unexpectedEOZ (ZIO* Z)
{
luaL_verror("unexpected end of file in %s",zname(Z));
}
static int ezgetc (ZIO* Z)
{
int c=zgetc(Z);
if (c==EOZ) unexpectedEOZ(Z);
return c;
}
static void ezread (ZIO* Z, void* b, int n)
{
int r=zread(Z,b,n);
if (r!=0) unexpectedEOZ(Z);
}
static unsigned int LoadWord (ZIO* Z)
{
unsigned int hi=ezgetc(Z);
unsigned int lo=ezgetc(Z);
return (hi<<8)|lo;
}
static unsigned long LoadLong (ZIO* Z)
{
unsigned long hi=LoadWord(Z);
unsigned long lo=LoadWord(Z);
return (hi<<16)|lo;
}
/*
* convert number from text
*/
double luaU_str2d (char* b, char* where)
{
int negative=(b[0]=='-');
double x=luaO_str2d(b+negative);
if (x<0) luaL_verror("cannot convert number '%s' in %s",b,where);
return negative ? -x : x;
}
static real LoadNumber (ZIO* Z, int native)
{
real x;
if (native)
{
LoadBlock(&x,sizeof(x),Z);
return x;
}
else
{
char b[256];
int size=ezgetc(Z);
LoadBlock(b,size,Z);
b[size]=0;
return luaU_str2d(b,zname(Z));
}
}
static int LoadInt (ZIO* Z, char* message)
{
unsigned long l=LoadLong(Z);
unsigned int i=l;
if (i!=l) luaL_verror(message,l,zname(Z));
return i;
}
#define PAD 5 /* two word operands plus opcode */
static Byte* LoadCode (ZIO* Z)
{
int size=LoadInt(Z,"code too long (%ld bytes) in %s");
Byte* b=luaM_malloc(size+PAD);
LoadBlock(b,size,Z);
if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z));
memset(b+size,ENDCODE,PAD); /* pad code for safety */
return b;
}
static TaggedString* LoadTString (ZIO* Z)
{
long size=LoadLong(Z);
if (size==0)
return NULL;
else
{
char* s=luaL_openspace(size);
LoadBlock(s,size,Z);
return luaS_newlstr(s,size-1);
}
}
static void LoadLocals (TProtoFunc* tf, ZIO* Z)
{
int i,n=LoadInt(Z,"too many locals (%ld) in %s");
if (n==0) return;
tf->locvars=luaM_newvector(n+1,LocVar);
for (i=0; i<n; i++)
{
tf->locvars[i].line=LoadInt(Z,"too many lines (%ld) in %s");
tf->locvars[i].varname=LoadTString(Z);
}
tf->locvars[i].line=-1; /* flag end of vector */
tf->locvars[i].varname=NULL;
}
static TProtoFunc* LoadFunction (ZIO* Z, int native);
static void LoadConstants (TProtoFunc* tf, ZIO* Z, int native)
{
int i,n=LoadInt(Z,"too many constants (%ld) in %s");
tf->nconsts=n;
if (n==0) return;
tf->consts=luaM_newvector(n,TObject);
for (i=0; i<n; i++)
{
TObject* o=tf->consts+i;
ttype(o)=-ezgetc(Z); /* ttype(o) is negative - ORDER LUA_T */
switch (ttype(o))
{
case LUA_T_NUMBER:
nvalue(o)=LoadNumber(Z,native);
break;
case LUA_T_STRING:
tsvalue(o)=LoadTString(Z);
break;
case LUA_T_PROTO:
tfvalue(o)=LoadFunction(Z,native);
break;
case LUA_T_NIL:
break;
default: /* cannot happen */
luaU_badconstant("load",i,o,tf);
break;
}
}
}
static TProtoFunc* LoadFunction (ZIO* Z, int native)
{
TProtoFunc* tf=luaF_newproto();
tf->lineDefined=LoadInt(Z,"lineDefined too large (%ld) in %s");
tf->source=LoadTString(Z);
if (tf->source==NULL) tf->source=luaS_new(zname(Z));
tf->code=LoadCode(Z);
LoadLocals(tf,Z);
LoadConstants(tf,Z,native);
return tf;
}
static void LoadSignature (ZIO* Z)
{
char* s=SIGNATURE;
while (*s!=0 && ezgetc(Z)==*s)
++s;
if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
}
static int LoadHeader (ZIO* Z)
{
int version,sizeofR;
int native;
LoadSignature(Z);
version=ezgetc(Z);
if (version>VERSION)
luaL_verror(
"%s too new: version=0x%02x; expected at most 0x%02x",
zname(Z),version,VERSION);
if (version<VERSION0) /* check last major change */
luaL_verror(
"%s too old: version=0x%02x; expected at least 0x%02x",
zname(Z),version,VERSION0);
sizeofR=ezgetc(Z);
native=(sizeofR!=0);
if (native) /* test number representation */
{
if (sizeofR!=sizeof(real))
luaL_verror("unknown number size in %s: read %d; expected %d",
zname(Z),sizeofR,sizeof(real));
else
{
real tf=TEST_NUMBER;
real f=LoadNumber(Z,native);
if ((long)f!=(long)tf)
luaL_verror("unknown number format in %s: "
"read " NUMBER_FMT "; expected " NUMBER_FMT,
zname(Z),f,tf);
}
}
return native;
}
static TProtoFunc* LoadChunk (ZIO* Z)
{
return LoadFunction(Z,LoadHeader(Z));
}
/*
** load one chunk from a file or buffer
** return main if ok and NULL at EOF
*/
TProtoFunc* luaU_undump1 (ZIO* Z)
{
int c=zgetc(Z);
if (c==ID_CHUNK)
return LoadChunk(Z);
else if (c!=EOZ)
luaL_verror("%s is not a Lua binary file",zname(Z));
return NULL;
}
/*
* handle constants that cannot happen
*/
void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf)
{
int t=ttype(o);
char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t];
luaL_verror("cannot %s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC);
}

View File

@@ -1,39 +0,0 @@
/*
** $Id: lundump.h,v 1.15 1999/07/02 19:34:26 lhf Exp $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
#ifndef lundump_h
#define lundump_h
#include "lobject.h"
#include "lzio.h"
TProtoFunc* luaU_undump1 (ZIO* Z); /* load one chunk */
void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf);
/* handle cases that cannot happen */
double luaU_str2d (char* b, char* where);
/* convert number from text */
/* definitions for headers of binary files */
#define VERSION 0x32 /* last format change was in 3.2 */
#define VERSION0 0x32 /* last major change was in 3.2 */
#define ID_CHUNK 27 /* binary files start with ESC... */
#define SIGNATURE "Lua" /* ...followed by this signature */
/* formats for error messages */
#define SOURCE "<%s:%d>"
#define IN " in %p " SOURCE
#define INLOC tf,tf->source->str,tf->lineDefined
/* format for numbers in listings and error messages */
#ifndef NUMBER_FMT
#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
#endif
/* a multiple of PI for testing native format */
/* multiplying by 1E8 gives non-trivial integer values */
#define TEST_NUMBER 3.14159265358979323846E8
#endif

635
lvm.c
View File

@@ -1,635 +0,0 @@
/*
** $Id: lvm.c,v 1.57 1999/05/21 19:41:49 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "luadebug.h"
#include "lvm.h"
#ifdef OLD_ANSI
#define strcoll(a,b) strcmp(a,b)
#endif
#define highbyte(x) ((x)<<8)
/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */
#define EXTRA_STACK 5
static TaggedString *strconc (TaggedString *l, TaggedString *r) {
long nl = l->u.s.len;
long nr = r->u.s.len;
char *buffer = luaL_openspace(nl+nr);
memcpy(buffer, l->str, nl);
memcpy(buffer+nl, r->str, nr);
return luaS_newlstr(buffer, nl+nr);
}
int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */
if (ttype(obj) != LUA_T_STRING)
return 1;
else {
double t;
char *e = svalue(obj);
int sig = 1;
while (isspace((unsigned char)*e)) e++;
if (*e == '-') {
e++;
sig = -1;
}
else if (*e == '+') e++;
/* no digit before or after decimal point? */
if (!isdigit((unsigned char)*e) && !isdigit((unsigned char)*(e+1)))
return 2;
t = luaO_str2d(e);
if (t<0) return 2;
nvalue(obj) = (real)t*sig;
ttype(obj) = LUA_T_NUMBER;
return 0;
}
}
int luaV_tostring (TObject *obj) { /* LUA_NUMBER */
if (ttype(obj) != LUA_T_NUMBER)
return 1;
else {
char s[32]; /* 16 digits, signal, point and \0 (+ some extra...) */
sprintf(s, "%.16g", (double)nvalue(obj));
tsvalue(obj) = luaS_new(s);
ttype(obj) = LUA_T_STRING;
return 0;
}
}
void luaV_setn (Hash *t, int val) {
TObject index, value;
ttype(&index) = LUA_T_STRING; tsvalue(&index) = luaS_new("n");
ttype(&value) = LUA_T_NUMBER; nvalue(&value) = val;
luaH_set(t, &index, &value);
}
void luaV_closure (int nelems) {
if (nelems > 0) {
struct Stack *S = &L->stack;
Closure *c = luaF_newclosure(nelems);
c->consts[0] = *(S->top-1);
memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject));
S->top -= nelems;
ttype(S->top-1) = LUA_T_CLOSURE;
(S->top-1)->value.cl = c;
}
}
/*
** Function to index a table.
** Receives the table at top-2 and the index at top-1.
*/
void luaV_gettable (void) {
TObject *table = L->stack.top-2;
TObject *im;
if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
im = luaT_getimbyObj(table, IM_GETTABLE);
if (ttype(im) == LUA_T_NIL)
lua_error("indexed expression not a table");
}
else { /* object is a table... */
int tg = table->value.a->htag;
im = luaT_getim(tg, IM_GETTABLE);
if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */
TObject *h = luaH_get(avalue(table), table+1);
if (ttype(h) == LUA_T_NIL &&
(ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)) {
/* result is nil and there is an "index" tag method */
luaD_callTM(im, 2, 1); /* calls it */
}
else {
L->stack.top--;
*table = *h; /* "push" result into table position */
}
return;
}
/* else it has a "gettable" method, go through to next command */
}
/* object is not a table, or it has a "gettable" method */
luaD_callTM(im, 2, 1);
}
/*
** Receives table at *t, index at *(t+1) and value at top.
*/
void luaV_settable (TObject *t) {
struct Stack *S = &L->stack;
TObject *im;
if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
im = luaT_getimbyObj(t, IM_SETTABLE);
if (ttype(im) == LUA_T_NIL)
lua_error("indexed expression not a table");
}
else { /* object is a table... */
im = luaT_getim(avalue(t)->htag, IM_SETTABLE);
if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */
luaH_set(avalue(t), t+1, S->top-1);
S->top--; /* pop value */
return;
}
/* else it has a "settable" method, go through to next command */
}
/* object is not a table, or it has a "settable" method */
/* prepare arguments and call the tag method */
*(S->top+1) = *(L->stack.top-1);
*(S->top) = *(t+1);
*(S->top-1) = *t;
S->top += 2; /* WARNING: caller must assure stack space */
luaD_callTM(im, 3, 0);
}
void luaV_rawsettable (TObject *t) {
if (ttype(t) != LUA_T_ARRAY)
lua_error("indexed expression not a table");
else {
struct Stack *S = &L->stack;
luaH_set(avalue(t), t+1, S->top-1);
S->top -= 3;
}
}
void luaV_getglobal (TaggedString *ts) {
/* WARNING: caller must assure stack space */
/* only userdata, tables and nil can have getglobal tag methods */
static char valid_getglobals[] = {1, 0, 0, 1, 0, 0, 1, 0}; /* ORDER LUA_T */
TObject *value = &ts->u.s.globalval;
if (valid_getglobals[-ttype(value)]) {
TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
struct Stack *S = &L->stack;
ttype(S->top) = LUA_T_STRING;
tsvalue(S->top) = ts;
S->top++;
*S->top++ = *value;
luaD_callTM(im, 2, 1);
return;
}
/* else no tag method: go through to default behavior */
}
*L->stack.top++ = *value; /* default behavior */
}
void luaV_setglobal (TaggedString *ts) {
TObject *oldvalue = &ts->u.s.globalval;
TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
luaS_rawsetglobal(ts, --L->stack.top);
else {
/* WARNING: caller must assure stack space */
struct Stack *S = &L->stack;
TObject newvalue;
newvalue = *(S->top-1);
ttype(S->top-1) = LUA_T_STRING;
tsvalue(S->top-1) = ts;
*S->top++ = *oldvalue;
*S->top++ = newvalue;
luaD_callTM(im, 3, 0);
}
}
static void call_binTM (IMS event, char *msg)
{
TObject *im = luaT_getimbyObj(L->stack.top-2, event);/* try first operand */
if (ttype(im) == LUA_T_NIL) {
im = luaT_getimbyObj(L->stack.top-1, event); /* try second operand */
if (ttype(im) == LUA_T_NIL) {
im = luaT_getim(0, event); /* try a 'global' i.m. */
if (ttype(im) == LUA_T_NIL)
lua_error(msg);
}
}
lua_pushstring(luaT_eventname[event]);
luaD_callTM(im, 3, 1);
}
static void call_arith (IMS event)
{
call_binTM(event, "unexpected type in arithmetic operation");
}
static int luaV_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;
}
}
void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
lua_Type ttype_great, IMS op) {
struct Stack *S = &L->stack;
TObject *l = S->top-2;
TObject *r = S->top-1;
real result;
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
result = nvalue(l)-nvalue(r);
else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
svalue(r), tsvalue(r)->u.s.len);
else {
call_binTM(op, "unexpected type in comparison");
return;
}
S->top--;
nvalue(S->top-1) = 1;
ttype(S->top-1) = (result < 0) ? ttype_less :
(result == 0) ? ttype_equal : ttype_great;
}
void luaV_pack (StkId firstel, int nvararg, TObject *tab) {
TObject *firstelem = L->stack.stack+firstel;
int i;
Hash *htab;
if (nvararg < 0) nvararg = 0;
htab = avalue(tab) = luaH_new(nvararg+1); /* +1 for field 'n' */
ttype(tab) = LUA_T_ARRAY;
for (i=0; i<nvararg; i++)
luaH_setint(htab, i+1, firstelem+i);
luaV_setn(htab, nvararg); /* store counter in field "n" */
}
static void adjust_varargs (StkId first_extra_arg)
{
TObject arg;
luaV_pack(first_extra_arg,
(L->stack.top-L->stack.stack)-first_extra_arg, &arg);
luaD_adjusttop(first_extra_arg);
*L->stack.top++ = arg;
}
/*
** Execute the given opcode, until a RET. Parameters are between
** [stack+base,top). Returns n such that the the results are between
** [stack+n,top).
*/
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
struct Stack *S = &L->stack; /* to optimize */
register Byte *pc = tf->code;
TObject *consts = tf->consts;
if (L->callhook)
luaD_callHook(base, tf, 0);
luaD_checkstack((*pc++)+EXTRA_STACK);
if (*pc < ZEROVARARG)
luaD_adjusttop(base+*(pc++));
else { /* varargs */
luaC_checkGC();
adjust_varargs(base+(*pc++)-ZEROVARARG);
}
for (;;) {
register int aux = 0;
switchentry:
switch ((OpCode)*pc++) {
case ENDCODE:
S->top = S->stack + base;
goto ret;
case RETCODE:
base += *pc++;
goto ret;
case CALL: aux = *pc++;
luaD_calln(*pc++, aux);
break;
case TAILCALL: aux = *pc++;
luaD_calln(*pc++, MULT_RET);
base += aux;
goto ret;
case PUSHNIL: aux = *pc++;
do {
ttype(S->top++) = LUA_T_NIL;
} while (aux--);
break;
case POP: aux = *pc++;
S->top -= aux;
break;
case PUSHNUMBERW: aux += highbyte(*pc++);
case PUSHNUMBER: aux += *pc++;
ttype(S->top) = LUA_T_NUMBER;
nvalue(S->top) = aux;
S->top++;
break;
case PUSHNUMBERNEGW: aux += highbyte(*pc++);
case PUSHNUMBERNEG: aux += *pc++;
ttype(S->top) = LUA_T_NUMBER;
nvalue(S->top) = -aux;
S->top++;
break;
case PUSHCONSTANTW: aux += highbyte(*pc++);
case PUSHCONSTANT: aux += *pc++;
*S->top++ = consts[aux];
break;
case PUSHUPVALUE: aux = *pc++;
*S->top++ = cl->consts[aux+1];
break;
case PUSHLOCAL: aux = *pc++;
*S->top++ = *((S->stack+base) + aux);
break;
case GETGLOBALW: aux += highbyte(*pc++);
case GETGLOBAL: aux += *pc++;
luaV_getglobal(tsvalue(&consts[aux]));
break;
case GETTABLE:
luaV_gettable();
break;
case GETDOTTEDW: aux += highbyte(*pc++);
case GETDOTTED: aux += *pc++;
*S->top++ = consts[aux];
luaV_gettable();
break;
case PUSHSELFW: aux += highbyte(*pc++);
case PUSHSELF: aux += *pc++; {
TObject receiver;
receiver = *(S->top-1);
*S->top++ = consts[aux];
luaV_gettable();
*S->top++ = receiver;
break;
}
case CREATEARRAYW: aux += highbyte(*pc++);
case CREATEARRAY: aux += *pc++;
luaC_checkGC();
avalue(S->top) = luaH_new(aux);
ttype(S->top) = LUA_T_ARRAY;
S->top++;
break;
case SETLOCAL: aux = *pc++;
*((S->stack+base) + aux) = *(--S->top);
break;
case SETGLOBALW: aux += highbyte(*pc++);
case SETGLOBAL: aux += *pc++;
luaV_setglobal(tsvalue(&consts[aux]));
break;
case SETTABLEPOP:
luaV_settable(S->top-3);
S->top -= 2; /* pop table and index */
break;
case SETTABLE:
luaV_settable(S->top-3-(*pc++));
break;
case SETLISTW: aux += highbyte(*pc++);
case SETLIST: aux += *pc++; {
int n = *(pc++);
Hash *arr = avalue(S->top-n-1);
aux *= LFIELDS_PER_FLUSH;
for (; n; n--)
luaH_setint(arr, n+aux, --S->top);
break;
}
case SETMAP: aux = *pc++; {
Hash *arr = avalue(S->top-(2*aux)-3);
do {
luaH_set(arr, S->top-2, S->top-1);
S->top-=2;
} while (aux--);
break;
}
case NEQOP: aux = 1;
case EQOP: {
int res = luaO_equalObj(S->top-2, S->top-1);
if (aux) res = !res;
S->top--;
ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
nvalue(S->top-1) = 1;
break;
}
case LTOP:
luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
break;
case LEOP:
luaV_comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
break;
case GTOP:
luaV_comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
break;
case GEOP:
luaV_comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
break;
case ADDOP: {
TObject *l = S->top-2;
TObject *r = S->top-1;
if (tonumber(r) || tonumber(l))
call_arith(IM_ADD);
else {
nvalue(l) += nvalue(r);
--S->top;
}
break;
}
case SUBOP: {
TObject *l = S->top-2;
TObject *r = S->top-1;
if (tonumber(r) || tonumber(l))
call_arith(IM_SUB);
else {
nvalue(l) -= nvalue(r);
--S->top;
}
break;
}
case MULTOP: {
TObject *l = S->top-2;
TObject *r = S->top-1;
if (tonumber(r) || tonumber(l))
call_arith(IM_MUL);
else {
nvalue(l) *= nvalue(r);
--S->top;
}
break;
}
case DIVOP: {
TObject *l = S->top-2;
TObject *r = S->top-1;
if (tonumber(r) || tonumber(l))
call_arith(IM_DIV);
else {
nvalue(l) /= nvalue(r);
--S->top;
}
break;
}
case POWOP:
call_binTM(IM_POW, "undefined operation");
break;
case CONCOP: {
TObject *l = S->top-2;
TObject *r = S->top-1;
if (tostring(l) || tostring(r))
call_binTM(IM_CONCAT, "unexpected type for concatenation");
else {
tsvalue(l) = strconc(tsvalue(l), tsvalue(r));
--S->top;
}
luaC_checkGC();
break;
}
case MINUSOP:
if (tonumber(S->top-1)) {
ttype(S->top) = LUA_T_NIL;
S->top++;
call_arith(IM_UNM);
}
else
nvalue(S->top-1) = - nvalue(S->top-1);
break;
case NOTOP:
ttype(S->top-1) =
(ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
nvalue(S->top-1) = 1;
break;
case ONTJMPW: aux += highbyte(*pc++);
case ONTJMP: aux += *pc++;
if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
else S->top--;
break;
case ONFJMPW: aux += highbyte(*pc++);
case ONFJMP: aux += *pc++;
if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
else S->top--;
break;
case JMPW: aux += highbyte(*pc++);
case JMP: aux += *pc++;
pc += aux;
break;
case IFFJMPW: aux += highbyte(*pc++);
case IFFJMP: aux += *pc++;
if (ttype(--S->top) == LUA_T_NIL) pc += aux;
break;
case IFTUPJMPW: aux += highbyte(*pc++);
case IFTUPJMP: aux += *pc++;
if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
break;
case IFFUPJMPW: aux += highbyte(*pc++);
case IFFUPJMP: aux += *pc++;
if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
break;
case CLOSUREW: aux += highbyte(*pc++);
case CLOSURE: aux += *pc++;
*S->top++ = consts[aux];
luaV_closure(*pc++);
luaC_checkGC();
break;
case SETLINEW: aux += highbyte(*pc++);
case SETLINE: aux += *pc++;
if ((S->stack+base-1)->ttype != LUA_T_LINE) {
/* open space for LINE value */
luaD_openstack((S->top-S->stack)-base);
base++;
(S->stack+base-1)->ttype = LUA_T_LINE;
}
(S->stack+base-1)->value.i = aux;
if (L->linehook)
luaD_lineHook(aux);
break;
case LONGARGW: aux += highbyte(*pc++);
case LONGARG: aux += *pc++;
aux = highbyte(highbyte(aux));
goto switchentry; /* do not reset "aux" */
case CHECKSTACK: aux = *pc++;
LUA_ASSERT((S->top-S->stack)-base == aux && S->last >= S->top,
"wrong stack size");
break;
}
} ret:
if (L->callhook)
luaD_callHook(0, NULL, 1);
return base;
}

34
lvm.h
View File

@@ -1,34 +0,0 @@
/*
** $Id: lvm.h,v 1.7 1998/12/30 17:26:49 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
#ifndef lvm_h
#define lvm_h
#include "ldo.h"
#include "lobject.h"
#include "ltm.h"
#define tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (luaV_tonumber(o) != 0))
#define tostring(o) ((ttype(o) != LUA_T_STRING) && (luaV_tostring(o) != 0))
void luaV_pack (StkId firstel, int nvararg, TObject *tab);
int luaV_tonumber (TObject *obj);
int luaV_tostring (TObject *obj);
void luaV_setn (Hash *t, int val);
void luaV_gettable (void);
void luaV_settable (TObject *t);
void luaV_rawsettable (TObject *t);
void luaV_getglobal (TaggedString *ts);
void luaV_setglobal (TaggedString *ts);
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base);
void luaV_closure (int nelems);
void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
lua_Type ttype_great, IMS op);
#endif

84
lzio.c
View File

@@ -1,84 +0,0 @@
/*
** $Id: lzio.c,v 1.6 1999/03/04 14:49:18 roberto Exp roberto $
** a generic input stream interface
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <string.h>
#include "lzio.h"
/* ----------------------------------------------------- memory buffers --- */
static int zmfilbuf (ZIO* z) {
return EOZ;
}
ZIO* zmopen (ZIO* z, char* b, int size, char *name)
{
if (b==NULL) return NULL;
z->n=size;
z->p= (unsigned char *)b;
z->filbuf=zmfilbuf;
z->u=NULL;
z->name=name;
return z;
}
/* ------------------------------------------------------------ strings --- */
ZIO* zsopen (ZIO* z, char* s, char *name)
{
if (s==NULL) return NULL;
return zmopen(z,s,strlen(s),name);
}
/* -------------------------------------------------------------- FILEs --- */
static int zffilbuf (ZIO* z) {
int n;
if (feof((FILE *)z->u)) return EOZ;
n=fread(z->buffer,1,ZBSIZE,z->u);
if (n==0) return EOZ;
z->n=n-1;
z->p=z->buffer;
return *(z->p++);
}
ZIO* zFopen (ZIO* z, FILE* f, char *name)
{
if (f==NULL) return NULL;
z->n=0;
z->p=z->buffer;
z->filbuf=zffilbuf;
z->u=f;
z->name=name;
return z;
}
/* --------------------------------------------------------------- read --- */
int zread (ZIO *z, void *b, int n) {
while (n) {
int m;
if (z->n == 0) {
if (z->filbuf(z) == EOZ)
return n; /* return number of missing bytes */
zungetc(z); /* put result from 'filbuf' in the buffer */
}
m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
memcpy(b, z->p, m);
z->n -= m;
z->p += m;
b = (char *)b + m;
n -= m;
}
return 0;
}

50
lzio.h
View File

@@ -1,50 +0,0 @@
/*
** $Id: lzio.h,v 1.3 1997/12/22 20:57:18 roberto Exp roberto $
** Buffered streams
** See Copyright Notice in lua.h
*/
#ifndef lzio_h
#define lzio_h
#include <stdio.h>
/* For Lua only */
#define zFopen luaZ_Fopen
#define zsopen luaZ_sopen
#define zmopen luaZ_mopen
#define zread luaZ_read
#define EOZ (-1) /* end of stream */
typedef struct zio ZIO;
ZIO* zFopen (ZIO* z, FILE* f, char *name); /* open FILEs */
ZIO* zsopen (ZIO* z, char* s, char *name); /* string */
ZIO* zmopen (ZIO* z, char* b, int size, char *name); /* memory */
int zread (ZIO* z, void* b, int n); /* read next n bytes */
#define zgetc(z) (--(z)->n>=0 ? ((int)*(z)->p++): (z)->filbuf(z))
#define zungetc(z) (++(z)->n,--(z)->p)
#define zname(z) ((z)->name)
/* --------- Private Part ------------------ */
#define ZBSIZE 256 /* buffer size */
struct zio {
int n; /* bytes still unread */
unsigned char* p; /* current position in buffer */
int (*filbuf)(ZIO* z);
void* u; /* additional data */
char *name;
unsigned char buffer[ZBSIZE]; /* buffer */
};
#endif

140
makefile
View File

@@ -1,140 +0,0 @@
#
## $Id: makefile,v 1.18 1999/02/23 15:01:29 roberto Exp roberto $
## Makefile
## See Copyright Notice in lua.h
#
#CONFIGURATION
# define (undefine) POPEN if your system (does not) support piped I/O
#
# define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant
#
# define (undefine) OLD_ANSI if your system does NOT have some new ANSI
# facilities (e.g. strerror, locale.h, memmove). SunOS does not comply;
# so, add "-DOLD_ANSI" on SunOS
#
# 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
# (for instance, -DLUA_NUM_TYPE=float)
#
CONFIG = -DPOPEN -D_POSIX_SOURCE
#CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG
# Compilation parameters
CC = gcc
CWARNS = -Wall -Wmissing-prototypes -Wshadow -pedantic -Wpointer-arith -Wcast-align -Waggregate-return
CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2
# To make early versions
CO_OPTIONS =
AR = ar
ARFLAGS = rvl
# Aplication modules
LUAOBJS = \
lapi.o \
lauxlib.o \
lbuffer.o \
lbuiltin.o \
ldo.o \
lfunc.o \
lgc.o \
llex.o \
lmem.o \
lobject.o \
lparser.o \
lstate.o \
lstring.o \
ltable.o \
ltm.o \
lvm.o \
lundump.o \
lzio.o
LIBOBJS = \
liolib.o \
lmathlib.o \
lstrlib.o \
ldblib.o \
linit.o
lua : lua.o liblua.a liblualib.a
$(CC) $(CFLAGS) -o $@ lua.o -L. -llua -llualib -lm
liblua.a : $(LUAOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib $@
liblualib.a : $(LIBOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib $@
liblua.so.1.0 : lua.o
ld -o liblua.so.1.0 $(LUAOBJS)
clear :
rcsclean
rm -f *.o
rm -f
co $(CO_OPTIONS) lua.h lualib.h luadebug.h
%.h : RCS/%.h,v
co $(CO_OPTIONS) $@
%.c : RCS/%.c,v
co $(CO_OPTIONS) $@
lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h \
luadebug.h lfunc.h lgc.h lmem.h lstring.h ltable.h ltm.h lvm.h
lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h \
luadebug.h
lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \
ldo.h lstate.h luadebug.h lfunc.h lmem.h lstring.h ltable.h ltm.h \
lundump.h lzio.h lvm.h
ldblib.o: ldblib.c lauxlib.h lua.h luadebug.h lualib.h
ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
lmem.h lparser.h lzio.h lstring.h ltm.h lundump.h lvm.h
lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h luadebug.h
lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
lmem.h lstring.h ltable.h ltm.h
linit.o: linit.c lua.h lualib.h
liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h
llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \
lparser.h lstate.h luadebug.h lstring.h
lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h
lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h luadebug.h
lobject.o: lobject.c lobject.h lua.h
lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h \
luadebug.h lfunc.h llex.h lzio.h lmem.h lopcodes.h lparser.h \
lstring.h
lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h \
luadebug.h lfunc.h lgc.h llex.h lzio.h lmem.h lstring.h ltable.h \
ltm.h
lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h luadebug.h \
lstring.h
lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h
ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h lstate.h \
luadebug.h ltable.h
ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h luadebug.h \
ltm.h
lua.o: lua.c lua.h luadebug.h lualib.h
lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \
lstring.h lundump.h lzio.h
lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h \
lfunc.h lgc.h lmem.h lopcodes.h lstring.h ltable.h ltm.h lvm.h
lzio.o: lzio.c lzio.h

3294
manual.tex

File diff suppressed because it is too large Load Diff

234
mathlib.c Normal file
View File

@@ -0,0 +1,234 @@
/*
** mathlib.c
** Mathematica library to LUA
**
** Waldemar Celes Filho
** TeCGraf - PUC-Rio
** 19 May 93
*/
#include <stdio.h> /* NULL */
#include <math.h>
#include "lua.h"
static void math_abs (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `abs'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `abs'"); return; }
d = lua_getnumber(o);
if (d < 0) d = -d;
lua_pushnumber (d);
}
static void math_sin (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `sin'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `sin'"); return; }
d = lua_getnumber(o);
lua_pushnumber (sin(d));
}
static void math_cos (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `cos'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `cos'"); return; }
d = lua_getnumber(o);
lua_pushnumber (cos(d));
}
static void math_tan (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `tan'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `tan'"); return; }
d = lua_getnumber(o);
lua_pushnumber (tan(d));
}
static void math_asin (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `asin'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `asin'"); return; }
d = lua_getnumber(o);
lua_pushnumber (asin(d));
}
static void math_acos (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `acos'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `acos'"); return; }
d = lua_getnumber(o);
lua_pushnumber (acos(d));
}
static void math_atan (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `atan'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `atan'"); return; }
d = lua_getnumber(o);
lua_pushnumber (atan(d));
}
static void math_ceil (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `ceil'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `ceil'"); return; }
d = lua_getnumber(o);
lua_pushnumber (ceil(d));
}
static void math_floor (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `floor'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `floor'"); return; }
d = lua_getnumber(o);
lua_pushnumber (floor(d));
}
static void math_mod (void)
{
int d1, d2;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (!lua_isnumber(o1) || !lua_isnumber(o2))
{ lua_error ("incorrect arguments to function `mod'"); return; }
d1 = (int) lua_getnumber(o1);
d2 = (int) lua_getnumber(o2);
lua_pushnumber (d1%d2);
}
static void math_sqrt (void)
{
double d;
lua_Object o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `sqrt'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `sqrt'"); return; }
d = lua_getnumber(o);
lua_pushnumber (sqrt(d));
}
static void math_pow (void)
{
double d1, d2;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (!lua_isnumber(o1) || !lua_isnumber(o2))
{ lua_error ("incorrect arguments to function `pow'"); return; }
d1 = lua_getnumber(o1);
d2 = lua_getnumber(o2);
lua_pushnumber (pow(d1,d2));
}
static void math_min (void)
{
int i=1;
double d, dmin;
lua_Object o;
if ((o = lua_getparam(i++)) == NULL)
{ lua_error ("too few arguments to function `min'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `min'"); return; }
dmin = lua_getnumber (o);
while ((o = lua_getparam(i++)) != NULL)
{
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `min'"); return; }
d = lua_getnumber (o);
if (d < dmin) dmin = d;
}
lua_pushnumber (dmin);
}
static void math_max (void)
{
int i=1;
double d, dmax;
lua_Object o;
if ((o = lua_getparam(i++)) == NULL)
{ lua_error ("too few arguments to function `max'"); return; }
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `max'"); return; }
dmax = lua_getnumber (o);
while ((o = lua_getparam(i++)) != NULL)
{
if (!lua_isnumber(o))
{ lua_error ("incorrect arguments to function `max'"); return; }
d = lua_getnumber (o);
if (d > dmax) dmax = d;
}
lua_pushnumber (dmax);
}
/*
** Open math library
*/
void mathlib_open (void)
{
lua_register ("abs", math_abs);
lua_register ("sin", math_sin);
lua_register ("cos", math_cos);
lua_register ("tan", math_tan);
lua_register ("asin", math_asin);
lua_register ("acos", math_acos);
lua_register ("atan", math_atan);
lua_register ("ceil", math_ceil);
lua_register ("floor", math_floor);
lua_register ("mod", math_mod);
lua_register ("sqrt", math_sqrt);
lua_register ("pow", math_pow);
lua_register ("min", math_min);
lua_register ("max", math_max);
}

933
opcode.c Normal file
View File

@@ -0,0 +1,933 @@
/*
** opcode.c
** TecCGraf - PUC-Rio
** 26 Apr 93
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __GNUC__
#include <floatingpoint.h>
#endif
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "lua.h"
#define tonumber(o) ((tag(o) != T_NUMBER) && (lua_tonumber(o) != 0))
#define tostring(o) ((tag(o) != T_STRING) && (lua_tostring(o) != 0))
#ifndef MAXSTACK
#define MAXSTACK 256
#endif
static Object stack[MAXSTACK] = {{T_MARK, {NULL}}};
static Object *top=stack+1, *base=stack+1;
/*
** Concatenate two given string, creating a mark space at the beginning.
** Return the new string pointer.
*/
static char *lua_strconc (char *l, char *r)
{
char *s = calloc (strlen(l)+strlen(r)+2, sizeof(char));
if (s == NULL)
{
lua_error ("not enough memory");
return NULL;
}
*s++ = 0; /* create mark space */
return strcat(strcpy(s,l),r);
}
/*
** Duplicate a string, creating a mark space at the beginning.
** Return the new string pointer.
*/
char *lua_strdup (char *l)
{
char *s = calloc (strlen(l)+2, sizeof(char));
if (s == NULL)
{
lua_error ("not enough memory");
return NULL;
}
*s++ = 0; /* create mark space */
return strcpy(s,l);
}
/*
** Convert, if possible, to a number tag.
** Return 0 in success or not 0 on error.
*/
static int lua_tonumber (Object *obj)
{
char *ptr;
if (tag(obj) != T_STRING)
{
lua_reportbug ("unexpected type at conversion to number");
return 1;
}
nvalue(obj) = strtod(svalue(obj), &ptr);
if (*ptr)
{
lua_reportbug ("string to number convertion failed");
return 2;
}
tag(obj) = T_NUMBER;
return 0;
}
/*
** Test if is possible to convert an object to a number one.
** If possible, return the converted object, otherwise return nil object.
*/
static Object *lua_convtonumber (Object *obj)
{
static Object cvt;
if (tag(obj) == T_NUMBER)
{
cvt = *obj;
return &cvt;
}
tag(&cvt) = T_NIL;
if (tag(obj) == T_STRING)
{
char *ptr;
nvalue(&cvt) = strtod(svalue(obj), &ptr);
if (*ptr == 0)
tag(&cvt) = T_NUMBER;
}
return &cvt;
}
/*
** Convert, if possible, to a string tag
** Return 0 in success or not 0 on error.
*/
static int lua_tostring (Object *obj)
{
static char s[256];
if (tag(obj) != T_NUMBER)
{
lua_reportbug ("unexpected type at conversion to string");
return 1;
}
if ((int) nvalue(obj) == nvalue(obj))
sprintf (s, "%d", (int) nvalue(obj));
else
sprintf (s, "%g", nvalue(obj));
svalue(obj) = lua_createstring(lua_strdup(s));
if (svalue(obj) == NULL)
return 1;
tag(obj) = T_STRING;
return 0;
}
/*
** Execute the given opcode. Return 0 in success or 1 on error.
*/
int lua_execute (Byte *pc)
{
while (1)
{
switch ((OpCode)*pc++)
{
case NOP: break;
case PUSHNIL: tag(top++) = T_NIL; break;
case PUSH0: tag(top) = T_NUMBER; nvalue(top++) = 0; break;
case PUSH1: tag(top) = T_NUMBER; nvalue(top++) = 1; break;
case PUSH2: tag(top) = T_NUMBER; nvalue(top++) = 2; break;
case PUSHBYTE: tag(top) = T_NUMBER; nvalue(top++) = *pc++; break;
case PUSHWORD:
tag(top) = T_NUMBER; nvalue(top++) = *((Word *)(pc)); pc += sizeof(Word);
break;
case PUSHFLOAT:
tag(top) = T_NUMBER; nvalue(top++) = *((float *)(pc)); pc += sizeof(float);
break;
case PUSHSTRING:
{
int w = *((Word *)(pc));
pc += sizeof(Word);
tag(top) = T_STRING; svalue(top++) = lua_constant[w];
}
break;
case PUSHLOCAL0: *top++ = *(base + 0); break;
case PUSHLOCAL1: *top++ = *(base + 1); break;
case PUSHLOCAL2: *top++ = *(base + 2); break;
case PUSHLOCAL3: *top++ = *(base + 3); break;
case PUSHLOCAL4: *top++ = *(base + 4); break;
case PUSHLOCAL5: *top++ = *(base + 5); break;
case PUSHLOCAL6: *top++ = *(base + 6); break;
case PUSHLOCAL7: *top++ = *(base + 7); break;
case PUSHLOCAL8: *top++ = *(base + 8); break;
case PUSHLOCAL9: *top++ = *(base + 9); break;
case PUSHLOCAL: *top++ = *(base + (*pc++)); break;
case PUSHGLOBAL:
*top++ = s_object(*((Word *)(pc))); pc += sizeof(Word);
break;
case PUSHINDEXED:
--top;
if (tag(top-1) != T_ARRAY)
{
lua_reportbug ("indexed expression not a table");
return 1;
}
{
Object *h = lua_hashdefine (avalue(top-1), top);
if (h == NULL) return 1;
*(top-1) = *h;
}
break;
case PUSHMARK: tag(top++) = T_MARK; break;
case PUSHOBJECT: *top = *(top-3); top++; break;
case STORELOCAL0: *(base + 0) = *(--top); break;
case STORELOCAL1: *(base + 1) = *(--top); break;
case STORELOCAL2: *(base + 2) = *(--top); break;
case STORELOCAL3: *(base + 3) = *(--top); break;
case STORELOCAL4: *(base + 4) = *(--top); break;
case STORELOCAL5: *(base + 5) = *(--top); break;
case STORELOCAL6: *(base + 6) = *(--top); break;
case STORELOCAL7: *(base + 7) = *(--top); break;
case STORELOCAL8: *(base + 8) = *(--top); break;
case STORELOCAL9: *(base + 9) = *(--top); break;
case STORELOCAL: *(base + (*pc++)) = *(--top); break;
case STOREGLOBAL:
s_object(*((Word *)(pc))) = *(--top); pc += sizeof(Word);
break;
case STOREINDEXED0:
if (tag(top-3) != T_ARRAY)
{
lua_reportbug ("indexed expression not a table");
return 1;
}
{
Object *h = lua_hashdefine (avalue(top-3), top-2);
if (h == NULL) return 1;
*h = *(top-1);
}
top -= 3;
break;
case STOREINDEXED:
{
int n = *pc++;
if (tag(top-3-n) != T_ARRAY)
{
lua_reportbug ("indexed expression not a table");
return 1;
}
{
Object *h = lua_hashdefine (avalue(top-3-n), top-2-n);
if (h == NULL) return 1;
*h = *(top-1);
}
--top;
}
break;
case STOREFIELD:
if (tag(top-3) != T_ARRAY)
{
lua_error ("internal error - table expected");
return 1;
}
*(lua_hashdefine (avalue(top-3), top-2)) = *(top-1);
top -= 2;
break;
case ADJUST:
{
Object *newtop = base + *(pc++);
if (top != newtop)
{
while (top < newtop) tag(top++) = T_NIL;
top = newtop;
}
}
break;
case CREATEARRAY:
if (tag(top-1) == T_NIL)
nvalue(top-1) = 101;
else
{
if (tonumber(top-1)) return 1;
if (nvalue(top-1) <= 0) nvalue(top-1) = 101;
}
avalue(top-1) = lua_createarray(lua_hashcreate(nvalue(top-1)));
if (avalue(top-1) == NULL)
return 1;
tag(top-1) = T_ARRAY;
break;
case EQOP:
{
Object *l = top-2;
Object *r = top-1;
--top;
if (tag(l) != tag(r))
tag(top-1) = T_NIL;
else
{
switch (tag(l))
{
case T_NIL: tag(top-1) = T_NUMBER; break;
case T_NUMBER: tag(top-1) = (nvalue(l) == nvalue(r)) ? T_NUMBER : T_NIL; break;
case T_ARRAY: tag(top-1) = (avalue(l) == avalue(r)) ? T_NUMBER : T_NIL; break;
case T_FUNCTION: tag(top-1) = (bvalue(l) == bvalue(r)) ? T_NUMBER : T_NIL; break;
case T_CFUNCTION: tag(top-1) = (fvalue(l) == fvalue(r)) ? T_NUMBER : T_NIL; break;
case T_USERDATA: tag(top-1) = (uvalue(l) == uvalue(r)) ? T_NUMBER : T_NIL; break;
case T_STRING: tag(top-1) = (strcmp (svalue(l), svalue(r)) == 0) ? T_NUMBER : T_NIL; break;
case T_MARK: return 1;
}
}
nvalue(top-1) = 1;
}
break;
case LTOP:
{
Object *l = top-2;
Object *r = top-1;
--top;
if (tag(l) == T_NUMBER && tag(r) == T_NUMBER)
tag(top-1) = (nvalue(l) < nvalue(r)) ? T_NUMBER : T_NIL;
else
{
if (tostring(l) || tostring(r))
return 1;
tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? T_NUMBER : T_NIL;
}
nvalue(top-1) = 1;
}
break;
case LEOP:
{
Object *l = top-2;
Object *r = top-1;
--top;
if (tag(l) == T_NUMBER && tag(r) == T_NUMBER)
tag(top-1) = (nvalue(l) <= nvalue(r)) ? T_NUMBER : T_NIL;
else
{
if (tostring(l) || tostring(r))
return 1;
tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? T_NUMBER : T_NIL;
}
nvalue(top-1) = 1;
}
break;
case ADDOP:
{
Object *l = top-2;
Object *r = top-1;
if (tonumber(r) || tonumber(l))
return 1;
nvalue(l) += nvalue(r);
--top;
}
break;
case SUBOP:
{
Object *l = top-2;
Object *r = top-1;
if (tonumber(r) || tonumber(l))
return 1;
nvalue(l) -= nvalue(r);
--top;
}
break;
case MULTOP:
{
Object *l = top-2;
Object *r = top-1;
if (tonumber(r) || tonumber(l))
return 1;
nvalue(l) *= nvalue(r);
--top;
}
break;
case DIVOP:
{
Object *l = top-2;
Object *r = top-1;
if (tonumber(r) || tonumber(l))
return 1;
nvalue(l) /= nvalue(r);
--top;
}
break;
case CONCOP:
{
Object *l = top-2;
Object *r = top-1;
if (tostring(r) || tostring(l))
return 1;
svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r)));
if (svalue(l) == NULL)
return 1;
--top;
}
break;
case MINUSOP:
if (tonumber(top-1))
return 1;
nvalue(top-1) = - nvalue(top-1);
break;
case NOTOP:
tag(top-1) = tag(top-1) == T_NIL ? T_NUMBER : T_NIL;
break;
case ONTJMP:
{
int n = *((Word *)(pc));
pc += sizeof(Word);
if (tag(top-1) != T_NIL) pc += n;
}
break;
case ONFJMP:
{
int n = *((Word *)(pc));
pc += sizeof(Word);
if (tag(top-1) == T_NIL) pc += n;
}
break;
case JMP: pc += *((Word *)(pc)) + sizeof(Word); break;
case UPJMP: pc -= *((Word *)(pc)) - sizeof(Word); break;
case IFFJMP:
{
int n = *((Word *)(pc));
pc += sizeof(Word);
top--;
if (tag(top) == T_NIL) pc += n;
}
break;
case IFFUPJMP:
{
int n = *((Word *)(pc));
pc += sizeof(Word);
top--;
if (tag(top) == T_NIL) pc -= n;
}
break;
case POP: --top; break;
case CALLFUNC:
{
Byte *newpc;
Object *b = top-1;
while (tag(b) != T_MARK) b--;
if (tag(b-1) == T_FUNCTION)
{
lua_debugline = 0; /* always reset debug flag */
newpc = bvalue(b-1);
bvalue(b-1) = pc; /* store return code */
nvalue(b) = (base-stack); /* store base value */
base = b+1;
pc = newpc;
if (MAXSTACK-(base-stack) < STACKGAP)
{
lua_error ("stack overflow");
return 1;
}
}
else if (tag(b-1) == T_CFUNCTION)
{
int nparam;
lua_debugline = 0; /* always reset debug flag */
nvalue(b) = (base-stack); /* store base value */
base = b+1;
nparam = top-base; /* number of parameters */
(fvalue(b-1))(); /* call C function */
/* shift returned values */
{
int i;
int nretval = top - base - nparam;
top = base - 2;
base = stack + (int) nvalue(base-1);
for (i=0; i<nretval; i++)
{
*top = *(top+nparam+2);
++top;
}
}
}
else
{
lua_reportbug ("call expression not a function");
return 1;
}
}
break;
case RETCODE:
{
int i;
int shift = *pc++;
int nretval = top - base - shift;
top = base - 2;
pc = bvalue(base-2);
base = stack + (int) nvalue(base-1);
for (i=0; i<nretval; i++)
{
*top = *(top+shift+2);
++top;
}
}
break;
case HALT:
return 0; /* success */
case SETFUNCTION:
{
int file, func;
file = *((Word *)(pc));
pc += sizeof(Word);
func = *((Word *)(pc));
pc += sizeof(Word);
if (lua_pushfunction (file, func))
return 1;
}
break;
case SETLINE:
lua_debugline = *((Word *)(pc));
pc += sizeof(Word);
break;
case RESET:
lua_popfunction ();
break;
default:
lua_error ("internal error - opcode didn't match");
return 1;
}
}
}
/*
** Mark all strings and arrays used by any object stored at stack.
*/
void lua_markstack (void)
{
Object *o;
for (o = top-1; o >= stack; o--)
lua_markobject (o);
}
/*
** Open file, generate opcode and execute global statement. Return 0 on
** success or 1 on error.
*/
int lua_dofile (char *filename)
{
if (lua_openfile (filename)) return 1;
if (lua_parse ()) { lua_closefile (); return 1; }
lua_closefile ();
return 0;
}
/*
** Generate opcode stored on string and execute global statement. Return 0 on
** success or 1 on error.
*/
int lua_dostring (char *string)
{
if (lua_openstring (string)) return 1;
if (lua_parse ()) return 1;
return 0;
}
/*
** Execute the given function. Return 0 on success or 1 on error.
*/
int lua_call (char *functionname, int nparam)
{
static Byte startcode[] = {CALLFUNC, HALT};
int i;
Object func = s_object(lua_findsymbol(functionname));
if (tag(&func) != T_FUNCTION) return 1;
for (i=1; i<=nparam; i++)
*(top-i+2) = *(top-i);
top += 2;
tag(top-nparam-1) = T_MARK;
*(top-nparam-2) = func;
return (lua_execute (startcode));
}
/*
** Get a parameter, returning the object handle or NULL on error.
** 'number' must be 1 to get the first parameter.
*/
Object *lua_getparam (int number)
{
if (number <= 0 || number > top-base) return NULL;
return (base+number-1);
}
/*
** Given an object handle, return its number value. On error, return 0.0.
*/
real lua_getnumber (Object *object)
{
if (tonumber (object)) return 0.0;
else return (nvalue(object));
}
/*
** Given an object handle, return its string pointer. On error, return NULL.
*/
char *lua_getstring (Object *object)
{
if (tostring (object)) return NULL;
else return (svalue(object));
}
/*
** Given an object handle, return a copy of its string. On error, return NULL.
*/
char *lua_copystring (Object *object)
{
if (tostring (object)) return NULL;
else return (strdup(svalue(object)));
}
/*
** Given an object handle, return its cfuntion pointer. On error, return NULL.
*/
lua_CFunction lua_getcfunction (Object *object)
{
if (tag(object) != T_CFUNCTION) return NULL;
else return (fvalue(object));
}
/*
** Given an object handle, return its user data. On error, return NULL.
*/
void *lua_getuserdata (Object *object)
{
if (tag(object) != T_USERDATA) return NULL;
else return (uvalue(object));
}
/*
** Given an object handle and a field name, return its field object.
** On error, return NULL.
*/
Object *lua_getfield (Object *object, char *field)
{
if (tag(object) != T_ARRAY)
return NULL;
else
{
Object ref;
tag(&ref) = T_STRING;
svalue(&ref) = lua_createstring(lua_strdup(field));
return (lua_hashdefine(avalue(object), &ref));
}
}
/*
** Given an object handle and an index, return its indexed object.
** On error, return NULL.
*/
Object *lua_getindexed (Object *object, float index)
{
if (tag(object) != T_ARRAY)
return NULL;
else
{
Object ref;
tag(&ref) = T_NUMBER;
nvalue(&ref) = index;
return (lua_hashdefine(avalue(object), &ref));
}
}
/*
** Get a global object. Return the object handle or NULL on error.
*/
Object *lua_getglobal (char *name)
{
int n = lua_findsymbol(name);
if (n < 0) return NULL;
return &s_object(n);
}
/*
** Pop and return an object
*/
Object *lua_pop (void)
{
if (top <= base) return NULL;
top--;
return top;
}
/*
** Push a nil object
*/
int lua_pushnil (void)
{
if ((top-stack) >= MAXSTACK-1)
{
lua_error ("stack overflow");
return 1;
}
tag(top) = T_NIL;
return 0;
}
/*
** Push an object (tag=number) to stack. Return 0 on success or 1 on error.
*/
int lua_pushnumber (real n)
{
if ((top-stack) >= MAXSTACK-1)
{
lua_error ("stack overflow");
return 1;
}
tag(top) = T_NUMBER; nvalue(top++) = n;
return 0;
}
/*
** Push an object (tag=string) to stack. Return 0 on success or 1 on error.
*/
int lua_pushstring (char *s)
{
if ((top-stack) >= MAXSTACK-1)
{
lua_error ("stack overflow");
return 1;
}
tag(top) = T_STRING;
svalue(top++) = lua_createstring(lua_strdup(s));
return 0;
}
/*
** Push an object (tag=cfunction) to stack. Return 0 on success or 1 on error.
*/
int lua_pushcfunction (lua_CFunction fn)
{
if ((top-stack) >= MAXSTACK-1)
{
lua_error ("stack overflow");
return 1;
}
tag(top) = T_CFUNCTION; fvalue(top++) = fn;
return 0;
}
/*
** Push an object (tag=userdata) to stack. Return 0 on success or 1 on error.
*/
int lua_pushuserdata (void *u)
{
if ((top-stack) >= MAXSTACK-1)
{
lua_error ("stack overflow");
return 1;
}
tag(top) = T_USERDATA; uvalue(top++) = u;
return 0;
}
/*
** Push an object to stack.
*/
int lua_pushobject (Object *o)
{
if ((top-stack) >= MAXSTACK-1)
{
lua_error ("stack overflow");
return 1;
}
*top++ = *o;
return 0;
}
/*
** Store top of the stack at a global variable array field.
** Return 1 on error, 0 on success.
*/
int lua_storeglobal (char *name)
{
int n = lua_findsymbol (name);
if (n < 0) return 1;
if (tag(top-1) == T_MARK) return 1;
s_object(n) = *(--top);
return 0;
}
/*
** Store top of the stack at an array field. Return 1 on error, 0 on success.
*/
int lua_storefield (lua_Object object, char *field)
{
if (tag(object) != T_ARRAY)
return 1;
else
{
Object ref, *h;
tag(&ref) = T_STRING;
svalue(&ref) = lua_createstring(lua_strdup(field));
h = lua_hashdefine(avalue(object), &ref);
if (h == NULL) return 1;
if (tag(top-1) == T_MARK) return 1;
*h = *(--top);
}
return 0;
}
/*
** Store top of the stack at an array index. Return 1 on error, 0 on success.
*/
int lua_storeindexed (lua_Object object, float index)
{
if (tag(object) != T_ARRAY)
return 1;
else
{
Object ref, *h;
tag(&ref) = T_NUMBER;
nvalue(&ref) = index;
h = lua_hashdefine(avalue(object), &ref);
if (h == NULL) return 1;
if (tag(top-1) == T_MARK) return 1;
*h = *(--top);
}
return 0;
}
/*
** Given an object handle, return if it is nil.
*/
int lua_isnil (Object *object)
{
return (object != NULL && tag(object) == T_NIL);
}
/*
** Given an object handle, return if it is a number one.
*/
int lua_isnumber (Object *object)
{
return (object != NULL && tag(object) == T_NUMBER);
}
/*
** Given an object handle, return if it is a string one.
*/
int lua_isstring (Object *object)
{
return (object != NULL && tag(object) == T_STRING);
}
/*
** Given an object handle, return if it is an array one.
*/
int lua_istable (Object *object)
{
return (object != NULL && tag(object) == T_ARRAY);
}
/*
** Given an object handle, return if it is a cfunction one.
*/
int lua_iscfunction (Object *object)
{
return (object != NULL && tag(object) == T_CFUNCTION);
}
/*
** Given an object handle, return if it is an user data one.
*/
int lua_isuserdata (Object *object)
{
return (object != NULL && tag(object) == T_USERDATA);
}
/*
** Internal function: return an object type.
*/
void lua_type (void)
{
Object *o = lua_getparam(1);
lua_pushstring (lua_constant[tag(o)]);
}
/*
** Internal function: convert an object to a number
*/
void lua_obj2number (void)
{
Object *o = lua_getparam(1);
lua_pushobject (lua_convtonumber(o));
}
/*
** Internal function: print object values
*/
void lua_print (void)
{
int i=1;
void *obj;
while ((obj=lua_getparam (i++)) != NULL)
{
if (lua_isnumber(obj)) printf("%g\n",lua_getnumber (obj));
else if (lua_isstring(obj)) printf("%s\n",lua_getstring (obj));
else if (lua_iscfunction(obj)) printf("cfunction: %p\n",lua_getcfunction (obj));
else if (lua_isuserdata(obj)) printf("userdata: %p\n",lua_getuserdata (obj));
else if (lua_istable(obj)) printf("table: %p\n",obj);
else if (lua_isnil(obj)) printf("nil\n");
else printf("invalid value to print\n");
}
}

144
opcode.h Normal file
View File

@@ -0,0 +1,144 @@
/*
** opcode.h
** TeCGraf - PUC-Rio
** 16 Apr 92
*/
#ifndef opcode_h
#define opcode_h
#ifndef STACKGAP
#define STACKGAP 128
#endif
#ifndef real
#define real float
#endif
typedef unsigned char Byte;
typedef unsigned short Word;
typedef enum
{
NOP,
PUSHNIL,
PUSH0, PUSH1, PUSH2,
PUSHBYTE,
PUSHWORD,
PUSHFLOAT,
PUSHSTRING,
PUSHLOCAL0, PUSHLOCAL1, PUSHLOCAL2, PUSHLOCAL3, PUSHLOCAL4,
PUSHLOCAL5, PUSHLOCAL6, PUSHLOCAL7, PUSHLOCAL8, PUSHLOCAL9,
PUSHLOCAL,
PUSHGLOBAL,
PUSHINDEXED,
PUSHMARK,
PUSHOBJECT,
STORELOCAL0, STORELOCAL1, STORELOCAL2, STORELOCAL3, STORELOCAL4,
STORELOCAL5, STORELOCAL6, STORELOCAL7, STORELOCAL8, STORELOCAL9,
STORELOCAL,
STOREGLOBAL,
STOREINDEXED0,
STOREINDEXED,
STOREFIELD,
ADJUST,
CREATEARRAY,
EQOP,
LTOP,
LEOP,
ADDOP,
SUBOP,
MULTOP,
DIVOP,
CONCOP,
MINUSOP,
NOTOP,
ONTJMP,
ONFJMP,
JMP,
UPJMP,
IFFJMP,
IFFUPJMP,
POP,
CALLFUNC,
RETCODE,
HALT,
SETFUNCTION,
SETLINE,
RESET
} OpCode;
typedef enum
{
T_MARK,
T_NIL,
T_NUMBER,
T_STRING,
T_ARRAY,
T_FUNCTION,
T_CFUNCTION,
T_USERDATA
} Type;
typedef void (*Cfunction) (void);
typedef int (*Input) (void);
typedef void (*Unput) (int );
typedef union
{
Cfunction f;
real n;
char *s;
Byte *b;
struct Hash *a;
void *u;
} Value;
typedef struct Object
{
Type tag;
Value value;
} Object;
typedef struct
{
char *name;
Object object;
} Symbol;
/* Macros to access structure members */
#define tag(o) ((o)->tag)
#define nvalue(o) ((o)->value.n)
#define svalue(o) ((o)->value.s)
#define bvalue(o) ((o)->value.b)
#define avalue(o) ((o)->value.a)
#define fvalue(o) ((o)->value.f)
#define uvalue(o) ((o)->value.u)
/* Macros to access symbol table */
#define s_name(i) (lua_table[i].name)
#define s_object(i) (lua_table[i].object)
#define s_tag(i) (tag(&s_object(i)))
#define s_nvalue(i) (nvalue(&s_object(i)))
#define s_svalue(i) (svalue(&s_object(i)))
#define s_bvalue(i) (bvalue(&s_object(i)))
#define s_avalue(i) (avalue(&s_object(i)))
#define s_fvalue(i) (fvalue(&s_object(i)))
#define s_uvalue(i) (uvalue(&s_object(i)))
/* Exported functions */
int lua_execute (Byte *pc);
void lua_markstack (void);
char *lua_strdup (char *l);
void lua_setinput (Input fn); /* from "lua.lex" module */
void lua_setunput (Unput fn); /* from "lua.lex" module */
char *lua_lasttext (void); /* from "lua.lex" module */
int lua_parse (void); /* from "lua.stx" module */
void lua_type (void);
void lua_obj2number (void);
void lua_print (void);
#endif

47
save.lua Normal file
View File

@@ -0,0 +1,47 @@
$debug
function savevar (n,v)
if v = nil then return end;
if type(v) = "number" then print(n.."="..v) return end
if type(v) = "string" then print(n.."='"..v.."'") return end
if type(v) = "table" then
if v.__visited__ ~= nil then
print(n .. "=" .. v.__visited__);
else
print(n.."=@()")
v.__visited__ = n;
local r,f;
r,f = next(v,nil);
while r ~= nil do
if r ~= "__visited__" then
if type(r) = 'string' then
savevar(n.."['"..r.."']",f)
else
savevar(n.."["..r.."]",f)
end
end
r,f = next(v,r)
end
end
end
end
function save ()
local n,v
n,v = nextvar(nil)
while n ~= nil do
savevar(n,v);
n,v = nextvar(n)
end
end
a = 3
x = @{a = 4, b = "name", l=@[4,5,67]}
b = @{t=5}
x.next = b
save()

56
sort.lua Normal file
View File

@@ -0,0 +1,56 @@
$debug
function quicksort(r,s)
if s<=r then return end -- caso basico da recursao
local v=x[r]
local i=r
local j=s+1
i=i+1; while x[i]<v do i=i+1 end
j=j-1; while x[j]>v do j=j-1 end
x[i],x[j]=x[j],x[i]
while j>i do -- separacao
i=i+1; while x[i]<v do i=i+1 end
j=j-1; while x[j]>v do j=j-1 end
x[i],x[j]=x[j],x[i]
end
x[i],x[j]=x[j],x[i] -- undo last swap
x[j],x[r]=x[r],x[j]
quicksort(r,j-1) -- recursao
quicksort(j+1,s)
end
function sort(a,n) -- selection sort
local i=1
while i<=n do
local m=i
local j=i+1
while j<=n do
if a[j]<a[m] then m=j end
j=j+1
end
a[i],a[m]=a[m],a[i] -- swap a[i] and a[m]
i=i+1
end
end
function main()
x=@()
n=-1
n=n+1; x[n]="a"
n=n+1; x[n]="waldemar"
n=n+1; x[n]="luiz"
n=n+1; x[n]="lula"
n=n+1; x[n]="peter"
n=n+1; x[n]="raquel"
n=n+1; x[n]="camilo"
n=n+1; x[n]="andre"
n=n+1; x[n]="marcelo"
n=n+1; x[n]="sedrez"
n=n+1; x[n]="z"
-- quicksort(1,n-1)
print(x[0]..","..x[1]..","..x[2]..","..x[3]..","..x[4]..","..x[5]..","..x[6]..","..x[7]..","..x[8]..","..x[9]..","..x[10])
sort (x, n-1)
print(x[0]..","..x[1]..","..x[2]..","..x[3]..","..x[4]..","..x[5]..","..x[6]..","..x[7]..","..x[8]..","..x[9]..","..x[10])
end

131
strlib.c Normal file
View File

@@ -0,0 +1,131 @@
/*
** strlib.c
** String library to LUA
**
** Waldemar Celes Filho
** TeCGraf - PUC-Rio
** 19 May 93
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "lua.h"
/*
** Return the position of the first caracter of a substring into a string
** LUA interface:
** n = strfind (string, substring)
*/
static void str_find (void)
{
int n;
char *s1, *s2;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
if (!lua_isstring(o1) || !lua_isstring(o2))
{ lua_error ("incorrect arguments to function `strfind'"); return; }
s1 = lua_getstring(o1);
s2 = lua_getstring(o2);
n = strstr(s1,s2) - s1 + 1;
lua_pushnumber (n);
}
/*
** Return the string length
** LUA interface:
** n = strlen (string)
*/
static void str_len (void)
{
lua_Object o = lua_getparam (1);
if (!lua_isstring(o))
{ lua_error ("incorrect arguments to function `strlen'"); return; }
lua_pushnumber(strlen(lua_getstring(o)));
}
/*
** Return the substring of a string, from start to end
** LUA interface:
** substring = strsub (string, start, end)
*/
static void str_sub (void)
{
int start, end;
char *s;
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
lua_Object o3 = lua_getparam (3);
if (!lua_isstring(o1) || !lua_isnumber(o2) || !lua_isnumber(o3))
{ lua_error ("incorrect arguments to function `strsub'"); return; }
s = strdup (lua_getstring(o1));
start = lua_getnumber (o2);
end = lua_getnumber (o3);
if (end < start || start < 1 || end > strlen(s))
lua_pushstring ("");
else
{
s[end] = 0;
lua_pushstring (&s[start-1]);
}
free (s);
}
/*
** Convert a string to lower case.
** LUA interface:
** lowercase = strlower (string)
*/
static void str_lower (void)
{
char *s, *c;
lua_Object o = lua_getparam (1);
if (!lua_isstring(o))
{ lua_error ("incorrect arguments to function `strlower'"); return; }
c = s = strdup(lua_getstring(o));
while (*c != 0)
{
*c = tolower(*c);
c++;
}
lua_pushstring(s);
free(s);
}
/*
** Convert a string to upper case.
** LUA interface:
** uppercase = strupper (string)
*/
static void str_upper (void)
{
char *s, *c;
lua_Object o = lua_getparam (1);
if (!lua_isstring(o))
{ lua_error ("incorrect arguments to function `strlower'"); return; }
c = s = strdup(lua_getstring(o));
while (*c != 0)
{
*c = toupper(*c);
c++;
}
lua_pushstring(s);
free(s);
}
/*
** Open string library
*/
void strlib_open (void)
{
lua_register ("strfind", str_find);
lua_register ("strlen", str_len);
lua_register ("strsub", str_sub);
lua_register ("strlower", str_lower);
lua_register ("strupper", str_upper);
}

351
table.c Normal file
View File

@@ -0,0 +1,351 @@
/*
** table.c
** Module to control static tables
** TeCGraf - PUC-Rio
** 11 May 93
*/
#include <stdlib.h>
#include <string.h>
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "lua.h"
#define streq(s1,s2) (strcmp(s1,s2)==0)
#ifndef MAXSYMBOL
#define MAXSYMBOL 512
#endif
static Symbol tablebuffer[MAXSYMBOL] = {
{"type",{T_CFUNCTION,{lua_type}}},
{"tonumber",{T_CFUNCTION,{lua_obj2number}}},
{"next",{T_CFUNCTION,{lua_next}}},
{"nextvar",{T_CFUNCTION,{lua_nextvar}}},
{"print",{T_CFUNCTION,{lua_print}}}
};
Symbol *lua_table=tablebuffer;
Word lua_ntable=5;
#ifndef MAXCONSTANT
#define MAXCONSTANT 256
#endif
static char *constantbuffer[MAXCONSTANT] = {"mark","nil","number",
"string","table",
"function","cfunction"
};
char **lua_constant = constantbuffer;
Word lua_nconstant=T_CFUNCTION+1;
#ifndef MAXSTRING
#define MAXSTRING 512
#endif
static char *stringbuffer[MAXSTRING];
char **lua_string = stringbuffer;
Word lua_nstring=0;
#ifndef MAXARRAY
#define MAXARRAY 512
#endif
static Hash *arraybuffer[MAXARRAY];
Hash **lua_array = arraybuffer;
Word lua_narray=0;
#define MAXFILE 20
char *lua_file[MAXFILE];
int lua_nfile;
/*
** Given a name, search it at symbol table and return its index. If not
** found, allocate at end of table, checking oveflow and return its index.
** On error, return -1.
*/
int lua_findsymbol (char *s)
{
int i;
for (i=0; i<lua_ntable; i++)
if (streq(s,s_name(i)))
return i;
if (lua_ntable >= MAXSYMBOL-1)
{
lua_error ("symbol table overflow");
return -1;
}
s_name(lua_ntable) = strdup(s);
if (s_name(lua_ntable) == NULL)
{
lua_error ("not enough memory");
return -1;
}
s_tag(lua_ntable++) = T_NIL;
return (lua_ntable-1);
}
/*
** Given a constant string, eliminate its delimeters (" or '), search it at
** constant table and return its index. If not found, allocate at end of
** the table, checking oveflow and return its index.
**
** For each allocation, the function allocate a extra char to be used to
** mark used string (it's necessary to deal with constant and string
** uniformily). The function store at the table the second position allocated,
** that represents the beginning of the real string. On error, return -1.
**
*/
int lua_findenclosedconstant (char *s)
{
int i, j, l=strlen(s);
char *c = calloc (l, sizeof(char)); /* make a copy */
c++; /* create mark space */
/* introduce scape characters */
for (i=1,j=0; i<l-1; i++)
{
if (s[i] == '\\')
{
switch (s[++i])
{
case 'n': c[j++] = '\n'; break;
case 't': c[j++] = '\t'; break;
case 'r': c[j++] = '\r'; break;
default : c[j++] = '\\'; c[j++] = c[i]; break;
}
}
else
c[j++] = s[i];
}
c[j++] = 0;
for (i=0; i<lua_nconstant; i++)
if (streq(c,lua_constant[i]))
{
free (c-1);
return i;
}
if (lua_nconstant >= MAXCONSTANT-1)
{
lua_error ("lua: constant string table overflow");
return -1;
}
lua_constant[lua_nconstant++] = c;
return (lua_nconstant-1);
}
/*
** Given a constant string, search it at constant table and return its index.
** If not found, allocate at end of the table, checking oveflow and return
** its index.
**
** For each allocation, the function allocate a extra char to be used to
** mark used string (it's necessary to deal with constant and string
** uniformily). The function store at the table the second position allocated,
** that represents the beginning of the real string. On error, return -1.
**
*/
int lua_findconstant (char *s)
{
int i;
for (i=0; i<lua_nconstant; i++)
if (streq(s,lua_constant[i]))
return i;
if (lua_nconstant >= MAXCONSTANT-1)
{
lua_error ("lua: constant string table overflow");
return -1;
}
{
char *c = calloc(strlen(s)+2,sizeof(char));
c++; /* create mark space */
lua_constant[lua_nconstant++] = strcpy(c,s);
}
return (lua_nconstant-1);
}
/*
** Mark an object if it is a string or a unmarked array.
*/
void lua_markobject (Object *o)
{
if (tag(o) == T_STRING)
lua_markstring (svalue(o)) = 1;
else if (tag(o) == T_ARRAY && markarray(avalue(o)) == 0)
lua_hashmark (avalue(o));
}
/*
** Mark all strings and arrays used by any object stored at symbol table.
*/
static void lua_marktable (void)
{
int i;
for (i=0; i<lua_ntable; i++)
lua_markobject (&s_object(i));
}
/*
** Simulate a garbage colection. When string table or array table overflows,
** this function check if all allocated strings and arrays are in use. If
** there are unused ones, pack (compress) the tables.
*/
static void lua_pack (void)
{
lua_markstack ();
lua_marktable ();
{ /* pack string */
int i, j;
for (i=j=0; i<lua_nstring; i++)
if (lua_markstring(lua_string[i]) == 1)
{
lua_string[j++] = lua_string[i];
lua_markstring(lua_string[i]) = 0;
}
else
{
free (lua_string[i]-1);
}
lua_nstring = j;
}
{ /* pack array */
int i, j;
for (i=j=0; i<lua_narray; i++)
if (markarray(lua_array[i]) == 1)
{
lua_array[j++] = lua_array[i];
markarray(lua_array[i]) = 0;
}
else
{
lua_hashdelete (lua_array[i]);
}
lua_narray = j;
}
}
/*
** Allocate a new string at string table. The given string is already
** allocated with mark space and the function puts it at the end of the
** table, checking overflow, and returns its own pointer, or NULL on error.
*/
char *lua_createstring (char *s)
{
if (s == NULL) return NULL;
if (lua_nstring >= MAXSTRING-1)
{
lua_pack ();
if (lua_nstring >= MAXSTRING-1)
{
lua_error ("string table overflow");
return NULL;
}
}
lua_string[lua_nstring++] = s;
return s;
}
/*
** Allocate a new array, already created, at array table. The function puts
** it at the end of the table, checking overflow, and returns its own pointer,
** or NULL on error.
*/
void *lua_createarray (void *a)
{
if (a == NULL) return NULL;
if (lua_narray >= MAXARRAY-1)
{
lua_pack ();
if (lua_narray >= MAXARRAY-1)
{
lua_error ("indexed table overflow");
return NULL;
}
}
lua_array[lua_narray++] = a;
return a;
}
/*
** Add a file name at file table, checking overflow. This function also set
** the external variable "lua_filename" with the function filename set.
** Return 0 on success or 1 on error.
*/
int lua_addfile (char *fn)
{
if (lua_nfile >= MAXFILE-1)
{
lua_error ("too many files");
return 1;
}
if ((lua_file[lua_nfile++] = strdup (fn)) == NULL)
{
lua_error ("not enough memory");
return 1;
}
return 0;
}
/*
** Return the last file name set.
*/
char *lua_filename (void)
{
return lua_file[lua_nfile-1];
}
/*
** Internal function: return next global variable
*/
void lua_nextvar (void)
{
int index;
Object *o = lua_getparam (1);
if (o == NULL)
{ lua_error ("too few arguments to function `nextvar'"); return; }
if (lua_getparam (2) != NULL)
{ lua_error ("too many arguments to function `nextvar'"); return; }
if (tag(o) == T_NIL)
{
index = 0;
}
else if (tag(o) != T_STRING)
{
lua_error ("incorrect argument to function `nextvar'");
return;
}
else
{
for (index=0; index<lua_ntable; index++)
if (streq(s_name(index),svalue(o))) break;
if (index == lua_ntable)
{
lua_error ("name not found in function `nextvar'");
return;
}
index++;
while (index < lua_ntable-1 && tag(&s_object(index)) == T_NIL) index++;
if (index == lua_ntable-1)
{
lua_pushnil();
lua_pushnil();
return;
}
}
{
Object name;
tag(&name) = T_STRING;
svalue(&name) = lua_createstring(lua_strdup(s_name(index)));
if (lua_pushobject (&name)) return;
if (lua_pushobject (&s_object(index))) return;
}
}

39
table.h Normal file
View File

@@ -0,0 +1,39 @@
/*
** table.c
** Module to control static tables
** TeCGraf - PUC-Rio
** 11 May 93
*/
#ifndef table_h
#define table_h
extern Symbol *lua_table;
extern Word lua_ntable;
extern char **lua_constant;
extern Word lua_nconstant;
extern char **lua_string;
extern Word lua_nstring;
extern Hash **lua_array;
extern Word lua_narray;
extern char *lua_file[];
extern int lua_nfile;
#define lua_markstring(s) (*((s)-1))
int lua_findsymbol (char *s);
int lua_findenclosedconstant (char *s);
int lua_findconstant (char *s);
void lua_markobject (Object *o);
char *lua_createstring (char *s);
void *lua_createarray (void *a);
int lua_addfile (char *fn);
char *lua_filename (void);
void lua_nextvar (void);
#endif

15
test.lua Normal file
View File

@@ -0,0 +1,15 @@
$debug
function somaP (x1,y1,x2,y2)
return x1+x2, y1+y2
end
function norma (x,y)
return x*x+y*y
end
function retorno_multiplo ()
print (norma(somaP(2,3,4,5)))
end

35
type.lua Normal file
View File

@@ -0,0 +1,35 @@
$debug
function check (object, class)
local v = next(object,nil);
while v ~= nil do
if class[v] = nil then print("unknown field: " .. v)
elseif type(object[v]) ~= class[v].type
then print("wrong type for field " .. v)
end
v = next(object,v);
end
v = next(class,nil);
while v ~= nil do
if object[v] = nil then
if class[v].default ~= nil then
object[v] = class[v].default
else print("field "..v.." not initialized")
end
end
v = next(class,v);
end
end
typetrilha = @{x = @{default = 0, type = "number"},
y = @{default = 0, type = "number"},
name = @{type = "string"}
}
function trilha (t) check(t,typetrilha) end
t1 = @trilha{ x = 4, name = "3"}
a = "na".."me"


1639
y_tab.c Normal file

File diff suppressed because it is too large Load Diff

35
y_tab.h Normal file
View File

@@ -0,0 +1,35 @@
typedef union
{
int vInt;
long vLong;
float vFloat;
Word vWord;
Byte *pByte;
} YYSTYPE;
extern YYSTYPE yylval;
# define NIL 257
# define IF 258
# define THEN 259
# define ELSE 260
# define ELSEIF 261
# define WHILE 262
# define DO 263
# define REPEAT 264
# define UNTIL 265
# define END 266
# define RETURN 267
# define LOCAL 268
# define NUMBER 269
# define FUNCTION 270
# define NAME 271
# define STRING 272
# define DEBUG 273
# define NOT 274
# define AND 275
# define OR 276
# define NE 277
# define LE 278
# define GE 279
# define CONC 280
# define UNARY 281