Modify the if
/else
statement from step 9 in order to add support for else
if
clauses. This kind of clause allows checking multiple expressions and execute a block of code as soon as one of the conditions evaluates to true (any non-zero value). Similar to the else
clause, the else
if
clause is optional. However, unlike else
, for which there can be only one, there can be an arbitrary number of else
if
clauses following an if
.
The syntax for the if
/else
if
/else
statement is:
\( \; \; \; \; \texttt{if} \; \textit{expression}_1 \texttt{\{} \; \)
\( \; \; \; \; \; \; \; \; \textit{statements}_1 \)
\( \; \; \; \; \texttt{\} } \)
\( \; \; \; \; \texttt{else if} \; \textit{expression}_2 \; \texttt{\{} \; \)
\( \; \; \; \; \; \; \; \; \textit{statements}_2 \)
\( \; \; \; \; \texttt{\} } \)
\( \; \; \; \; \vdots \)
\( \; \; \; \; \texttt{else if} \; \textit{expression}_n \; \texttt{\{} \; \)
\( \; \; \; \; \; \; \; \; \textit{statements}_n \)
\( \; \; \; \; \texttt{\} } \)
\( \; \; \; \; \texttt{else \{} \; \)
\( \; \; \; \; \; \; \; \; \textit{statements}_{n+1} \)
\( \; \; \; \; \texttt{\} } \)
The Delta program:
var x, y; x = 5; if x - 5 { y = 1; } else if x * 0 { y = 2; } else if x - 1 { y = 3; } else { y = 4; } y
should produce the following WAT code:
(module (func (export "_start") (result i32) (local $x i32) (local $y i32) i32.const 5 local.set $x local.get $x i32.const 5 i32.sub if i32.const 1 local.set $y else local.get $x i32.const 0 i32.mul if i32.const 2 local.set $y else local.get $x i32.const 1 i32.sub if i32.const 3 local.set $y else i32.const 4 local.set $y end end end local.get $y ) )
The above WAT function’s return value should be:
3
# File: tests/test_C_if_elseif_else.py from unittest import TestCase from delta import Compiler, SyntaxMistake class TestIfElseIfElse(TestCase): def setUp(self): self.c = Compiler('program') def test_syntax_mistake1(self): with self.assertRaises(SyntaxMistake): self.c.realize('if true {} else if {}') def test_if_elseif_else_1(self): self.assertEqual(3, self.c.realize( ''' var x, y; x = 5; if x - 5 { y = 1; } else if x * 0 { y = 2; } else if x - 1 { y = 3; } else { y = 4; } y ''')) def test_if_elseif_else_2(self): self.assertEqual(0, self.c.realize( ''' var x, y; x = 5; if x - 5 { y = 1; } else if x * 0 { y = 2; } else if x - x { y = 3; } else if x / x - 1 { y = 4; } y ''')) def test_if_elseif_else_3(self): self.assertEqual(5, self.c.realize( ''' var x, y; x = 5; if x - 5 { y = 1; } else if x * 0 { y = 2; } else if x - x { y = 3; } else if x / x - 1 { y = 4; } else { y = x; } y ''')) def test_if_elseif_else_4(self): self.assertEqual(1, self.c.realize( ''' var x, y; x = 5; if x { y = 1; } else if x * 0 { y = 2; } else if x - x { y = 3; } else if x / x - 1 { y = 4; } else { y = x; } y ''')) def test_if_elseif_else_5(self): self.assertEqual(3, self.c.realize( ''' var x, y; x = 5; if x - 5 { y = 1; } else if x * 0 { y = 2; } else if x - 1 { y = 3; } else if x / x - 1 { y = 4; } else { y = x; } y ''')) def test_if_elseif_else_6(self): self.assertEqual(27, self.c.realize( ''' var a, b, c; a = 4; b = 2 * a - 5; c = a * b; if a - a { a = a * 2; b = b - 1; c = c + 1; } else if a - b { a = a * 3; b = b - 2; c = c + 2; } else if c + 1 { a = a * 4; b = b - 3; c = c + 3; } else { a = a * 5; b = b - 4; c = c + 4; } a + b + c '''))