aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-22 14:42:53 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-22 14:42:53 -0200
commit0050d983fc2f3cc56442cadd73a93823643ac53d (patch)
tree6abc67442252231122429f72a2a71c9a3d5110a3
parent04b143ddf931f5312209ddfc1d8d14ede6997afd (diff)
downloadlua-0050d983fc2f3cc56442cadd73a93823643ac53d.tar.gz
lua-0050d983fc2f3cc56442cadd73a93823643ac53d.tar.bz2
lua-0050d983fc2f3cc56442cadd73a93823643ac53d.zip
make more clear "primitive" recursive definitions
-rw-r--r--lparser.c206
1 files changed, 100 insertions, 106 deletions
diff --git a/lparser.c b/lparser.c
index 3fbe451c..24a9aa22 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.197 2002/11/22 13:59:04 roberto Exp roberto $ 2** $Id: lparser.c,v 1.198 2002/11/22 16:35:20 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -47,9 +47,7 @@ typedef struct BlockCnt {
47/* 47/*
48** prototypes for recursive non-terminal functions 48** prototypes for recursive non-terminal functions
49*/ 49*/
50static void body (LexState *ls, expdesc *v, int needself, int line);
51static void chunk (LexState *ls); 50static void chunk (LexState *ls);
52static void constructor (LexState *ls, expdesc *v);
53static void expr (LexState *ls, expdesc *v); 51static void expr (LexState *ls, expdesc *v);
54 52
55 53
@@ -400,69 +398,6 @@ static void luaY_index (LexState *ls, expdesc *v) {
400} 398}
401 399
402 400
403static int explist1 (LexState *ls, expdesc *v) {
404 /* explist1 -> expr { `,' expr } */
405 int n = 1; /* at least one expression */
406 expr(ls, v);
407 while (testnext(ls, ',')) {
408 luaK_exp2nextreg(ls->fs, v);
409 expr(ls, v);
410 n++;
411 }
412 return n;
413}
414
415
416static void funcargs (LexState *ls, expdesc *f) {
417 FuncState *fs = ls->fs;
418 expdesc args;
419 int base, nparams;
420 int line = ls->linenumber;
421 switch (ls->t.token) {
422 case '(': { /* funcargs -> `(' [ explist1 ] `)' */
423 if (line != ls->lastline)
424 luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
425 next(ls);
426 if (ls->t.token == ')') /* arg list is empty? */
427 args.k = VVOID;
428 else {
429 explist1(ls, &args);
430 luaK_setcallreturns(fs, &args, LUA_MULTRET);
431 }
432 check_match(ls, ')', '(', line);
433 break;
434 }
435 case '{': { /* funcargs -> constructor */
436 constructor(ls, &args);
437 break;
438 }
439 case TK_STRING: { /* funcargs -> STRING */
440 codestring(ls, &args, ls->t.seminfo.ts);
441 next(ls); /* must use `seminfo' before `next' */
442 break;
443 }
444 default: {
445 luaX_syntaxerror(ls, "function arguments expected");
446 return;
447 }
448 }
449 lua_assert(f->k == VNONRELOC);
450 base = f->info; /* base register for call */
451 if (args.k == VCALL)
452 nparams = LUA_MULTRET; /* open call */
453 else {
454 if (args.k != VVOID)
455 luaK_exp2nextreg(fs, &args); /* close last argument */
456 nparams = fs->freereg - (base+1);
457 }
458 init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
459 luaK_fixline(fs, line);
460 fs->freereg = base+1; /* call remove function and arguments and leaves
461 (unless changed) one result */
462}
463
464
465
466/* 401/*
467** {====================================================================== 402** {======================================================================
468** Rules for Constructors 403** Rules for Constructors
@@ -578,11 +513,107 @@ static void constructor (LexState *ls, expdesc *t) {
578 SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */ 513 SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */
579} 514}
580 515
581
582/* }====================================================================== */ 516/* }====================================================================== */
583 517
584 518
585 519
520static void parlist (LexState *ls) {
521 /* parlist -> [ param { `,' param } ] */
522 int nparams = 0;
523 int dots = 0;
524 if (ls->t.token != ')') { /* is `parlist' not empty? */
525 do {
526 switch (ls->t.token) {
527 case TK_DOTS: dots = 1; next(ls); break;
528 case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
529 default: luaX_syntaxerror(ls, "<name> or `...' expected");
530 }
531 } while (!dots && testnext(ls, ','));
532 }
533 code_params(ls, nparams, dots);
534}
535
536
537static void body (LexState *ls, expdesc *e, int needself, int line) {
538 /* body -> `(' parlist `)' chunk END */
539 FuncState new_fs;
540 open_func(ls, &new_fs);
541 new_fs.f->lineDefined = line;
542 check(ls, '(');
543 if (needself)
544 create_local(ls, "self");
545 parlist(ls);
546 check(ls, ')');
547 chunk(ls);
548 check_match(ls, TK_END, TK_FUNCTION, line);
549 close_func(ls);
550 pushclosure(ls, &new_fs, e);
551}
552
553
554static int explist1 (LexState *ls, expdesc *v) {
555 /* explist1 -> expr { `,' expr } */
556 int n = 1; /* at least one expression */
557 expr(ls, v);
558 while (testnext(ls, ',')) {
559 luaK_exp2nextreg(ls->fs, v);
560 expr(ls, v);
561 n++;
562 }
563 return n;
564}
565
566
567static void funcargs (LexState *ls, expdesc *f) {
568 FuncState *fs = ls->fs;
569 expdesc args;
570 int base, nparams;
571 int line = ls->linenumber;
572 switch (ls->t.token) {
573 case '(': { /* funcargs -> `(' [ explist1 ] `)' */
574 if (line != ls->lastline)
575 luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
576 next(ls);
577 if (ls->t.token == ')') /* arg list is empty? */
578 args.k = VVOID;
579 else {
580 explist1(ls, &args);
581 luaK_setcallreturns(fs, &args, LUA_MULTRET);
582 }
583 check_match(ls, ')', '(', line);
584 break;
585 }
586 case '{': { /* funcargs -> constructor */
587 constructor(ls, &args);
588 break;
589 }
590 case TK_STRING: { /* funcargs -> STRING */
591 codestring(ls, &args, ls->t.seminfo.ts);
592 next(ls); /* must use `seminfo' before `next' */
593 break;
594 }
595 default: {
596 luaX_syntaxerror(ls, "function arguments expected");
597 return;
598 }
599 }
600 lua_assert(f->k == VNONRELOC);
601 base = f->info; /* base register for call */
602 if (args.k == VCALL)
603 nparams = LUA_MULTRET; /* open call */
604 else {
605 if (args.k != VVOID)
606 luaK_exp2nextreg(fs, &args); /* close last argument */
607 nparams = fs->freereg - (base+1);
608 }
609 init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
610 luaK_fixline(fs, line);
611 fs->freereg = base+1; /* call remove function and arguments and leaves
612 (unless changed) one result */
613}
614
615
616
586 617
587/* 618/*
588** {====================================================================== 619** {======================================================================
@@ -703,8 +734,6 @@ static void simpleexp (LexState *ls, expdesc *v) {
703} 734}
704 735
705 736
706
707
708static UnOpr getunopr (int op) { 737static UnOpr getunopr (int op) {
709 switch (op) { 738 switch (op) {
710 case TK_NOT: return OPR_NOT; 739 case TK_NOT: return OPR_NOT;
@@ -788,6 +817,7 @@ static void expr (LexState *ls, expdesc *v) {
788/* }==================================================================== */ 817/* }==================================================================== */
789 818
790 819
820
791/* 821/*
792** {====================================================================== 822** {======================================================================
793** Rules for Statements 823** Rules for Statements
@@ -1268,43 +1298,6 @@ static int statement (LexState *ls) {
1268} 1298}
1269 1299
1270 1300
1271static void parlist (LexState *ls) {
1272 /* parlist -> [ param { `,' param } ] */
1273 int nparams = 0;
1274 int dots = 0;
1275 if (ls->t.token != ')') { /* is `parlist' not empty? */
1276 do {
1277 switch (ls->t.token) {
1278 case TK_DOTS: dots = 1; next(ls); break;
1279 case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
1280 default: luaX_syntaxerror(ls, "<name> or `...' expected");
1281 }
1282 } while (!dots && testnext(ls, ','));
1283 }
1284 code_params(ls, nparams, dots);
1285}
1286
1287
1288static void body (LexState *ls, expdesc *e, int needself, int line) {
1289 /* body -> `(' parlist `)' chunk END */
1290 FuncState new_fs;
1291 open_func(ls, &new_fs);
1292 new_fs.f->lineDefined = line;
1293 check(ls, '(');
1294 if (needself)
1295 create_local(ls, "self");
1296 parlist(ls);
1297 check(ls, ')');
1298 chunk(ls);
1299 check_match(ls, TK_END, TK_FUNCTION, line);
1300 close_func(ls);
1301 pushclosure(ls, &new_fs, e);
1302}
1303
1304
1305/* }====================================================================== */
1306
1307
1308static void chunk (LexState *ls) { 1301static void chunk (LexState *ls) {
1309 /* chunk -> { stat [`;'] } */ 1302 /* chunk -> { stat [`;'] } */
1310 int islast = 0; 1303 int islast = 0;
@@ -1318,3 +1311,4 @@ static void chunk (LexState *ls) {
1318 leavelevel(ls); 1311 leavelevel(ls);
1319} 1312}
1320 1313
1314/* }====================================================================== */