diff options
author | Lua Team <team@lua.org> | 1995-02-07 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 1995-02-07 12:00:00 +0000 |
commit | a8b6ba0954edb9e0e669e1f451b9a8f145ce5166 (patch) | |
tree | 35e9e9999968c4f13a25a5f647203456f044274a /src/yacc/lua.stx | |
parent | 944fc7d7d95575f2b8023c1f3d4ac19e1369fc76 (diff) | |
download | lua-github-2.1.tar.gz |
Lua 2.12.1
Diffstat (limited to 'src/yacc/lua.stx')
-rw-r--r-- | src/yacc/lua.stx | 847 |
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: |