Compiler Design

Delta: An Incremental Compiler
Step 14: Comparison Operators

Description

Add support for signed integer comparison operators:

These six operators have less precedence than the additive operators and they associate from left to right.

Check the WebAssembly numeric comparison instructions documentation to see which WASM instruction should be used for each operator.

Example

The Delta program:

1 <= 2 == 1 != 0 > 0 < 0 <= 1

should produce the following WAT code:

(module
  (func
    (export "_start")
    (result i32)
    i32.const 1
    i32.const 2
    i32.le_s
    i32.const 1
    i32.eq
    i32.const 0
    i32.ne
    i32.const 0
    i32.gt_s
    i32.const 0
    i32.lt_s
    i32.const 1
    i32.le_s
  )
)

The above WAT function’s return value should be:

1

Unit Tests

# File: tests/test_14_comparisons.py

from unittest import TestCase
from delta import Compiler, SyntaxMistake


class TestComparisons(TestCase):

    def setUp(self):
        self.c = Compiler('expression_start')

    def test_syntax_mistake(self):
        with self.assertRaises(SyntaxMistake):
            self.c.realize('1 <=')

    def test_equal_true(self):
        self.assertEqual(1,
                         self.c.realize('3 == 1 + 2'))

    def test_equal_false(self):
        self.assertEqual(0,
                         self.c.realize('4 == 3 + 2'))

    def test_not_equal_true(self):
        self.assertEqual(1,
                         self.c.realize('4 != 3 + 2'))

    def test_not_equal_false(self):
        self.assertEqual(0,
                         self.c.realize('5 != 3 + 2'))

    def test_less_than_true(self):
        self.assertEqual(1,
                         self.c.realize('3 + 2 < 6'))

    def test_less_than_false(self):
        self.assertEqual(0,
                         self.c.realize('3 + 2 < 5'))

    def test_greater_than_true(self):
        self.assertEqual(1,
                         self.c.realize('3 + 2 > 4'))

    def test_greater_than_false(self):
        self.assertEqual(0,
                         self.c.realize('3 + 2 > 5'))

    def test_less_or_equal_true1(self):
        self.assertEqual(1,
                         self.c.realize('3 + 2 <= 5'))

    def test_less_or_equal_true2(self):
        self.assertEqual(1,
                         self.c.realize('3 + 2 <= 6'))

    def test_less_or_equal_false(self):
        self.assertEqual(0,
                         self.c.realize('3 + 2 <= 4'))

    def test_greater_or_equal_true1(self):
        self.assertEqual(1,
                         self.c.realize('3 + 2 >= 5'))

    def test_greater_or_equal_true2(self):
        self.assertEqual(1,
                         self.c.realize('3 + 2 >= 4'))

    def test_greater_or_equal_false(self):
        self.assertEqual(0,
                         self.c.realize('3 + 2 >= 6'))

    def test_mix_1(self):
        self.assertEqual(1,
                         self.c.realize('1 <= 2 == 1 != '
                                        '0 > 0 < 0 <= 1'))

    def test_mix_2(self):
        self.assertEqual(1,
                         self.c.realize('1 < 2 < 3 < 4'))

    def test_mix_3(self):
        self.assertEqual(1,
                         self.c.realize('(1 >= 2 > 3) == '
                                        '(4 <= 5 < 6) != 1'))