commit 41fd23287aae60354c264be8f1807bccd937fbf1
parent be7aa3854be4c8d9203637955a064439f240951f
Author: Waldemar Celes <celes@tecgraf.puc-rio.br>
Date: Fri, 5 Aug 1994 16:30:50 -0300
Implementacao da definicao e chamada de METODOS.
Diffstat:
M | lua.stx | | | 155 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
M | opcode.c | | | 17 | +++++++++++++---- |
M | opcode.h | | | 11 | ++++++++++- |
3 files changed, 148 insertions(+), 35 deletions(-)
diff --git a/lua.stx b/lua.stx
@@ -1,6 +1,6 @@
%{
-char *rcs_luastx = "$Id: lua.stx,v 2.5 1994/07/19 21:27:18 celes Exp $";
+char *rcs_luastx = "$Id: lua.stx,v 2.6 1994/08/03 14:15:46 celes Exp celes $";
#include <stdio.h>
#include <stdlib.h>
@@ -77,6 +77,16 @@ static void code_float (float n)
code_byte(code.m.c4);
}
+static void code_code (Byte *b)
+{
+ CodeCode code;
+ code.b = b;
+ code_byte(code.m.c1);
+ code_byte(code.m.c2);
+ code_byte(code.m.c3);
+ code_byte(code.m.c4);
+}
+
static void code_word_at (Byte *p, Word n)
{
CodeWord code;
@@ -185,6 +195,21 @@ static void code_number (float f)
incr_ntemp();
}
+static void init_function (void)
+{
+ if (code == NULL) /* first function */
+ {
+ code = (Byte *) calloc(CODE_BLOCK, sizeof(Byte));
+ if (code == NULL)
+ {
+ lua_error("not enough memory");
+ err = 1;
+ }
+ maxcode = CODE_BLOCK;
+ }
+}
+
+
%}
@@ -205,9 +230,10 @@ static void code_number (float f)
%token IF THEN ELSE ELSEIF WHILE DO REPEAT UNTIL END
%token RETURN
%token LOCAL
+%token FUNCTION
%token <vFloat> NUMBER
-%token <vWord> FUNCTION STRING
-%token <pChar> NAME
+%token <vWord> STRING
+%token <pChar> NAME
%token <vInt> DEBUG
%type <vLong> PrepJump
@@ -215,7 +241,8 @@ static void code_number (float f)
%type <vInt> fieldlist, localdeclist
%type <vInt> ffieldlist, ffieldlist1
%type <vInt> lfieldlist, lfieldlist1
-%type <vLong> var, objectname
+%type <vInt> functionvalue
+%type <vLong> var, singlevar, objectname
%left AND OR
@@ -240,21 +267,13 @@ functionlist : /* empty */
maincode=pc; initcode=basepc; maxmain=maxcurr;
}
| functionlist function
+ | functionlist method
| functionlist setdebug
;
-
+
function : FUNCTION NAME
- {
- if (code == NULL) /* first function */
- {
- code = (Byte *) calloc(CODE_BLOCK, sizeof(Byte));
- if (code == NULL)
- {
- lua_error("not enough memory");
- err = 1;
- }
- maxcode = CODE_BLOCK;
- }
+ {
+ init_function();
pc=0; basepc=code; maxcurr=maxcode;
nlocalvar=0;
$<vWord>$ = lua_findsymbol($2);
@@ -284,11 +303,62 @@ function : FUNCTION NAME
memcpy (s_bvalue($<vWord>3), basepc, pc*sizeof(Byte));
code = basepc; maxcode=maxcurr;
#if LISTING
-PrintCode(code,code+pc);
+ PrintCode(code,code+pc);
#endif
}
;
+method : FUNCTION NAME { $<vWord>$ = lua_findsymbol($2); } ':' NAME
+ {
+ init_function();
+ pc=0; basepc=code; maxcurr=maxcode;
+ nlocalvar=0;
+ localvar[nlocalvar]=lua_findsymbol("self"); /* self param. */
+ add_nlocalvar(1);
+ $<vWord>$ = lua_findconstant($5);
+ }
+ '(' parlist ')'
+ {
+ if (lua_debug)
+ {
+ code_byte(SETFUNCTION);
+ code_word(lua_nfile-1);
+ code_word($<vWord>6);
+ }
+ lua_codeadjust (0);
+ }
+ block
+ END
+ {
+ Byte *b;
+ if (lua_debug) code_byte(RESET);
+ code_byte(RETCODE); code_byte(nlocalvar);
+ b = calloc (pc, sizeof(Byte));
+ if (b == NULL)
+ {
+ lua_error("not enough memory");
+ err = 1;
+ }
+ memcpy (b, basepc, pc*sizeof(Byte));
+ code = basepc; maxcode=maxcurr;
+#if LISTING
+ PrintCode(code,code+pc);
+#endif
+ /* assign function to table field */
+ pc=maincode; basepc=initcode; maxcurr=maxmain;
+ nlocalvar=0;
+
+ lua_pushvar($<vWord>3+1);
+ code_byte(PUSHSTRING);
+ code_word($<vWord>6);
+ code_byte(PUSHFUNCTION);
+ code_code(b);
+ code_byte(STOREINDEXED0);
+
+ maincode=pc; initcode=basepc; maxmain=maxcurr;
+ }
+ ;
+
statlist : /* empty */
| statlist stat sc
;
@@ -499,10 +569,23 @@ dimension : /* empty */ { code_byte(PUSHNIL); incr_ntemp();}
| expr1
;
-functioncall : functionvalue {code_byte(PUSHMARK); $<vInt>$ = ntemp; incr_ntemp();}
- '(' exprlist ')' { code_byte(CALLFUNC); ntemp = $<vInt>2-1;}
+functioncall : functionvalue
+ {
+ code_byte(PUSHMARK); $<vInt>$ = ntemp; incr_ntemp();
+ if ($1 != 0) lua_pushvar($1);
+ }
+ '(' exprlist ')' { code_byte(CALLFUNC); ntemp = $<vInt>2-1;}
-functionvalue : var {lua_pushvar ($1); }
+functionvalue : var {lua_pushvar ($1); $$ = 0; }
+ | singlevar ':' NAME
+ {
+ $$ = $1;
+ lua_pushvar($1);
+ code_byte(PUSHSTRING);
+ code_word(lua_findconstant($3));
+ incr_ntemp();
+ lua_pushvar(0);
+ }
;
exprlist : /* empty */ { $$ = 1; }
@@ -590,16 +673,7 @@ varlist1 : var
}
;
-var : NAME
- {
- Word s = lua_findsymbol($1);
- int local = lua_localname (s);
- if (local == -1) /* global var */
- $$ = s + 1; /* return positive value */
- else
- $$ = -(local+1); /* return negative value */
- }
-
+var : singlevar { $$ = $1; }
| var {lua_pushvar ($1);} '[' expr1 ']'
{
$$ = 0; /* indexed variable */
@@ -612,6 +686,17 @@ var : NAME
}
;
+singlevar : NAME
+ {
+ Word s = lua_findsymbol($1);
+ int local = lua_localname (s);
+ if (local == -1) /* global var */
+ $$ = s + 1; /* return positive value */
+ else
+ $$ = -(local+1); /* return negative value */
+ }
+ ;
+
localdeclist : NAME {localvar[nlocalvar]=lua_findsymbol($1); $$ = 1;}
| localdeclist ',' NAME
{
@@ -799,6 +884,16 @@ static void PrintCode (Byte *code, Byte *end)
printf ("%d PUSHSTRING %d\n", n, c.w);
}
break;
+ case PUSHFUNCTION:
+ {
+ CodeCode c;
+ int n = p-code;
+ p++;
+ get_code(c,p);
+ printf ("%d PUSHFUNCTION %p\n", n, c.b);
+ }
+ break;
+
case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3:
case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7:
case PUSHLOCAL8: case PUSHLOCAL9:
diff --git a/opcode.c b/opcode.c
@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_opcode="$Id: opcode.c,v 2.2 1994/07/19 21:27:18 celes Exp celes $";
+char *rcs_opcode="$Id: opcode.c,v 2.3 1994/08/03 14:15:46 celes Exp celes $";
#include <stdio.h>
#include <stdlib.h>
@@ -211,6 +211,14 @@ int lua_execute (Byte *pc)
tag(top) = T_STRING; svalue(top++) = lua_constant[code.w];
}
break;
+
+ case PUSHFUNCTION:
+ {
+ CodeCode code;
+ get_code(code,pc);
+ tag(top) = T_FUNCTION; bvalue(top++) = code.b;
+ }
+ break;
case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2:
case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5:
@@ -235,7 +243,7 @@ int lua_execute (Byte *pc)
return 1;
}
{
- Object *h = lua_hashdefine (avalue(top-1), top);
+ Object *h = lua_hashget (avalue(top-1), top);
if (h == NULL) return 1;
*(top-1) = *h;
}
@@ -773,7 +781,7 @@ Object *lua_getfield (Object *object, char *field)
Object ref;
tag(&ref) = T_STRING;
svalue(&ref) = lua_createstring(field);
- return (lua_hashdefine(avalue(object), &ref));
+ return (lua_hashget(avalue(object), &ref));
}
}
@@ -791,7 +799,7 @@ Object *lua_getindexed (Object *object, float index)
Object ref;
tag(&ref) = T_NUMBER;
nvalue(&ref) = index;
- return (lua_hashdefine(avalue(object), &ref));
+ return (lua_hashget(avalue(object), &ref));
}
}
@@ -1025,6 +1033,7 @@ void lua_print (void)
{
if (lua_isnumber(obj)) printf("%g\n",lua_getnumber (obj));
else if (lua_isstring(obj)) printf("%s\n",lua_getstring (obj));
+ else if (lua_isfunction(obj)) printf("function: %p\n",bvalue(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);
diff --git a/opcode.h b/opcode.h
@@ -1,6 +1,6 @@
/*
** TeCGraf - PUC-Rio
-** $Id: opcode.h,v 2.1 1994/04/20 22:07:57 celes Exp celes $
+** $Id: opcode.h,v 2.2 1994/07/19 21:27:18 celes Exp celes $
*/
#ifndef opcode_h
@@ -34,6 +34,12 @@ typedef union
float f;
} CodeFloat;
+typedef union
+{
+ struct {char c1; char c2; char c3; char c4;} m;
+ Byte *b;
+} CodeCode;
+
typedef enum
{
PUSHNIL,
@@ -42,6 +48,7 @@ typedef enum
PUSHWORD,
PUSHFLOAT,
PUSHSTRING,
+ PUSHFUNCTION,
PUSHLOCAL0, PUSHLOCAL1, PUSHLOCAL2, PUSHLOCAL3, PUSHLOCAL4,
PUSHLOCAL5, PUSHLOCAL6, PUSHLOCAL7, PUSHLOCAL8, PUSHLOCAL9,
PUSHLOCAL,
@@ -143,6 +150,8 @@ typedef struct
#define get_word(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;}
#define get_float(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\
code.m.c3 = *pc++; code.m.c4 = *pc++;}
+#define get_code(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\
+ code.m.c3 = *pc++; code.m.c4 = *pc++;}