summaryrefslogtreecommitdiff
path: root/src/yacc/lua.stx
diff options
context:
space:
mode:
authorLua Team <team@lua.org>1995-02-07 12:00:00 +0000
committerrepogen <>1995-02-07 12:00:00 +0000
commita8b6ba0954edb9e0e669e1f451b9a8f145ce5166 (patch)
tree35e9e9999968c4f13a25a5f647203456f044274a /src/yacc/lua.stx
parent944fc7d7d95575f2b8023c1f3d4ac19e1369fc76 (diff)
downloadlua-github-2.1.tar.gz
Lua 2.12.1
Diffstat (limited to 'src/yacc/lua.stx')
-rw-r--r--src/yacc/lua.stx847
1 files changed, 434 insertions, 413 deletions
diff --git a/src/yacc/lua.stx b/src/yacc/lua.stx
index 118a240c..9c818708 100644
--- a/src/yacc/lua.stx
+++ b/src/yacc/lua.stx
@@ -1,35 +1,43 @@
%{
-char *rcs_luastx = "$Id: lua.stx,v 2.4 1994/04/20 16:22:21 celes Exp $";
+char *rcs_luastx = "$Id: lua.stx,v 3.17 1995/01/13 22:11:12 roberto Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "mm.h"
-
+#include "mem.h"
#include "opcode.h"
#include "hash.h"
#include "inout.h"
+#include "tree.h"
#include "table.h"
#include "lua.h"
+/* to avoid warnings generated by yacc */
+int yyparse (void);
+#define malloc luaI_malloc
+#define realloc luaI_realloc
+#define free luaI_free
+
+#ifndef LISTING
#define LISTING 0
+#endif
-#ifndef GAPCODE
-#define GAPCODE 50
+#ifndef CODE_BLOCK
+#define CODE_BLOCK 256
#endif
-static Word maxcode;
-static Word maxmain;
-static Word maxcurr ;
-static Byte *code = NULL;
-static Byte *initcode;
+static int maxcode;
+static int maxmain;
+static Long maxcurr; /* to allow maxcurr *= 2 without overflow */
+static Byte *funcCode = NULL;
+static Byte **initcode;
static Byte *basepc;
-static Word maincode;
-static Word pc;
+static int maincode;
+static int pc;
#define MAXVAR 32
-static long varbuffer[MAXVAR]; /* variables in an assignment list;
+static Long varbuffer[MAXVAR]; /* variables in an assignment list;
it's long to store negative Word values */
static int nvarbuffer=0; /* number of variables at a list */
@@ -39,8 +47,7 @@ static int nlocalvar=0; /* number of local variables */
#define MAXFIELDS FIELDS_PER_FLUSH*2
static Word fields[MAXFIELDS]; /* fieldnames to be flushed */
static int nfields=0;
-static int ntemp; /* number of temporary var into stack */
-static int err; /* flag to indicate error */
+
/* Internal functions */
@@ -48,13 +55,12 @@ static void code_byte (Byte c)
{
if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */
{
- maxcurr += GAPCODE;
- basepc = (Byte *)realloc(basepc, maxcurr*sizeof(Byte));
- if (basepc == NULL)
- {
- lua_error ("not enough memory");
- err = 1;
- }
+ if (maxcurr >= MAX_INT)
+ lua_error("code size overflow");
+ maxcurr *= 2;
+ if (maxcurr >= MAX_INT)
+ maxcurr = MAX_INT;
+ basepc = growvector(basepc, maxcurr, Byte);
}
basepc[pc++] = c;
}
@@ -77,6 +83,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;
@@ -90,10 +106,7 @@ static void push_field (Word name)
if (nfields < STACKGAP-1)
fields[nfields++] = name;
else
- {
lua_error ("too many fields in a constructor");
- err = 1;
- }
}
static void flush_record (int n)
@@ -104,7 +117,6 @@ static void flush_record (int n)
code_byte(n);
for (i=0; i<n; i++)
code_word(fields[--nfields]);
- ntemp -= n;
}
static void flush_list (int m, int n)
@@ -113,34 +125,22 @@ static void flush_list (int m, int n)
if (m == 0)
code_byte(STORELIST0);
else
+ if (m < 255)
{
code_byte(STORELIST);
code_byte(m);
}
+ else
+ lua_error ("list constructor too long");
code_byte(n);
- ntemp-=n;
-}
-
-static void incr_ntemp (void)
-{
- if (ntemp+nlocalvar+MAXVAR+1 < STACKGAP)
- ntemp++;
- else
- {
- lua_error ("stack overflow");
- err = 1;
- }
}
static void add_nlocalvar (int n)
{
- if (ntemp+nlocalvar+MAXVAR+n < STACKGAP)
+ if (MAX_TEMPS+nlocalvar+MAXVAR+n < STACKGAP)
nlocalvar += n;
else
- {
- lua_error ("too many local variables or expression too complicate");
- err = 1;
- }
+ lua_error ("too many local variables");
}
static void incr_nvarbuffer (void)
@@ -148,14 +148,12 @@ static void incr_nvarbuffer (void)
if (nvarbuffer < MAXVAR-1)
nvarbuffer++;
else
- {
lua_error ("variable buffer overflow");
- err = 1;
- }
}
static void code_number (float f)
-{ Word i = (Word)f;
+{
+ Word i = (Word)f;
if (f == (float)i) /* f has an (short) integer value */
{
if (i <= 2) code_byte(PUSH0 + i);
@@ -175,20 +173,204 @@ static void code_number (float f)
code_byte(PUSHFLOAT);
code_float(f);
}
- incr_ntemp();
}
+/*
+** Search a local name and if find return its index. If do not find return -1
+*/
+static int lua_localname (Word n)
+{
+ int i;
+ for (i=nlocalvar-1; i >= 0; i--)
+ if (n == localvar[i]) return i; /* local var */
+ return -1; /* global var */
+}
+
+/*
+** Push a variable given a number. If number is positive, push global variable
+** indexed by (number -1). If negative, push local indexed by ABS(number)-1.
+** Otherwise, if zero, push indexed variable (record).
+*/
+static void lua_pushvar (Long number)
+{
+ if (number > 0) /* global var */
+ {
+ code_byte(PUSHGLOBAL);
+ code_word(number-1);
+ }
+ else if (number < 0) /* local var */
+ {
+ number = (-number) - 1;
+ if (number < 10) code_byte(PUSHLOCAL0 + number);
+ else
+ {
+ code_byte(PUSHLOCAL);
+ code_byte(number);
+ }
+ }
+ else
+ {
+ code_byte(PUSHINDEXED);
+ }
+}
+
+static void lua_codeadjust (int n)
+{
+ if (n+nlocalvar == 0)
+ code_byte(ADJUST0);
+ else
+ {
+ code_byte(ADJUST);
+ code_byte(n+nlocalvar);
+ }
+}
+
+static void init_function (TreeNode *func)
+{
+ if (funcCode == NULL) /* first function */
+ {
+ funcCode = newvector(CODE_BLOCK, Byte);
+ maxcode = CODE_BLOCK;
+ }
+ pc=0; basepc=funcCode; maxcurr=maxcode;
+ nlocalvar=0;
+ if (lua_debug)
+ {
+ code_byte(SETFUNCTION);
+ code_code((Byte *)luaI_strdup(lua_file[lua_nfile-1]));
+ code_word(luaI_findconstant(func));
+ }
+}
+
+static void codereturn (void)
+{
+ if (lua_debug) code_byte(RESET);
+ if (nlocalvar == 0)
+ code_byte(RETCODE0);
+ else
+ {
+ code_byte(RETCODE);
+ code_byte(nlocalvar);
+ }
+}
+
+static void codedebugline (void)
+{
+ if (lua_debug)
+ {
+ code_byte(SETLINE);
+ code_word(lua_linenumber);
+ }
+}
+
+static void adjust_mult_assign (int vars, int exps, int temps)
+{
+ if (exps < 0)
+ {
+ int r = vars - (-exps-1);
+ if (r >= 0)
+ code_byte(r);
+ else
+ {
+ code_byte(0);
+ lua_codeadjust(temps);
+ }
+ }
+ else if (vars != exps)
+ lua_codeadjust(temps);
+}
+
+static void lua_codestore (int i)
+{
+ if (varbuffer[i] > 0) /* global var */
+ {
+ code_byte(STOREGLOBAL);
+ code_word(varbuffer[i]-1);
+ }
+ else if (varbuffer[i] < 0) /* local var */
+ {
+ int number = (-varbuffer[i]) - 1;
+ if (number < 10) code_byte(STORELOCAL0 + number);
+ else
+ {
+ code_byte(STORELOCAL);
+ code_byte(number);
+ }
+ }
+ else /* indexed var */
+ {
+ int j;
+ int upper=0; /* number of indexed variables upper */
+ int param; /* number of itens until indexed expression */
+ for (j=i+1; j <nvarbuffer; j++)
+ if (varbuffer[j] == 0) upper++;
+ param = upper*2 + i;
+ if (param == 0)
+ code_byte(STOREINDEXED0);
+ else
+ {
+ code_byte(STOREINDEXED);
+ code_byte(param);
+ }
+ }
+}
+
+static void codeIf (Long thenAdd, Long elseAdd)
+{
+ Long elseinit = elseAdd+sizeof(Word)+1;
+ if (pc == elseinit) /* no else */
+ {
+ pc -= sizeof(Word)+1;
+ elseinit = pc;
+ }
+ else
+ {
+ basepc[elseAdd] = JMP;
+ code_word_at(basepc+elseAdd+1, pc-elseinit);
+ }
+ basepc[thenAdd] = IFFJMP;
+ code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1));
+}
+
+static void yyerror (char *s)
+{
+ static char msg[256];
+ sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"",
+ s, lua_lasttext (), lua_linenumber, lua_filename());
+ lua_error (msg);
+}
+
+
+/*
+** Parse LUA code.
+*/
+void lua_parse (Byte **code)
+{
+ initcode = code;
+ *initcode = newvector(CODE_BLOCK, Byte);
+ maincode = 0;
+ maxmain = CODE_BLOCK;
+ if (yyparse ()) lua_error("parse error");
+ (*initcode)[maincode++] = RETCODE0;
+#if LISTING
+{ static void PrintCode (Byte *c, Byte *end);
+ PrintCode(*initcode,*initcode+maincode); }
+#endif
+}
+
+
%}
%union
{
int vInt;
- long vLong;
float vFloat;
char *pChar;
Word vWord;
+ Long vLong;
Byte *pByte;
+ TreeNode *pNode;
}
%start functionlist
@@ -198,25 +380,27 @@ 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 <pNode> NAME
%token <vInt> DEBUG
-%type <vWord> PrepJump
-%type <vInt> expr, exprlist, exprlist1, varlist1, typeconstructor
-%type <vInt> fieldlist, localdeclist
-%type <vInt> ffieldlist, ffieldlist1
-%type <vInt> lfieldlist, lfieldlist1
-%type <vLong> var, objectname
-
+%type <vLong> PrepJump
+%type <vInt> expr, exprlist, exprlist1, varlist1, funcParams, funcvalue
+%type <vInt> fieldlist, localdeclist, decinit
+%type <vInt> ffieldlist1
+%type <vInt> lfieldlist1
+%type <vLong> var, singlevar
+%type <pByte> body
%left AND OR
-%left '=' NE '>' '<' LE GE
+%left EQ NE '>' '<' LE GE
%left CONC
%left '+' '-'
%left '*' '/'
%left UNARY NOT
+%right '^'
%% /* beginning of rules section */
@@ -225,156 +409,115 @@ static void code_number (float f)
functionlist : /* empty */
| functionlist
{
- pc=maincode; basepc=initcode; maxcurr=maxmain;
+ pc=maincode; basepc=*initcode; maxcurr=maxmain;
nlocalvar=0;
}
stat sc
{
- maincode=pc; initcode=basepc; maxmain=maxcurr;
+ maincode=pc; *initcode=basepc; maxmain=maxcurr;
}
| functionlist function
+ | functionlist method
| functionlist setdebug
;
-
+
function : FUNCTION NAME
+ {
+ init_function($2);
+ }
+ body
+ {
+ Word func = luaI_findsymbol($2);
+ s_tag(func) = LUA_T_FUNCTION;
+ s_bvalue(func) = $4;
+ }
+ ;
+
+method : FUNCTION NAME ':' NAME
{
- if (code == NULL) /* first function */
- {
- code = (Byte *) calloc(GAPCODE, sizeof(Byte));
- if (code == NULL)
- {
- lua_error("not enough memory");
- err = 1;
- }
- maxcode = GAPCODE;
- }
- pc=0; basepc=code; maxcurr=maxcode;
- nlocalvar=0;
- $<vWord>$ = lua_findsymbol($2);
+ init_function($4);
+ localvar[nlocalvar]=luaI_findsymbolbyname("self");
+ add_nlocalvar(1);
}
- '(' parlist ')'
+ body
{
- if (lua_debug)
- {
- code_byte(SETFUNCTION);
- code_word(lua_nfile-1);
- code_word($<vWord>3);
- }
- lua_codeadjust (0);
+ /* assign function to table field */
+ pc=maincode; basepc=*initcode; maxcurr=maxmain;
+ nlocalvar=0;
+ lua_pushvar(luaI_findsymbol($2)+1);
+ code_byte(PUSHSTRING);
+ code_word(luaI_findconstant($4));
+ code_byte(PUSHFUNCTION);
+ code_code($6);
+ code_byte(STOREINDEXED0);
+ maincode=pc; *initcode=basepc; maxmain=maxcurr;
}
- block
- END
- {
- if (lua_debug) code_byte(RESET);
- code_byte(RETCODE); code_byte(nlocalvar);
- s_tag($<vWord>3) = T_FUNCTION;
- s_bvalue($<vWord>3) = calloc (pc, sizeof(Byte));
- if (s_bvalue($<vWord>3) == NULL)
- {
- lua_error("not enough memory");
- err = 1;
- }
- memcpy (s_bvalue($<vWord>3), basepc, pc*sizeof(Byte));
- code = basepc; maxcode=maxcurr;
+ ;
+
+body : '(' parlist ')' block END
+ {
+ codereturn();
+ $$ = newvector(pc, Byte);
+ memcpy($$, basepc, pc*sizeof(Byte));
+ funcCode = basepc; maxcode=maxcurr;
#if LISTING
-PrintCode(code,code+pc);
+ PrintCode(funcCode,funcCode+pc);
#endif
- }
- ;
+ }
+ ;
statlist : /* empty */
| statlist stat sc
;
-stat : {
- ntemp = 0;
- if (lua_debug)
- {
- code_byte(SETLINE); code_word(lua_linenumber);
- }
- }
- stat1
-
sc : /* empty */ | ';' ;
+stat : { codedebugline(); } stat1 ;
+
+cond : { codedebugline(); } expr1 ;
stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
- {
- {
- Word elseinit = $6+sizeof(Word)+1;
- if (pc - elseinit == 0) /* no else */
- {
- pc -= sizeof(Word)+1;
- elseinit = pc;
- }
- else
- {
- basepc[$6] = JMP;
- code_word_at(basepc+$6+1, pc - elseinit);
- }
- basepc[$4] = IFFJMP;
- code_word_at(basepc+$4+1,elseinit-($4+sizeof(Word)+1));
- }
- }
-
- | WHILE {$<vWord>$=pc;} expr1 DO PrepJump block PrepJump END
-
+ { codeIf($4, $6); }
+
+ | WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END
{
basepc[$5] = IFFJMP;
code_word_at(basepc+$5+1, pc - ($5 + sizeof(Word)+1));
-
basepc[$7] = UPJMP;
- code_word_at(basepc+$7+1, pc - ($<vWord>2));
+ code_word_at(basepc+$7+1, pc - ($<vLong>2));
}
- | REPEAT {$<vWord>$=pc;} block UNTIL expr1 PrepJump
-
+ | REPEAT {$<vLong>$=pc;} block UNTIL cond PrepJump
{
basepc[$6] = IFFUPJMP;
- code_word_at(basepc+$6+1, pc - ($<vWord>2));
+ code_word_at(basepc+$6+1, pc - ($<vLong>2));
}
-
| varlist1 '=' exprlist1
{
{
int i;
- if ($3 == 0 || nvarbuffer != ntemp - $1 * 2)
- lua_codeadjust ($1 * 2 + nvarbuffer);
+ adjust_mult_assign(nvarbuffer, $3, $1 * 2 + nvarbuffer);
for (i=nvarbuffer-1; i>=0; i--)
lua_codestore (i);
if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0))
lua_codeadjust (0);
}
}
- | functioncall { lua_codeadjust (0); }
- | typeconstructor { lua_codeadjust (0); }
- | LOCAL localdeclist decinit { add_nlocalvar($2); lua_codeadjust (0); }
+ | functioncall { code_byte(0); }
+ | LOCAL localdeclist decinit
+ { add_nlocalvar($2);
+ adjust_mult_assign($2, $3, 0);
+ }
;
elsepart : /* empty */
| ELSE block
- | ELSEIF expr1 THEN PrepJump block PrepJump elsepart
- {
- {
- Word elseinit = $6+sizeof(Word)+1;
- if (pc - elseinit == 0) /* no else */
- {
- pc -= sizeof(Word)+1;
- elseinit = pc;
- }
- else
- {
- basepc[$6] = JMP;
- code_word_at(basepc+$6+1, pc - elseinit);
- }
- basepc[$4] = IFFJMP;
- code_word_at(basepc+$4+1, elseinit - ($4 + sizeof(Word)+1));
- }
- }
+ | ELSEIF cond THEN PrepJump block PrepJump elsepart
+ { codeIf($4, $6); }
;
-block : {$<vInt>$ = nlocalvar;} statlist {ntemp = 0;} ret
+block : {$<vInt>$ = nlocalvar;} statlist ret
{
if (nlocalvar != $<vInt>1)
{
@@ -385,11 +528,10 @@ block : {$<vInt>$ = nlocalvar;} statlist {ntemp = 0;} ret
;
ret : /* empty */
- | { if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}}
- RETURN exprlist sc
- {
- if (lua_debug) code_byte(RESET);
- code_byte(RETCODE); code_byte(nlocalvar);
+ | RETURN { codedebugline(); } exprlist sc
+ {
+ if ($3 < 0) code_byte(MULT_RET);
+ codereturn();
}
;
@@ -400,55 +542,42 @@ PrepJump : /* empty */
code_word (0);
}
-expr1 : expr { if ($1 == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}}
+expr1 : expr { if ($1 == 0) code_byte(1); }
;
-expr : '(' expr ')' { $$ = $2; }
- | expr1 '=' expr1 { code_byte(EQOP); $$ = 1; ntemp--;}
- | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; ntemp--;}
- | expr1 '>' expr1 { code_byte(LEOP); code_byte(NOTOP); $$ = 1; ntemp--;}
- | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; ntemp--;}
- | expr1 LE expr1 { code_byte(LEOP); $$ = 1; ntemp--;}
- | expr1 GE expr1 { code_byte(LTOP); code_byte(NOTOP); $$ = 1; ntemp--;}
- | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; ntemp--;}
- | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; ntemp--;}
- | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; ntemp--;}
- | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; ntemp--;}
- | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; ntemp--;}
- | '+' expr1 %prec UNARY { $$ = 1; }
+expr : '(' expr ')' { $$ = $2; }
+ | expr1 EQ expr1 { code_byte(EQOP); $$ = 1; }
+ | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; }
+ | expr1 '>' expr1 { code_byte(GTOP); $$ = 1; }
+ | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; }
+ | expr1 LE expr1 { code_byte(LEOP); $$ = 1; }
+ | expr1 GE expr1 { code_byte(GEOP); $$ = 1; }
+ | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; }
+ | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; }
+ | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; }
+ | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; }
+ | expr1 '^' expr1 { code_byte(POWOP); $$ = 1; }
+ | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; }
| '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;}
- | typeconstructor { $$ = $1; }
- | '@' '(' dimension ')'
- {
- code_byte(CREATEARRAY);
- $$ = 1;
- }
- | var { lua_pushvar ($1); $$ = 1;}
- | NUMBER { code_number($1); $$ = 1; }
- | STRING
+ | table { $$ = 1; }
+ | varexp { $$ = 1;}
+ | NUMBER { code_number($1); $$ = 1; }
+ | STRING
{
code_byte(PUSHSTRING);
code_word($1);
$$ = 1;
- incr_ntemp();
- }
- | NIL {code_byte(PUSHNIL); $$ = 1; incr_ntemp();}
- | functioncall
- {
- $$ = 0;
- if (lua_debug)
- {
- code_byte(SETLINE); code_word(lua_linenumber);
- }
}
+ | NIL {code_byte(PUSHNIL); $$ = 1; }
+ | functioncall { $$ = 0; }
| NOT expr1 { code_byte(NOTOP); $$ = 1;}
- | expr1 AND PrepJump {code_byte(POP); ntemp--;} expr1
+ | expr1 AND PrepJump {code_byte(POP); } expr1
{
basepc[$3] = ONFJMP;
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
$$ = 1;
}
- | expr1 OR PrepJump {code_byte(POP); ntemp--;} expr1
+ | expr1 OR PrepJump {code_byte(POP); } expr1
{
basepc[$3] = ONTJMP;
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
@@ -456,92 +585,77 @@ expr : '(' expr ')' { $$ = $2; }
}
;
-typeconstructor: '@'
+table :
{
- code_byte(PUSHBYTE);
- $<vWord>$ = pc; code_byte(0);
- incr_ntemp();
code_byte(CREATEARRAY);
+ $<vLong>$ = pc; code_word(0);
}
- objectname fieldlist
+ '{' fieldlist '}'
{
- basepc[$<vWord>2] = $4;
- if ($3 < 0) /* there is no function to be called */
- {
- $$ = 1;
- }
- else
- {
- lua_pushvar ($3+1);
- code_byte(PUSHMARK);
- incr_ntemp();
- code_byte(PUSHOBJECT);
- incr_ntemp();
- code_byte(CALLFUNC);
- ntemp -= 4;
- $$ = 0;
- if (lua_debug)
- {
- code_byte(SETLINE); code_word(lua_linenumber);
- }
- }
+ code_word_at(basepc+$<vLong>1, $3);
}
;
-dimension : /* empty */ { code_byte(PUSHNIL); incr_ntemp();}
- | expr1
+functioncall : funcvalue funcParams
+ { code_byte(CALLFUNC); code_byte($1+$2); }
;
-
-functioncall : functionvalue {code_byte(PUSHMARK); $<vInt>$ = ntemp; incr_ntemp();}
- '(' exprlist ')' { code_byte(CALLFUNC); ntemp = $<vInt>2-1;}
-functionvalue : var {lua_pushvar ($1); }
- ;
-
-exprlist : /* empty */ { $$ = 1; }
+funcvalue : varexp { $$ = 0; }
+ | varexp ':' NAME
+ {
+ code_byte(PUSHSELF);
+ code_word(luaI_findconstant($3));
+ $$ = 1;
+ }
+ ;
+
+funcParams : '(' exprlist ')'
+ { if ($2<0) { code_byte(1); $$ = -$2; } else $$ = $2; }
+ | table { $$ = 1; }
+ ;
+
+exprlist : /* empty */ { $$ = 0; }
| exprlist1 { $$ = $1; }
;
-exprlist1 : expr { $$ = $1; }
- | exprlist1 ',' {if (!$1){lua_codeadjust (ntemp+1); incr_ntemp();}}
- expr {$$ = $4;}
+exprlist1 : expr { if ($1 == 0) $$ = -1; else $$ = 1; }
+ | exprlist1 ',' { if ($1 < 0) code_byte(1); } expr
+ {
+ int r = $1 < 0 ? -$1 : $1;
+ $$ = ($4 == 0) ? -(r+1) : r+1;
+ }
;
-parlist : /* empty */
- | parlist1
+parlist : /* empty */ { lua_codeadjust(0); }
+ | parlist1 { lua_codeadjust(0); }
;
parlist1 : NAME
{
- localvar[nlocalvar]=lua_findsymbol($1);
+ localvar[nlocalvar]=luaI_findsymbol($1);
add_nlocalvar(1);
}
| parlist1 ',' NAME
{
- localvar[nlocalvar]=lua_findsymbol($3);
+ localvar[nlocalvar]=luaI_findsymbol($3);
add_nlocalvar(1);
}
;
-objectname : /* empty */ {$$=-1;}
- | NAME {$$=lua_findsymbol($1);}
- ;
-
-fieldlist : '{' ffieldlist '}'
- {
- flush_record($2%FIELDS_PER_FLUSH);
- $$ = $2;
- }
- | '[' lfieldlist ']'
- {
- flush_list($2/FIELDS_PER_FLUSH, $2%FIELDS_PER_FLUSH);
- $$ = $2;
- }
+fieldlist : /* empty */ { $$ = 0; }
+ | lfieldlist1 lastcomma
+ { $$ = $1; flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); }
+ | ffieldlist1 lastcomma
+ { $$ = $1; flush_record($1%FIELDS_PER_FLUSH); }
+ | lfieldlist1 ';'
+ { flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); }
+ ffieldlist1 lastcomma
+ { $$ = $1+$4; flush_record($4%FIELDS_PER_FLUSH); }
;
-ffieldlist : /* empty */ { $$ = 0; }
- | ffieldlist1 { $$ = $1; }
- ;
+lastcomma : /* empty */
+ | ','
+ ;
ffieldlist1 : ffield {$$=1;}
| ffieldlist1 ',' ffield
@@ -551,16 +665,12 @@ ffieldlist1 : ffield {$$=1;}
}
;
-ffield : NAME {$<vWord>$ = lua_findconstant($1);} '=' expr1
+ffield : NAME '=' expr1
{
- push_field($<vWord>2);
+ push_field(luaI_findconstant($1));
}
;
-lfieldlist : /* empty */ { $$ = 0; }
- | lfieldlist1 { $$ = $1; }
- ;
-
lfieldlist1 : expr1 {$$=1;}
| lfieldlist1 ',' expr1
{
@@ -583,169 +693,49 @@ 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 {lua_pushvar ($1);} '[' expr1 ']'
+var : singlevar { $$ = $1; }
+ | varexp '[' expr1 ']'
{
$$ = 0; /* indexed variable */
}
- | var {lua_pushvar ($1);} '.' NAME
+ | varexp '.' NAME
{
code_byte(PUSHSTRING);
- code_word(lua_findconstant($4)); incr_ntemp();
+ code_word(luaI_findconstant($3));
$$ = 0; /* indexed variable */
}
;
-localdeclist : NAME {localvar[nlocalvar]=lua_findsymbol($1); $$ = 1;}
+singlevar : NAME
+ {
+ Word s = luaI_findsymbol($1);
+ int local = lua_localname (s);
+ if (local == -1) /* global var */
+ $$ = s + 1; /* return positive value */
+ else
+ $$ = -(local+1); /* return negative value */
+ }
+ ;
+
+varexp : var { lua_pushvar($1); }
+ ;
+
+localdeclist : NAME {localvar[nlocalvar]=luaI_findsymbol($1); $$ = 1;}
| localdeclist ',' NAME
{
- localvar[nlocalvar+$1]=lua_findsymbol($3);
+ localvar[nlocalvar+$1]=luaI_findsymbol($3);
$$ = $1+1;
}
;
-decinit : /* empty */
- | '=' exprlist1
+decinit : /* empty */ { $$ = 0; }
+ | '=' exprlist1 { $$ = $2; }
;
setdebug : DEBUG {lua_debug = $1;}
%%
-/*
-** Search a local name and if find return its index. If do not find return -1
-*/
-static int lua_localname (Word n)
-{
- int i;
- for (i=nlocalvar-1; i >= 0; i--)
- if (n == localvar[i]) return i; /* local var */
- return -1; /* global var */
-}
-
-/*
-** Push a variable given a number. If number is positive, push global variable
-** indexed by (number -1). If negative, push local indexed by ABS(number)-1.
-** Otherwise, if zero, push indexed variable (record).
-*/
-static void lua_pushvar (long number)
-{
- if (number > 0) /* global var */
- {
- code_byte(PUSHGLOBAL);
- code_word(number-1);
- incr_ntemp();
- }
- else if (number < 0) /* local var */
- {
- number = (-number) - 1;
- if (number < 10) code_byte(PUSHLOCAL0 + number);
- else
- {
- code_byte(PUSHLOCAL);
- code_byte(number);
- }
- incr_ntemp();
- }
- else
- {
- code_byte(PUSHINDEXED);
- ntemp--;
- }
-}
-
-static void lua_codeadjust (int n)
-{
- code_byte(ADJUST);
- code_byte(n + nlocalvar);
-}
-
-static void lua_codestore (int i)
-{
- if (varbuffer[i] > 0) /* global var */
- {
- code_byte(STOREGLOBAL);
- code_word(varbuffer[i]-1);
- }
- else if (varbuffer[i] < 0) /* local var */
- {
- int number = (-varbuffer[i]) - 1;
- if (number < 10) code_byte(STORELOCAL0 + number);
- else
- {
- code_byte(STORELOCAL);
- code_byte(number);
- }
- }
- else /* indexed var */
- {
- int j;
- int upper=0; /* number of indexed variables upper */
- int param; /* number of itens until indexed expression */
- for (j=i+1; j <nvarbuffer; j++)
- if (varbuffer[j] == 0) upper++;
- param = upper*2 + i;
- if (param == 0)
- code_byte(STOREINDEXED0);
- else
- {
- code_byte(STOREINDEXED);
- code_byte(param);
- }
- }
-}
-
-void yyerror (char *s)
-{
- static char msg[256];
- sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"",
- s, lua_lasttext (), lua_linenumber, lua_filename());
- lua_error (msg);
- err = 1;
-}
-
-int yywrap (void)
-{
- return 1;
-}
-
-
-/*
-** Parse LUA code and execute global statement.
-** Return 0 on success or 1 on error.
-*/
-int lua_parse (void)
-{
- Byte *init = initcode = (Byte *) calloc(GAPCODE, sizeof(Byte));
- maincode = 0;
- maxmain = GAPCODE;
- if (init == NULL)
- {
- lua_error("not enough memory");
- return 1;
- }
- err = 0;
- if (yyparse () || (err==1)) return 1;
- initcode[maincode++] = HALT;
- init = initcode;
-#if LISTING
- PrintCode(init,init+maincode);
-#endif
- if (lua_execute (init)) return 1;
- free(init);
- return 0;
-}
-
-
#if LISTING
static void PrintCode (Byte *code, Byte *end)
@@ -792,6 +782,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:
@@ -811,8 +811,6 @@ static void PrintCode (Byte *code, Byte *end)
}
break;
case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break;
- case PUSHMARK: printf ("%d PUSHMARK\n", (p++)-code); break;
- case PUSHOBJECT: printf ("%d PUSHOBJECT\n", (p++)-code); break;
case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3:
case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7:
case STORELOCAL8: case STORELOCAL9:
@@ -832,6 +830,15 @@ static void PrintCode (Byte *code, Byte *end)
printf ("%d STOREGLOBAL %d\n", n, c.w);
}
break;
+ case PUSHSELF:
+ {
+ CodeWord c;
+ int n = p-code;
+ p++;
+ get_word(c,p);
+ printf ("%d PUSHSELF %d\n", n, c.w);
+ }
+ break;
case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break;
case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p));
p++;
@@ -848,11 +855,20 @@ static void PrintCode (Byte *code, Byte *end)
printf("%d STORERECORD %d\n", p-code, *(++p));
p += *p*sizeof(Word) + 1;
break;
+ case ADJUST0: printf ("%d ADJUST0\n", (p++)-code); break;
case ADJUST:
printf ("%d ADJUST %d\n", p-code, *(++p));
p++;
break;
- case CREATEARRAY: printf ("%d CREATEARRAY\n", (p++)-code); break;
+ case CREATEARRAY:
+ {
+ CodeWord c;
+ int n = p-code;
+ p++;
+ get_word(c,p);
+ printf ("%d CREATEARRAY %d\n", n, c.w);
+ break;
+ }
case EQOP: printf ("%d EQOP\n", (p++)-code); break;
case LTOP: printf ("%d LTOP\n", (p++)-code); break;
case LEOP: printf ("%d LEOP\n", (p++)-code); break;
@@ -860,6 +876,7 @@ static void PrintCode (Byte *code, Byte *end)
case SUBOP: printf ("%d SUBOP\n", (p++)-code); break;
case MULTOP: printf ("%d MULTOP\n", (p++)-code); break;
case DIVOP: printf ("%d DIVOP\n", (p++)-code); break;
+ case POWOP: printf ("%d POWOP\n", (p++)-code); break;
case CONCOP: printf ("%d CONCOP\n", (p++)-code); break;
case MINUSOP: printf ("%d MINUSOP\n", (p++)-code); break;
case NOTOP: printf ("%d NOTOP\n", (p++)-code); break;
@@ -918,20 +935,24 @@ static void PrintCode (Byte *code, Byte *end)
}
break;
case POP: printf ("%d POP\n", (p++)-code); break;
- case CALLFUNC: printf ("%d CALLFUNC\n", (p++)-code); break;
+ case CALLFUNC:
+ printf ("%d CALLFUNC %d %d\n", p-code, *(p+1), *(p+2));
+ p+=3;
+ break;
+ case RETCODE0: printf ("%d RETCODE0\n", (p++)-code); break;
case RETCODE:
printf ("%d RETCODE %d\n", p-code, *(++p));
p++;
break;
- case HALT: printf ("%d HALT\n", (p++)-code); break;
case SETFUNCTION:
{
- CodeWord c1, c2;
+ CodeCode c1;
+ CodeWord c2;
int n = p-code;
p++;
- get_word(c1,p);
+ get_code(c1,p);
get_word(c2,p);
- printf ("%d SETFUNCTION %d %d\n", n, c1.w, c2.w);
+ printf ("%d SETFUNCTION %s %d\n", n, (char *)c1.b, c2.w);
}
break;
case SETLINE: