diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-02-01 16:52:05 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-02-01 16:52:05 -0200 |
| commit | 0f0079f394a21a5e8c705054fd807abb0cc22324 (patch) | |
| tree | 3d14aded7624c497b8ad6c0851f150c58eb5e2d4 | |
| parent | 68267ed878a2ea668aa97b40c5d9cacbe0e57831 (diff) | |
| download | lua-0f0079f394a21a5e8c705054fd807abb0cc22324.tar.gz lua-0f0079f394a21a5e8c705054fd807abb0cc22324.tar.bz2 lua-0f0079f394a21a5e8c705054fd807abb0cc22324.zip | |
"if" expressions.
| -rw-r--r-- | lparser.c | 55 |
1 files changed, 31 insertions, 24 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.9 1999/01/21 18:38:39 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.10 1999/01/29 13:48:58 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 | */ |
| @@ -118,7 +118,7 @@ static void exp1 (LexState *ls); | |||
| 118 | static void exp2 (LexState *ls, vardesc *v); | 118 | static void exp2 (LexState *ls, vardesc *v); |
| 119 | static void explist (LexState *ls, listdesc *e); | 119 | static void explist (LexState *ls, listdesc *e); |
| 120 | static void explist1 (LexState *ls, listdesc *e); | 120 | static void explist1 (LexState *ls, listdesc *e); |
| 121 | static void ifpart (LexState *ls); | 121 | static void ifpart (LexState *ls, int isexp, int line); |
| 122 | static void parlist (LexState *ls); | 122 | static void parlist (LexState *ls); |
| 123 | static void part (LexState *ls, constdesc *cd); | 123 | static void part (LexState *ls, constdesc *cd); |
| 124 | static void recfield (LexState *ls); | 124 | static void recfield (LexState *ls); |
| @@ -689,12 +689,9 @@ static int stat (LexState *ls) { | |||
| 689 | int line = ls->linenumber; /* may be needed for error messages */ | 689 | int line = ls->linenumber; /* may be needed for error messages */ |
| 690 | FuncState *fs = ls->fs; | 690 | FuncState *fs = ls->fs; |
| 691 | switch (ls->token) { | 691 | switch (ls->token) { |
| 692 | case IF: { /* stat -> IF ifpart END */ | 692 | case IF: /* stat -> IF ifpart END */ |
| 693 | next(ls); | 693 | ifpart(ls, 0, line); |
| 694 | ifpart(ls); | ||
| 695 | check_match(ls, END, IF, line); | ||
| 696 | return 1; | 694 | return 1; |
| 697 | } | ||
| 698 | 695 | ||
| 699 | case WHILE: { /* stat -> WHILE cond DO block END */ | 696 | case WHILE: { /* stat -> WHILE cond DO block END */ |
| 700 | TProtoFunc *f = fs->f; | 697 | TProtoFunc *f = fs->f; |
| @@ -841,27 +838,35 @@ static void body (LexState *ls, int needself, int line) { | |||
| 841 | func_onstack(ls, &newfs); | 838 | func_onstack(ls, &newfs); |
| 842 | } | 839 | } |
| 843 | 840 | ||
| 844 | static void ifpart (LexState *ls) { | 841 | |
| 842 | static void ifpart (LexState *ls, int isexp, int line) { | ||
| 845 | /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ | 843 | /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ |
| 846 | int c = cond(ls); | 844 | /* ifpart -> cond THEN exp [ELSE exp | ELSEIF ifpart] */ |
| 845 | int c; | ||
| 847 | int e; | 846 | int e; |
| 847 | next(ls); /* skip IF or ELSEIF */ | ||
| 848 | c = cond(ls); | ||
| 848 | check(ls, THEN); | 849 | check(ls, THEN); |
| 849 | block(ls); | 850 | if (isexp) exp1(ls); |
| 851 | else block(ls); | ||
| 850 | e = SaveWord(ls); | 852 | e = SaveWord(ls); |
| 851 | switch (ls->token) { | 853 | if (ls->token == ELSEIF) |
| 852 | case ELSE: | 854 | ifpart(ls, isexp, line); |
| 853 | next(ls); | 855 | else { |
| 854 | block(ls); | 856 | int elsepart = optional(ls, ELSE); |
| 855 | break; | 857 | if (!isexp) { |
| 856 | 858 | if (elsepart) block(ls); | |
| 857 | case ELSEIF: | 859 | } |
| 858 | next(ls); | 860 | else { /* is exp */ |
| 859 | ifpart(ls); | 861 | if (elsepart) exp1(ls); |
| 860 | break; | 862 | else code_oparg(ls, PUSHNIL, 1, 0, 1); /* empty else exp */ |
| 863 | } | ||
| 864 | check_match(ls, END, IF, line); | ||
| 861 | } | 865 | } |
| 862 | codeIf(ls, c, e); | 866 | codeIf(ls, c, e); |
| 863 | } | 867 | } |
| 864 | 868 | ||
| 869 | |||
| 865 | static void ret (LexState *ls) { | 870 | static void ret (LexState *ls) { |
| 866 | /* ret -> [RETURN explist sc] */ | 871 | /* ret -> [RETURN explist sc] */ |
| 867 | if (ls->token == RETURN) { | 872 | if (ls->token == RETURN) { |
| @@ -986,12 +991,14 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) { | |||
| 986 | constructor(ls); | 991 | constructor(ls); |
| 987 | break; | 992 | break; |
| 988 | 993 | ||
| 989 | case FUNCTION: { /* simpleexp -> FUNCTION body */ | 994 | case FUNCTION: /* simpleexp -> FUNCTION body */ |
| 990 | int line = ls->linenumber; | ||
| 991 | next(ls); | 995 | next(ls); |
| 992 | body(ls, 0, line); | 996 | body(ls, 0, ls->linenumber); |
| 997 | break; | ||
| 998 | |||
| 999 | case IF: /* simpleexp -> IF ifpart END */ | ||
| 1000 | ifpart(ls, 1, ls->linenumber); | ||
| 993 | break; | 1001 | break; |
| 994 | } | ||
| 995 | 1002 | ||
| 996 | case '(': /* simpleexp -> '(' exp0 ')' */ | 1003 | case '(': /* simpleexp -> '(' exp0 ')' */ |
| 997 | next(ls); | 1004 | next(ls); |
