Add support for variables, specifically:
Variable declaration statement: The var
keyword followed by a coma separated list of variable names ending with a semicolon. Examples:
var some_var;
var x, y, z;
A variable name should start with an upper or lower case letter followed by zero or more upper or lower case letters, digits, or underscore characters.
Variable names and keywords should be case-sensitive.
A delta.SemanticMistake
exception should be raised when trying to declare a variable that has already been declared or when trying to name a variable using a Delta language reserved keyword (these are so far: true
, false
, and var
).
It’s worth noting that WebAssembly local variables are initialized with zero by default once they are declared.
Variable assignment statement: A variable name followed by an equal sign (=
) followed by an expression and ending with a semicolon. Example:
some_var = 1 + 2 * 3;
A delta.SemanticMistake
exception should be raised when trying to assign to a variable that hasn’t been declared.
Variable references: A variable name should be allowed to be used as part of any expression. Example:
2 * x + 1
A delta.SemanticMistake
exception should be raised when trying to reference a variable that hasn’t been declared.
A Delta program should be comprised of zero or more statements ending with an expression. See example below.
The Delta program:
var x, y; // First statement x = 2; y = (x + 1) * 3; var z; z = y - 1; // Last statement x + y + z // Resulting expression
should produce the following WAT code:
(module (func (export "_start") (result i32) (local $x i32) (local $y i32) (local $z i32) i32.const 2 local.set $x local.get $x i32.const 1 i32.add i32.const 3 i32.mul local.set $y local.get $y i32.const 1 i32.sub local.set $z local.get $x local.get $y i32.add local.get $z i32.add ) )
The above WAT function’s return value should be:
19
# File: tests/test_08_variables.py from unittest import TestCase from delta import Compiler, SyntaxMistake from delta.semantics import SemanticMistake class TestVariables(TestCase): def setUp(self): self.c = Compiler('program') def test_syntax_mistake(self): with self.assertRaises(SyntaxMistake): self.c.realize('var x,') def test_vars0(self): self.assertEqual(0, self.c.realize( ''' var var_1; var var_2; var var_3; var_1 + var_2 + var_3 ''')) def test_vars1(self): self.assertEqual(42, self.c.realize( ''' var x; x = 42; x ''')) def test_vars2(self): self.assertEqual(15, self.c.realize( ''' var x, y, z; x = 2; y = 8; z = x * y - 1; z ''')) def test_vars3(self): self.assertEqual(10, self.c.realize( ''' var a; a = 10; var b, c; b = 100; c = (b - a * 2) / 8; c ''')) def test_vars4(self): self.assertEqual(55, self.c.realize( ''' var v, w, x, y, z; v = 1; w = 2; x = 3; y = 4; z = 5; var a, b, c, d, e; a = 6; b = 7; c = 8; d = 9; e = 10; a + b + c + d + e + v + w + x + y + z ''')) def test_vars5(self): self.assertEqual(19, self.c.realize( ''' var x, y; x = 2; y = (x + 1) * 3; var z; z = y - 1; x + y + z ''')) def test_duplicated_variable1(self): with self.assertRaises(SemanticMistake): self.c.realize( ''' var x, y, z; x = 10; var v, w, x; x ''') def test_duplicated_variable2(self): with self.assertRaises(SemanticMistake): self.c.realize( ''' var x, y, x; x = 10; x ''') def test_reserved_word(self): with self.assertRaises(SemanticMistake): self.c.realize( ''' var x, y, var; x = 1; y = 2; var = 3; x + y + var ''') def test_undeclared_lhs(self): with self.assertRaises(SemanticMistake): self.c.realize( ''' var x; y = 10; x ''') def test_undeclared_rhs(self): with self.assertRaises(SemanticMistake): self.c.realize( ''' var x; x = 10 + z; x ''')