diff options
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | lexer.c | 1 | ||||
-rw-r--r-- | lexer.h | 2 | ||||
-rw-r--r-- | parser.y | 21 | ||||
-rw-r--r-- | tests/00_syntax/18_if_condition | 16 |
5 files changed, 40 insertions, 1 deletions
@@ -1562,6 +1562,7 @@ static struct json_object *(*fns[__T_MAX])(struct ut_state *, uint32_t) = { [T_LBRACK] = ut_execute_lbrack, [T_LBRACE] = ut_execute_object, [T_IF] = ut_execute_if, + [T_ELIF] = ut_execute_if, [T_QMARK] = ut_execute_if, [T_FOR] = ut_execute_for, [T_WHILE] = ut_execute_while, @@ -142,6 +142,7 @@ static const struct token reserved_words[] = { { T_CATCH, "catch", 5 }, { T_BOOL, "false", 5, { .b = false } }, { T_BOOL, "true", 4, { .b = true } }, + { T_ELIF, "elif", 4 }, { T_ELSE, "else", 4 }, { T_THIS, "this", 4 }, { T_NULL, "null", 4 }, @@ -19,7 +19,7 @@ #include "ast.h" -#define __T_MAX 79 +#define __T_MAX 80 #define T_EXCEPTION (__T_MAX + 0) #define T_CFUNC (__T_MAX + 1) #define T_RESSOURCE (__T_MAX + 2) @@ -78,6 +78,19 @@ ut_no_empty_obj(struct ut_state *s, uint32_t off) return (!op || op->type != T_LBRACE || op->tree.operand[0]) ? off : 0; } +static inline uint32_t +ut_add_else(struct ut_state *s, uint32_t off, uint32_t add) +{ + struct ut_op *tail = ut_get_op(s, off); + + while (tail && tail->tree.operand[2]) + tail = ut_get_op(s, tail->tree.operand[2]); + + tail->tree.operand[2] = add; + + return off; +} + } %syntax_error { @@ -133,11 +146,19 @@ sel_stmt(A) ::= T_IF(B) T_LPAREN exp(C) T_RPAREN stmt(D) T_ELSE stmt(E). { A = wrap_op(B, C, no_empty_obj(D), no_empty_obj(E)); } sel_stmt(A) ::= T_IF(B) T_LPAREN exp(C) T_RPAREN stmt(D). [T_IF] { A = wrap_op(B, C, no_empty_obj(D)); } +sel_stmt(A) ::= T_IF(B) T_LPAREN exp(C) T_RPAREN T_COLON chunks(D) sel_elifs(E) T_ELSE chunks(F) T_ENDIF. + { A = ut_add_else(s, wrap_op(B, C, D, E), F); } sel_stmt(A) ::= T_IF(B) T_LPAREN exp(C) T_RPAREN T_COLON chunks(D) T_ELSE chunks(E) T_ENDIF. { A = wrap_op(B, C, D, E); } sel_stmt(A) ::= T_IF(B) T_LPAREN exp(C) T_RPAREN T_COLON chunks(D) T_ENDIF. [T_IF] { A = wrap_op(B, C, D); } +sel_elifs(A) ::= sel_elifs(B) sel_elif(C). { A = ut_add_else(s, B, C); } +sel_elifs(A) ::= sel_elif(B). { A = B; } + +sel_elif(A) ::= T_ELIF(B) T_LPAREN exp(C) T_RPAREN T_COLON chunks(D). + { A = wrap_op(B, C, D); } + iter_stmt(A) ::= T_WHILE(B) T_LPAREN exp(C) T_RPAREN stmt(D). { A = wrap_op(B, C, no_empty_obj(D)); } iter_stmt(A) ::= T_WHILE(B) T_LPAREN exp(C) T_RPAREN T_COLON chunks(D) T_ENDWHILE. diff --git a/tests/00_syntax/18_if_condition b/tests/00_syntax/18_if_condition index 9601f11..9e02767 100644 --- a/tests/00_syntax/18_if_condition +++ b/tests/00_syntax/18_if_condition @@ -22,6 +22,10 @@ An if-condition using the alternative syntax: Variable x has another value. +An if-condition using the special "elif" keyword in alternative syntax mode: +Variable x was set to five. + + Ternary expressions function similar to if/else statements but only allow for a single expression in the true and false branches: Variable x is one @@ -93,6 +97,18 @@ Variable x has another value. {% endif %} +An if-condition using the special "elif" keyword in alternative syntax mode: +{% if (x == 0): -%} +Variable x was set to zero. +{% elif (x == 1): -%} +Variable x was set to one. +{% elif (x == 5): -%} +Variable x was set to five. +{% else -%} +Variable x has another value. +{% endif %} + + Ternary expressions function similar to if/else statements but only allow for a single expression in the true and false branches: {% |