first version of vararg facility (plus new function "call").

This commit is contained in:
Roberto Ierusalimschy
1996-05-28 18:07:32 -03:00
parent 9a1948e67d
commit 9863223fbf
7 changed files with 217 additions and 115 deletions

81
lua.stx
View File

@@ -1,9 +1,10 @@
%{
char *rcs_luastx = "$Id: lua.stx,v 3.35 1996/03/08 12:02:37 roberto Exp roberto $";
char *rcs_luastx = "$Id: lua.stx,v 3.36 1996/03/21 16:31:32 roberto Exp roberto $";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "luadebug.h"
#include "mem.h"
@@ -67,49 +68,45 @@ static void yyerror (char *s)
lua_error (msg);
}
static void check_space (int i)
{
if (pc+i>maxcurr-1) /* 1 byte free to code HALT of main code */
maxcurr = growvector(&basepc, maxcurr, Byte, codeEM, MAX_INT);
}
static void code_byte (Byte c)
{
if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */
maxcurr = growvector(&basepc, maxcurr, Byte, codeEM, MAX_INT);
check_space(1);
basepc[pc++] = c;
}
static void code_word (Word n)
{
CodeWord code;
code.w = n;
code_byte(code.m.c1);
code_byte(code.m.c2);
check_space(sizeof(Word));
memcpy(basepc+pc, &n, sizeof(Word));
pc += sizeof(Word);
}
static void code_float (float n)
static void code_float (real n)
{
CodeFloat code;
code.f = n;
code_byte(code.m.c1);
code_byte(code.m.c2);
code_byte(code.m.c3);
code_byte(code.m.c4);
check_space(sizeof(real));
memcpy(basepc+pc, &n, sizeof(real));
pc += sizeof(real);
}
static void code_code (TFunc *tf)
{
CodeCode code;
code.tf = tf;
code_byte(code.m.c1);
code_byte(code.m.c2);
code_byte(code.m.c3);
code_byte(code.m.c4);
check_space(sizeof(TFunc *));
memcpy(basepc+pc, &tf, sizeof(TFunc *));
pc += sizeof(TFunc *);
}
static void code_word_at (Byte *p, int n)
{
CodeWord code;
if ((Word)n != n)
yyerror("block too big");
code.w = (Word)n;
*p++ = code.m.c1;
*p++ = code.m.c2;
Word w = n;
if (w != n)
yyerror("block too big");
memcpy(p, &w, sizeof(Word));
}
static void push_field (Word name)
@@ -322,6 +319,19 @@ static void adjust_mult_assign (int vars, Long exps, int temps)
lua_codeadjust(temps);
}
static int close_parlist (int dots)
{
if (!dots)
lua_codeadjust(0);
else
{
code_byte(VARARGS);
code_byte(nlocalvar);
add_localvar(luaI_createfixedstring("arg"));
}
return lua_linenumber;
}
static void storesinglevar (Long v)
{
if (v > 0) /* global var */
@@ -426,6 +436,7 @@ void lua_parse (TFunc *tf)
%token RETURN
%token LOCAL
%token FUNCTION
%token DOTS
%token <vFloat> NUMBER
%token <vWord> STRING
%token <pTStr> NAME
@@ -440,7 +451,7 @@ void lua_parse (TFunc *tf)
%type <vInt> fieldlist, localdeclist, decinit
%type <vInt> ffieldlist, ffieldlist1, semicolonpart
%type <vInt> lfieldlist, lfieldlist1
%type <vInt> parlist
%type <vInt> parlist, parlist1, par
%type <vLong> var, singlevar, funcname
%type <pFunc> body
@@ -674,13 +685,21 @@ exprlist1 : expr { if ($1 != 0) $$ = $1; else $$ = -1; }
}
;
parlist : /* empty */ { lua_codeadjust(0); $$ = lua_linenumber; }
| parlist1 { lua_codeadjust(0); $$ = lua_linenumber; }
parlist : /* empty */ { $$ = close_parlist(0); }
| parlist1 { $$ = close_parlist($1); }
;
parlist1 : NAME { add_localvar($1); }
| parlist1 ',' NAME { add_localvar($3); }
parlist1 : par { $$ = $1; }
| parlist1 ',' par
{
if ($1)
lua_error("invalid parameter list");
$$ = $3;
}
;
par : NAME { add_localvar($1); $$ = 0; }
| DOTS { $$ = 1; }
fieldlist : lfieldlist
{ flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); }