Пример #1
0
    def test_overflow(self):
        interpreter = pixiedust.PixieDust()

        with self.subTest("memory set"):
            # 0x7FFFFFFF + 1
            interpreter.execute(
                "*++ *. .* .+++++++++++++++++++++++++++++++* .* +\n")
            self.assertEqual(interpreter.memory[0], -0x80000000)

        with self.subTest("register set"):
            # 0x7FFFFFFF + 1
            interpreter.execute(
                "*++ .+ .* .+++++++++++++++++++++++++++++++* .* +\n")
            self.assertEqual(interpreter.registers.get(".+"), -0x80000000)

        with self.subTest("write stdout"):
            out = io.StringIO()
            interpreter = pixiedust.PixieDust(stdout=out)
            # copy -1 literal into the *+ registry
            interpreter.execute("*. *+ .* ++++++++++++++++++++++++++++++++\n")
            self.assertEqual(out.getvalue(), "\uFFFF")

        with self.subTest("read stdin"):
            in_ = io.StringIO("\U0001F9DA")  # U+1F9DA FAIRY
            interpreter = pixiedust.PixieDust(stdin=in_)
            # copy stdin character into memory
            interpreter.execute("*. *. *+\n")
            self.assertEqual(interpreter.memory[0], 0xF9DA)
Пример #2
0
    def test_output_unicode(self):
        with self.subTest("print"):
            out = io.StringIO()
            interpreter = pixiedust.PixieDust(stdout=out)
            # print U+2728 SPARKLES
            interpreter.execute("++ .* +..+++..+.+...\n")
            self.assertEqual(out.getvalue(), "\u2728")

        with self.subTest("*+ register"):
            out = io.StringIO()
            interpreter = pixiedust.PixieDust(stdout=out)
            # copy U+2728 SPARKLES to the *+ register
            interpreter.execute("*. *+ .* +..+++..+.+...\n")
            self.assertEqual(out.getvalue(), "\u2728")
Пример #3
0
    def test_label_errors(self):
        interpreter = pixiedust.PixieDust()

        with self.subTest("redefinition"):
            good_label = "".join([random.choice("*+.") for _ in range(10)])
            with self.assertRaisesRegex(
                    SyntaxError, r"Re-definition of label '[*+.]+' on line 2"):
                interpreter.execute(
                    # set good_label
                    f"+. {good_label}\n"
                    # set it again
                    f"+. {good_label}\n")

        with self.subTest("invalid target"):
            bad_label = "".join([random.choice("*+.") for _ in range(10)])
            with self.assertRaisesRegex(SyntaxError,
                                        r"Invalid label target on line 1"):
                interpreter.execute(
                    # jump to bad label
                    f"+* + {bad_label}\n")

        with self.subTest("invalid target after valid"):
            with self.assertRaisesRegex(SyntaxError,
                                        r"Invalid label target on line 3"):
                interpreter.execute(
                    # set good_label
                    f"+. {good_label}\n"
                    # jnz to good label
                    f"+* * {good_label}\n"
                    # jump to bad label
                    f"+* + {bad_label}\n")
Пример #4
0
    def test_invalid_literal(self):
        interpreter = pixiedust.PixieDust()

        with self.assertRaisesRegex(SyntaxError,
                                    r"Invalid number literal on line 2"):
            interpreter.execute(
                # copy 0 literal to the ** register
                "*. ** .* .*\n"
                # copy 0 literal to the ** register, but with a bit too many
                "*. ** .* .................................*\n")
Пример #5
0
    def test_invalid_math_operator(self):
        interpreter = pixiedust.PixieDust()

        with self.assertRaisesRegex(
                SyntaxError, r"No such math operator: \*\+\*, on line 2"):
            interpreter.execute(
                # copy 0 literal to the ** register
                "*. ** .* .*\n"
                # math operator * on two 0 literals
                "*+ * .* .* .* .*\n")
Пример #6
0
    def test_setting_literal_register(self):
        interpreter = pixiedust.PixieDust()

        with self.assertRaisesRegex(SyntaxError,
                                    r"No such register: \.\*, on line 2"):
            interpreter.execute(
                # copy 0 literal to the ** register
                "*. ** .* .*\n"
                # copy 0 literal to the .* register (the literal register)
                "*. .* .* .*\n")
Пример #7
0
    def test_missing_chars(self):
        interpreter = pixiedust.PixieDust()

        with self.assertRaisesRegex(
                SyntaxError, r"Missing instruction characters on line 2"):
            interpreter.execute(
                # copy 0 literal to the ** register
                "*. ** .* .*\n"
                # copy to the ** register, incomplete expression
                "*. ** .\n")
Пример #8
0
    def test_invalid_chars(self):
        interpreter = pixiedust.PixieDust()

        with self.assertRaisesRegex(SyntaxError,
                                    r"Invalid characters on line 2"):
            interpreter.execute(
                # copy 0 literal to the ** register
                "*. ** .* .*\n"
                # copy 0 literal to the ** register, with extra dots
                "*. ** .* .* SPAM\n")
Пример #9
0
    def test_trailing(self):
        interpreter = pixiedust.PixieDust()

        with self.assertRaisesRegex(SyntaxError,
                                    r"Trailing characters on line 2"):
            interpreter.execute(
                # copy 0 literal to the ** register
                "*. ** .* .*\n"
                # copy 0 literal to the ** register, with extra dots
                "*. ** .* .* ....\n")
Пример #10
0
 def test_jump_unconditional(self):
     interpreter = pixiedust.PixieDust()
     interpreter.execute(
         # set memory address 0 to 42
         "*. *. .* +.+.+.\n"
         # unconditial jump to *..*
         "+* + *..*\n"
         # set memory address 0 to 81
         "*. *. .* +.+...+\n"
         # set label *..*; code should jump here
         "+. *..*\n")
     self.assertEqual(interpreter.memory[0], 42)
Пример #11
0
    def test_comp(self):
        interpreter = pixiedust.PixieDust()

        tests = {
            "equals": (".* .* +* .* +\n", ".* .* +* .* .\n"),
            "lower": (".+ .* .* .* +\n", ".+ .* .* .* .\n"),
            "greater": (".. .* +* .* .\n", ".. .* .* .* .\n"),
        }
        for name, (true, false) in tests.items():
            with self.subTest(name):
                interpreter.execute(true)
                self.assertEqual(interpreter.registers[".."], 1)
                interpreter.execute(false)
                self.assertEqual(interpreter.registers[".."], 0)
Пример #12
0
 def test_helloworld(self):
     helloworld = (  # original hello world golf sample
         # Hello
         "++.*+..+...\n++.*++..+.+\n++.*++.++..\n++.*++.++..\n++.*++.++++\n"
         # ,<space>
         "++.*+.++..\n++.*+.....\n"
         # World
         "++.*+.+.+++\n++.*++.++++\n++.*+++..+.\n++.*++.++..\n++.*++..+..\n"
         # !
         "++.*+....+")
     out = io.StringIO()
     interpreter = pixiedust.PixieDust(stdout=out)
     interpreter.execute(helloworld)
     self.assertEqual(out.getvalue(), "Hello, World!")
Пример #13
0
    def test_math(self):
        interpreter = pixiedust.PixieDust()

        # tests set memory address 0 to the result
        # of the operation on two literals.
        tests = {
            "add": "*++ *. .* +.++.* .* +.+..\n",  # 22 + 20
            "subtract": "*+. *. .* +++++.* .* +.+..\n",  # 62 - 20
            "multiply": "*** *. .* +.+.+* .* +.\n",  # 21 * 2
            "divide": "**. *. .* +++++++* .* ++\n",  # 127 // 3
            "modulo": "**+ *. .* +++........+.* .* +.+...+\n",  # 7170 % 81
        }

        for name, dust in tests.items():
            with self.subTest(name):
                interpreter.execute(dust)
                self.assertEqual(interpreter.memory[0], 42)
Пример #14
0
 def test_jump_zero(self):
     interpreter = pixiedust.PixieDust()
     interpreter.execute(
         # set memory address 0 to 81
         "*. *. .* +.+...+\n"
         # set .. register to 1
         "*. .. .* +\n"
         # if .. is 0, jump to *..*
         "+* . *..*\n"
         # set memory address 0 to 42
         "*. *. .* +.+.+.\n"
         # set .. register to 0
         "*. .. .* .\n"
         # if .. is 0, jump to *..*
         "+* . *..*\n"
         # set memory address 0 to 81
         "*. *. .* +.+...+\n"
         # set label *..*; code should jump here
         "+. *..*\n")
     self.assertEqual(interpreter.memory[0], 42)
Пример #15
0
    def test_expressions(self):
        bindust_map = str.maketrans("01", ".+")
        pos_increment = "*++ ** ** .* +\n"  # add 1 to the ** register
        # try several different literal sizes
        for i in range(0, 0x80000000, 0x1234567):
            long_literal = format(i, "032b").translate(bindust_map) + "*"
            negative_literal = "+" + long_literal[1:]
            short_literal = long_literal.lstrip(".").rstrip("*")

            interpreter = pixiedust.PixieDust()
            interpreter.execute(
                # store each of the literals in memory
                # *. *. copies to the memory pointer, *++ ** + increments the pointer
                pos_increment.join([
                    f"*. *. .* {long_literal}\n",
                    f"*. *. .* {short_literal}\n",
                    f"*. *. .* {negative_literal}\n",
                ]))
            self.assertEqual(interpreter.memory[0], i)
            self.assertEqual(interpreter.memory[1], i)
            self.assertEqual(interpreter.memory[2], -0x80000000 + i)
Пример #16
0
 def test_input_unicode(self):
     in_ = io.StringIO("\u2728")
     interpreter = pixiedust.PixieDust(stdin=in_)
     # copy byte from stdin to memory address 0
     interpreter.execute("*. *. *+\n")
     self.assertEqual(interpreter.memory[0], 0x2728)