summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--eval.c1
-rw-r--r--lexer.c1
-rw-r--r--lexer.h2
-rw-r--r--parser.y21
-rw-r--r--tests/00_syntax/18_if_condition16
5 files changed, 40 insertions, 1 deletions
diff --git a/eval.c b/eval.c
index de0b24e..8931aec 100644
--- a/eval.c
+++ b/eval.c
@@ -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,
diff --git a/lexer.c b/lexer.c
index eb513b8..f14a944 100644
--- a/lexer.c
+++ b/lexer.c
@@ -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 },
diff --git a/lexer.h b/lexer.h
index f40c820..46cb9d5 100644
--- a/lexer.h
+++ b/lexer.h
@@ -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)
diff --git a/parser.y b/parser.y
index 1d5ccb1..25edf2f 100644
--- a/parser.y
+++ b/parser.y
@@ -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:
{%