diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-09-20 11:15:18 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-09-20 11:15:18 -0300 |
commit | e10788b2ff735916bbf6b4ba0e040a4568658ca3 (patch) | |
tree | a86c0c40a0d42bd25c3828b02df026523cddb22e | |
parent | 7eb2f1862136d72197a3935e99296c6337305415 (diff) | |
download | lua-e10788b2ff735916bbf6b4ba0e040a4568658ca3.tar.gz lua-e10788b2ff735916bbf6b4ba0e040a4568658ca3.tar.bz2 lua-e10788b2ff735916bbf6b4ba0e040a4568658ca3.zip |
reorganization of `stat' function.
-rw-r--r-- | lparser.c | 172 |
1 files changed, 96 insertions, 76 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.39 1999/08/16 20:52:00 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.40 1999/09/02 13:13:22 roberto Exp roberto $ |
3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -8,18 +8,15 @@ | |||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <string.h> | 9 | #include <string.h> |
10 | 10 | ||
11 | #include "lauxlib.h" | ||
12 | #include "ldo.h" | 11 | #include "ldo.h" |
13 | #include "lfunc.h" | 12 | #include "lfunc.h" |
14 | #include "llex.h" | 13 | #include "llex.h" |
15 | #include "lmem.h" | 14 | #include "lmem.h" |
15 | #include "lobject.h" | ||
16 | #include "lopcodes.h" | 16 | #include "lopcodes.h" |
17 | #include "lparser.h" | 17 | #include "lparser.h" |
18 | #include "lstate.h" | 18 | #include "lstate.h" |
19 | #include "lstring.h" | 19 | #include "lstring.h" |
20 | #include "lua.h" | ||
21 | #include "luadebug.h" | ||
22 | #include "lzio.h" | ||
23 | 20 | ||
24 | 21 | ||
25 | 22 | ||
@@ -136,7 +133,6 @@ static void parlist (LexState *ls); | |||
136 | static void part (LexState *ls, constdesc *cd); | 133 | static void part (LexState *ls, constdesc *cd); |
137 | static void recfield (LexState *ls); | 134 | static void recfield (LexState *ls); |
138 | static void ret (LexState *ls); | 135 | static void ret (LexState *ls); |
139 | static void statlist (LexState *ls); | ||
140 | static void var_or_func (LexState *ls, vardesc *v); | 136 | static void var_or_func (LexState *ls, vardesc *v); |
141 | static void var_or_func_tail (LexState *ls, vardesc *v); | 137 | static void var_or_func_tail (LexState *ls, vardesc *v); |
142 | 138 | ||
@@ -699,46 +695,108 @@ TProtoFunc *luaY_parser (ZIO *z) { | |||
699 | /* GRAMAR RULES */ | 695 | /* GRAMAR RULES */ |
700 | /*============================================================*/ | 696 | /*============================================================*/ |
701 | 697 | ||
702 | static void chunk (LexState *ls) { | ||
703 | /* chunk -> statlist ret */ | ||
704 | statlist(ls); | ||
705 | ret(ls); | ||
706 | } | ||
707 | 698 | ||
708 | static void statlist (LexState *ls) { | 699 | static void chunk (LexState *ls) { |
709 | /* statlist -> { stat [;] } */ | 700 | /* chunk -> { stat [;] } ret */ |
710 | while (stat(ls)) { | 701 | while (stat(ls)) { |
711 | LUA_ASSERT(ls->fs->stacksize == ls->fs->nlocalvar, | 702 | LUA_ASSERT(ls->fs->stacksize == ls->fs->nlocalvar, |
712 | "stack size != # local vars"); | 703 | "stack size != # local vars"); |
713 | optional(ls, ';'); | 704 | optional(ls, ';'); |
714 | } | 705 | } |
706 | ret(ls); /* optional return */ | ||
707 | } | ||
708 | |||
709 | |||
710 | static void whilestat (LexState *ls, int line) { | ||
711 | /* whilestat -> WHILE cond DO block END */ | ||
712 | FuncState *fs = ls->fs; | ||
713 | TProtoFunc *f = fs->f; | ||
714 | int while_init = fs->pc; | ||
715 | int cond_end, cond_size; | ||
716 | next(ls); | ||
717 | cond_end = cond(ls); | ||
718 | check(ls, DO); | ||
719 | block(ls); | ||
720 | check_match(ls, END, WHILE, line); | ||
721 | cond_size = cond_end-while_init; | ||
722 | check_pc(fs, cond_size); | ||
723 | memcpy(f->code+fs->pc, f->code+while_init, cond_size); | ||
724 | luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init); | ||
725 | while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size); | ||
726 | fix_upjmp(ls, IFTUPJMP, while_init); | ||
727 | } | ||
728 | |||
729 | |||
730 | static void repeatstat (LexState *ls, int line) { | ||
731 | /* repeatstat -> REPEAT block UNTIL exp1 */ | ||
732 | FuncState *fs = ls->fs; | ||
733 | int repeat_init = fs->pc; | ||
734 | next(ls); | ||
735 | block(ls); | ||
736 | check_match(ls, UNTIL, REPEAT, line); | ||
737 | exp1(ls); | ||
738 | fix_upjmp(ls, IFFUPJMP, repeat_init); | ||
739 | deltastack(ls, -1); /* pops condition */ | ||
740 | } | ||
741 | |||
742 | |||
743 | static void localstat (LexState *ls) { | ||
744 | /* stat -> LOCAL localnamelist decinit */ | ||
745 | FuncState *fs = ls->fs; | ||
746 | listdesc d; | ||
747 | int nvars; | ||
748 | check_debugline(ls); | ||
749 | next(ls); | ||
750 | nvars = localnamelist(ls); | ||
751 | decinit(ls, &d); | ||
752 | fs->nlocalvar += nvars; | ||
753 | correctvarlines(ls, nvars); /* vars will be alive only after decinit */ | ||
754 | adjust_mult_assign(ls, nvars, &d); | ||
755 | } | ||
756 | |||
757 | |||
758 | static int funcstat (LexState *ls, int line) { | ||
759 | /* funcstat -> FUNCTION funcname body */ | ||
760 | int needself; | ||
761 | vardesc v; | ||
762 | if (ls->fs->prev) /* inside other function? */ | ||
763 | return 0; | ||
764 | check_debugline(ls); | ||
765 | next(ls); | ||
766 | needself = funcname(ls, &v); | ||
767 | body(ls, needself, line); | ||
768 | storevar(ls, &v); | ||
769 | return 1; | ||
770 | } | ||
771 | |||
772 | |||
773 | static void namestat (LexState *ls) { | ||
774 | /* stat -> func | ['%'] NAME assignment */ | ||
775 | vardesc v; | ||
776 | check_debugline(ls); | ||
777 | var_or_func(ls, &v); | ||
778 | if (v.k == VEXP) { /* stat -> func */ | ||
779 | if (v.info == 0) /* is just an upper value? */ | ||
780 | luaX_error(ls, "syntax error"); | ||
781 | close_exp(ls, v.info, 0); | ||
782 | } | ||
783 | else { /* stat -> ['%'] NAME assignment */ | ||
784 | int left = assignment(ls, &v, 1); | ||
785 | adjuststack(ls, left); /* remove eventual garbage left on stack */ | ||
786 | } | ||
715 | } | 787 | } |
716 | 788 | ||
789 | |||
717 | static int stat (LexState *ls) { | 790 | static int stat (LexState *ls) { |
718 | int line = ls->linenumber; /* may be needed for error messages */ | 791 | int line = ls->linenumber; /* may be needed for error messages */ |
719 | FuncState *fs = ls->fs; | ||
720 | switch (ls->token) { | 792 | switch (ls->token) { |
721 | case IF: /* stat -> IF ifpart END */ | 793 | case IF: /* stat -> IF ifpart END */ |
722 | ifpart(ls, line); | 794 | ifpart(ls, line); |
723 | return 1; | 795 | return 1; |
724 | 796 | ||
725 | case WHILE: { /* stat -> WHILE cond DO block END */ | 797 | case WHILE: /* stat -> whilestat */ |
726 | TProtoFunc *f = fs->f; | 798 | whilestat(ls, line); |
727 | int while_init = fs->pc; | ||
728 | int cond_end, cond_size; | ||
729 | next(ls); | ||
730 | cond_end = cond(ls); | ||
731 | check(ls, DO); | ||
732 | block(ls); | ||
733 | check_match(ls, END, WHILE, line); | ||
734 | cond_size = cond_end-while_init; | ||
735 | check_pc(fs, cond_size); | ||
736 | memcpy(f->code+fs->pc, f->code+while_init, cond_size); | ||
737 | luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init); | ||
738 | while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size); | ||
739 | fix_upjmp(ls, IFTUPJMP, while_init); | ||
740 | return 1; | 799 | return 1; |
741 | } | ||
742 | 800 | ||
743 | case DO: { /* stat -> DO block END */ | 801 | case DO: { /* stat -> DO block END */ |
744 | next(ls); | 802 | next(ls); |
@@ -747,58 +805,20 @@ static int stat (LexState *ls) { | |||
747 | return 1; | 805 | return 1; |
748 | } | 806 | } |
749 | 807 | ||
750 | case REPEAT: { /* stat -> REPEAT block UNTIL exp1 */ | 808 | case REPEAT: /* stat -> repeatstat */ |
751 | int repeat_init = fs->pc; | 809 | repeatstat(ls, line); |
752 | next(ls); | ||
753 | block(ls); | ||
754 | check_match(ls, UNTIL, REPEAT, line); | ||
755 | exp1(ls); | ||
756 | fix_upjmp(ls, IFFUPJMP, repeat_init); | ||
757 | deltastack(ls, -1); /* pops condition */ | ||
758 | return 1; | 810 | return 1; |
759 | } | ||
760 | 811 | ||
761 | case FUNCTION: { /* stat -> FUNCTION funcname body */ | 812 | case FUNCTION: /* stat -> funcstat */ |
762 | int needself; | 813 | return funcstat(ls, line); |
763 | vardesc v; | ||
764 | if (ls->fs->prev) /* inside other function? */ | ||
765 | return 0; | ||
766 | check_debugline(ls); | ||
767 | next(ls); | ||
768 | needself = funcname(ls, &v); | ||
769 | body(ls, needself, line); | ||
770 | storevar(ls, &v); | ||
771 | return 1; | ||
772 | } | ||
773 | 814 | ||
774 | case LOCAL: { /* stat -> LOCAL localnamelist decinit */ | 815 | case LOCAL: /* stat -> localstat */ |
775 | listdesc d; | 816 | localstat(ls); |
776 | int nvars; | ||
777 | check_debugline(ls); | ||
778 | next(ls); | ||
779 | nvars = localnamelist(ls); | ||
780 | decinit(ls, &d); | ||
781 | fs->nlocalvar += nvars; | ||
782 | correctvarlines(ls, nvars); /* vars will be alive only after decinit */ | ||
783 | adjust_mult_assign(ls, nvars, &d); | ||
784 | return 1; | 817 | return 1; |
785 | } | ||
786 | 818 | ||
787 | case NAME: case '%': { /* stat -> func | ['%'] NAME assignment */ | 819 | case NAME: case '%': /* stat -> namestat */ |
788 | vardesc v; | 820 | namestat(ls); |
789 | check_debugline(ls); | ||
790 | var_or_func(ls, &v); | ||
791 | if (v.k == VEXP) { /* stat -> func */ | ||
792 | if (v.info == 0) /* is just an upper value? */ | ||
793 | luaX_error(ls, "syntax error"); | ||
794 | close_exp(ls, v.info, 0); | ||
795 | } | ||
796 | else { /* stat -> ['%'] NAME assignment */ | ||
797 | int left = assignment(ls, &v, 1); | ||
798 | adjuststack(ls, left); /* remove eventual garbage left on stack */ | ||
799 | } | ||
800 | return 1; | 821 | return 1; |
801 | } | ||
802 | 822 | ||
803 | case RETURN: case ';': case ELSE: case ELSEIF: | 823 | case RETURN: case ';': case ELSE: case ELSEIF: |
804 | case END: case UNTIL: case EOS: /* 'stat' follow */ | 824 | case END: case UNTIL: case EOS: /* 'stat' follow */ |