diff options
| -rw-r--r-- | lparser.c | 206 |
1 files changed, 100 insertions, 106 deletions
| @@ -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 | */ |
| 50 | static void body (LexState *ls, expdesc *v, int needself, int line); | ||
| 51 | static void chunk (LexState *ls); | 50 | static void chunk (LexState *ls); |
| 52 | static void constructor (LexState *ls, expdesc *v); | ||
| 53 | static void expr (LexState *ls, expdesc *v); | 51 | static 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 | ||
| 403 | static 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 | |||
| 416 | static 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 | ||
| 520 | static 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 | |||
| 537 | static 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 | |||
| 554 | static 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 | |||
| 567 | static 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 | |||
| 708 | static UnOpr getunopr (int op) { | 737 | static 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 | ||
| 1271 | static 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 | |||
| 1288 | static 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 | |||
| 1308 | static void chunk (LexState *ls) { | 1301 | static 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 | /* }====================================================================== */ | ||
