mirror of
https://github.com/lua/lua.git
synced 2024-11-28 04:33:53 +08:00
make more clear "primitive" recursive definitions
This commit is contained in:
parent
04b143ddf9
commit
0050d983fc
206
lparser.c
206
lparser.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lparser.c,v 1.197 2002/11/22 13:59:04 roberto Exp roberto $
|
||||
** $Id: lparser.c,v 1.198 2002/11/22 16:35:20 roberto Exp roberto $
|
||||
** Lua Parser
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -47,9 +47,7 @@ typedef struct BlockCnt {
|
||||
/*
|
||||
** prototypes for recursive non-terminal functions
|
||||
*/
|
||||
static void body (LexState *ls, expdesc *v, int needself, int line);
|
||||
static void chunk (LexState *ls);
|
||||
static void constructor (LexState *ls, expdesc *v);
|
||||
static void expr (LexState *ls, expdesc *v);
|
||||
|
||||
|
||||
@ -400,69 +398,6 @@ static void luaY_index (LexState *ls, expdesc *v) {
|
||||
}
|
||||
|
||||
|
||||
static int explist1 (LexState *ls, expdesc *v) {
|
||||
/* explist1 -> expr { `,' expr } */
|
||||
int n = 1; /* at least one expression */
|
||||
expr(ls, v);
|
||||
while (testnext(ls, ',')) {
|
||||
luaK_exp2nextreg(ls->fs, v);
|
||||
expr(ls, v);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static void funcargs (LexState *ls, expdesc *f) {
|
||||
FuncState *fs = ls->fs;
|
||||
expdesc args;
|
||||
int base, nparams;
|
||||
int line = ls->linenumber;
|
||||
switch (ls->t.token) {
|
||||
case '(': { /* funcargs -> `(' [ explist1 ] `)' */
|
||||
if (line != ls->lastline)
|
||||
luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
|
||||
next(ls);
|
||||
if (ls->t.token == ')') /* arg list is empty? */
|
||||
args.k = VVOID;
|
||||
else {
|
||||
explist1(ls, &args);
|
||||
luaK_setcallreturns(fs, &args, LUA_MULTRET);
|
||||
}
|
||||
check_match(ls, ')', '(', line);
|
||||
break;
|
||||
}
|
||||
case '{': { /* funcargs -> constructor */
|
||||
constructor(ls, &args);
|
||||
break;
|
||||
}
|
||||
case TK_STRING: { /* funcargs -> STRING */
|
||||
codestring(ls, &args, ls->t.seminfo.ts);
|
||||
next(ls); /* must use `seminfo' before `next' */
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
luaX_syntaxerror(ls, "function arguments expected");
|
||||
return;
|
||||
}
|
||||
}
|
||||
lua_assert(f->k == VNONRELOC);
|
||||
base = f->info; /* base register for call */
|
||||
if (args.k == VCALL)
|
||||
nparams = LUA_MULTRET; /* open call */
|
||||
else {
|
||||
if (args.k != VVOID)
|
||||
luaK_exp2nextreg(fs, &args); /* close last argument */
|
||||
nparams = fs->freereg - (base+1);
|
||||
}
|
||||
init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
|
||||
luaK_fixline(fs, line);
|
||||
fs->freereg = base+1; /* call remove function and arguments and leaves
|
||||
(unless changed) one result */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================================
|
||||
** Rules for Constructors
|
||||
@ -578,11 +513,107 @@ static void constructor (LexState *ls, expdesc *t) {
|
||||
SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */
|
||||
}
|
||||
|
||||
|
||||
/* }====================================================================== */
|
||||
|
||||
|
||||
|
||||
static void parlist (LexState *ls) {
|
||||
/* parlist -> [ param { `,' param } ] */
|
||||
int nparams = 0;
|
||||
int dots = 0;
|
||||
if (ls->t.token != ')') { /* is `parlist' not empty? */
|
||||
do {
|
||||
switch (ls->t.token) {
|
||||
case TK_DOTS: dots = 1; next(ls); break;
|
||||
case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
|
||||
default: luaX_syntaxerror(ls, "<name> or `...' expected");
|
||||
}
|
||||
} while (!dots && testnext(ls, ','));
|
||||
}
|
||||
code_params(ls, nparams, dots);
|
||||
}
|
||||
|
||||
|
||||
static void body (LexState *ls, expdesc *e, int needself, int line) {
|
||||
/* body -> `(' parlist `)' chunk END */
|
||||
FuncState new_fs;
|
||||
open_func(ls, &new_fs);
|
||||
new_fs.f->lineDefined = line;
|
||||
check(ls, '(');
|
||||
if (needself)
|
||||
create_local(ls, "self");
|
||||
parlist(ls);
|
||||
check(ls, ')');
|
||||
chunk(ls);
|
||||
check_match(ls, TK_END, TK_FUNCTION, line);
|
||||
close_func(ls);
|
||||
pushclosure(ls, &new_fs, e);
|
||||
}
|
||||
|
||||
|
||||
static int explist1 (LexState *ls, expdesc *v) {
|
||||
/* explist1 -> expr { `,' expr } */
|
||||
int n = 1; /* at least one expression */
|
||||
expr(ls, v);
|
||||
while (testnext(ls, ',')) {
|
||||
luaK_exp2nextreg(ls->fs, v);
|
||||
expr(ls, v);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static void funcargs (LexState *ls, expdesc *f) {
|
||||
FuncState *fs = ls->fs;
|
||||
expdesc args;
|
||||
int base, nparams;
|
||||
int line = ls->linenumber;
|
||||
switch (ls->t.token) {
|
||||
case '(': { /* funcargs -> `(' [ explist1 ] `)' */
|
||||
if (line != ls->lastline)
|
||||
luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
|
||||
next(ls);
|
||||
if (ls->t.token == ')') /* arg list is empty? */
|
||||
args.k = VVOID;
|
||||
else {
|
||||
explist1(ls, &args);
|
||||
luaK_setcallreturns(fs, &args, LUA_MULTRET);
|
||||
}
|
||||
check_match(ls, ')', '(', line);
|
||||
break;
|
||||
}
|
||||
case '{': { /* funcargs -> constructor */
|
||||
constructor(ls, &args);
|
||||
break;
|
||||
}
|
||||
case TK_STRING: { /* funcargs -> STRING */
|
||||
codestring(ls, &args, ls->t.seminfo.ts);
|
||||
next(ls); /* must use `seminfo' before `next' */
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
luaX_syntaxerror(ls, "function arguments expected");
|
||||
return;
|
||||
}
|
||||
}
|
||||
lua_assert(f->k == VNONRELOC);
|
||||
base = f->info; /* base register for call */
|
||||
if (args.k == VCALL)
|
||||
nparams = LUA_MULTRET; /* open call */
|
||||
else {
|
||||
if (args.k != VVOID)
|
||||
luaK_exp2nextreg(fs, &args); /* close last argument */
|
||||
nparams = fs->freereg - (base+1);
|
||||
}
|
||||
init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
|
||||
luaK_fixline(fs, line);
|
||||
fs->freereg = base+1; /* call remove function and arguments and leaves
|
||||
(unless changed) one result */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================================
|
||||
@ -703,8 +734,6 @@ static void simpleexp (LexState *ls, expdesc *v) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static UnOpr getunopr (int op) {
|
||||
switch (op) {
|
||||
case TK_NOT: return OPR_NOT;
|
||||
@ -788,6 +817,7 @@ static void expr (LexState *ls, expdesc *v) {
|
||||
/* }==================================================================== */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================================
|
||||
** Rules for Statements
|
||||
@ -1268,43 +1298,6 @@ static int statement (LexState *ls) {
|
||||
}
|
||||
|
||||
|
||||
static void parlist (LexState *ls) {
|
||||
/* parlist -> [ param { `,' param } ] */
|
||||
int nparams = 0;
|
||||
int dots = 0;
|
||||
if (ls->t.token != ')') { /* is `parlist' not empty? */
|
||||
do {
|
||||
switch (ls->t.token) {
|
||||
case TK_DOTS: dots = 1; next(ls); break;
|
||||
case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
|
||||
default: luaX_syntaxerror(ls, "<name> or `...' expected");
|
||||
}
|
||||
} while (!dots && testnext(ls, ','));
|
||||
}
|
||||
code_params(ls, nparams, dots);
|
||||
}
|
||||
|
||||
|
||||
static void body (LexState *ls, expdesc *e, int needself, int line) {
|
||||
/* body -> `(' parlist `)' chunk END */
|
||||
FuncState new_fs;
|
||||
open_func(ls, &new_fs);
|
||||
new_fs.f->lineDefined = line;
|
||||
check(ls, '(');
|
||||
if (needself)
|
||||
create_local(ls, "self");
|
||||
parlist(ls);
|
||||
check(ls, ')');
|
||||
chunk(ls);
|
||||
check_match(ls, TK_END, TK_FUNCTION, line);
|
||||
close_func(ls);
|
||||
pushclosure(ls, &new_fs, e);
|
||||
}
|
||||
|
||||
|
||||
/* }====================================================================== */
|
||||
|
||||
|
||||
static void chunk (LexState *ls) {
|
||||
/* chunk -> { stat [`;'] } */
|
||||
int islast = 0;
|
||||
@ -1318,3 +1311,4 @@ static void chunk (LexState *ls) {
|
||||
leavelevel(ls);
|
||||
}
|
||||
|
||||
/* }====================================================================== */
|
||||
|
Loading…
Reference in New Issue
Block a user