コード例 #1
0
 def test_for_loop(self, capsys):
     line = 'for (var i = 0; i < 10; i = i + 1) print i;'
     lox = Lox()
     lox.run(line)
     out, err = capsys.readouterr()
     assert err == ''
     assert out == "0.0\n1.0\n2.0\n3.0\n4.0\n5.0\n6.0\n7.0\n8.0\n9.0\n"
コード例 #2
0
class LoxTests_Execute_Statements(unittest.TestCase):

    def setUp(self):
        self.output = TestOutputStream()
        self.lox = Lox(output = self.output)

    def test_print_literal(self):
        self.lox.execute('print "yo";')
        self.assertEqual(self.output.last_sent, "yo")
コード例 #3
0
    def test_if(self, capsys):
        line = "var num = 9; \
               if(num >= 0 and num <= 10) \
               print(true);"

        lox = Lox()
        lox.run(line)
        out, err = capsys.readouterr()
        assert err == ''
        assert out == "True\n"
コード例 #4
0
    def test_of(self, capsys):
        line = 'var s = "hi"; \
               if(s == "hi" or s == "hello") \
               print("Greetings");'

        lox = Lox()
        lox.run(line)
        out, err = capsys.readouterr()
        assert err == ''
        assert out == "Greetings\n"
コード例 #5
0
    def test_num_parameters(self, capsys):
        line = 'fun add(a, b){ \
        return(a + b); \
        } \
        print(add(10, 5));'

        lox = Lox()
        lox.run(line)
        out, err = capsys.readouterr()
        assert err == ''
        assert out == "15.0\n"
コード例 #6
0
    def test_string_parameters(self, capsys):
        line = 'fun strAppend(str1, str2) { \
        var str = str1 + str2; \
        return str;} \
        print(strAppend("foo", "bar"));'

        lox = Lox()
        lox.run(line)
        out, err = capsys.readouterr()
        assert err == ''
        assert out == "foobar\n"
コード例 #7
0
    def test_while_loop(self, capsys):
        line = 'var i = 0; \
        while(i < 10) { \
        print(i); \
        i = i + 1; \
        }'

        lox = Lox()
        lox.run(line)
        out, err = capsys.readouterr()
        assert err == ''
        assert out == "0.0\n1.0\n2.0\n3.0\n4.0\n5.0\n6.0\n7.0\n8.0\n9.0\n"
コード例 #8
0
class LoxTests_LogicalOperators(unittest.TestCase):

    def setUp(self):
        self.output = TestOutputStream()
        self.lox = Lox(output = self.output)

    def test_print_false_and_1(self):
        self.lox.execute('print false and 1;')
        self.assertEqual(self.output.last_sent, False)

    def test_print_true_and_1(self):
        self.lox.execute('print true and 1;')
        self.assertEqual(self.output.last_sent, 1)
コード例 #9
0
    def test_fun_with_conditional(self, capsys):
        line = 'fun checkNegative(num){ \
        if(num <= 0) \
        return(true); \
        else \
        return(false); \
        } \
        print(checkNegative(-1));'

        lox = Lox()
        lox.run(line)
        out, err = capsys.readouterr()
        assert err == ''
        assert out == "True\n"
コード例 #10
0
    def test_recursion(self, capsys):
        line = 'fun isOdd(n) { \
        if (n == 0) return false; \
        return isEven(n - 1); \
        } \
        fun isEven(n){ \
        if (n == 0) return true; \
        return isOdd(n - 1); \
        } \
        print(isEven(3));'

        lox = Lox()
        lox.run(line)
        out, err = capsys.readouterr()
        assert err == ''
        assert out == "False\n"
コード例 #11
0
class LoxTests_Scoping(unittest.TestCase):

    def setUp(self):
        self.output = TestOutputStream()
        self.lox = Lox(output = self.output)

    def test_reuse_name_in_inner_scope(self):
        self.lox.execute('var a = 1;')
        self.lox.execute('{ var a = 2; print a; }')
        self.assertEqual(self.output.last_sent, 2)
        self.lox.execute('print a;')
        self.assertEqual(self.output.last_sent, 1)

    def test_assign_outer_in_inner_scope(self):
        self.lox.execute('var a = 1;')
        self.lox.execute('{ a = 2; }')
        self.lox.execute('print a;')
        self.assertEqual(self.output.last_sent, 2)
コード例 #12
0
class LoxTests_WhileLoops(unittest.TestCase):

    def setUp(self):
        self.output = TestOutputStream()
        self.lox = Lox(output = self.output)

    def test_while_var_one_loop(self):
        self.lox.execute('var do_loop = true;')
        self.lox.execute('while (do_loop) { print 1; do_loop = false; }')
        self.assertEqual(self.output.last_sent, 1)

    def test_while_false_does_nothing(self):
        self.lox.execute('while (false) print 1;')
        self.assertEqual(self.output.num_sent(), 0)

    def test_while_loops_multiple_times(self):
        self.lox.execute('var temp = 5;')
        self.lox.execute('while (temp > 0) { print 1; temp = temp - 1; }')
        self.assertEqual(self.output.num_sent(), 5)
コード例 #13
0
    def execute(self, lox_instance: Lox, out_buf: StringIO) -> bool:
        lox_instance.interpreter.reinitialize_environment()

        out_capture = StringIO()
        err_capture = StringIO()
        with self.path.open("r") as fil:
            source = fil.read()

        self._compute_expected_output(source)

        with suppress(LoxExit), redirect_stderr(err_capture), redirect_stdout(
                out_capture):
            lox_instance.run(source)

        out = tuple(line.strip()
                    for line in out_capture.getvalue().splitlines())
        err = tuple(line.strip()
                    for line in err_capture.getvalue().splitlines())

        if not (message := self._verify(out, err)):
            print(f"[{green('PASS')}]: {self.path}", file=out_buf)
            return True
コード例 #14
0
class LoxTests_Execute_Expressions(unittest.TestCase):

    def setUp(self):
        self.output = TestOutputStream()
        self.lox = Lox(output = self.output)

    def test_numerical(self):
        params = [
            ('1 + 1', 2),
            ('2 * 2', 4),
            ('1 + 4 / 2', 3),
            ('(1 + 4) / 2', 2.5),
            ("""  ( 1 +  4/2) * 3*2 - 10
               == ( 1 +  2)   * 6   - 10   """, True),
        ]
        for expression, expected in params:
            with self.subTest():
                self.lox.execute(f'print {expression};')
                self.assertEqual(self.output.last_sent, expected)

    def test_strings(self):
        params = [
            ('"cat" == "cat"', True),
            ('"dog" == "cat"', False)
        ]
        for expression, expected in params:
            with self.subTest():
                self.lox.execute(f'print {expression};')
                self.assertEqual(self.output.last_sent, expected)

    def test_bools(self):
        params = [
            ('true == 1 < 2', True),
            ('false != 1 < 2 + 4', True)
        ]
        for expression, expected in params:
            with self.subTest():
                self.lox.execute(f'print {expression};')
                self.assertEqual(self.output.last_sent, expected)

    def test_incomplete_expression(self):
        self.lox.execute('1 +')
        self.assertTrue('Expected expression' in self.output.last_sent)
コード例 #15
0
    def __init__(self) -> None:
        self._queued_tests: List[Test] = list()
        self._lox_instance = Lox(Debug.JAVA_STYLE_TOKENS
                                 | Debug.REDUCED_ERROR_REPORTING)
        self._fails_output = StringIO()

        self._test_root = Path(
            os.path.realpath(__file__)).parent / "test_suite"
        if not self._test_root.is_dir():
            raise FileNotFoundError("Test suite not found!")
        print(f"Test suite discovered at '{self._test_root}'.")

        ignored_paths_full = tuple(self._test_root / path
                                   for path in self.IGNORED_PATHS)

        for path in self.TEST_PATHS:
            self._discover_and_queue_tests(self._test_root / path,
                                           ignored_paths_full)
        print(f"{len(self._queued_tests)} tests found.")
コード例 #16
0
class LoxTests_IfElse(unittest.TestCase):

    def setUp(self):
        self.output = TestOutputStream()
        self.lox = Lox(output = self.output)

    def test_if_true_else(self):
        self.lox.execute('if (true) print "true"; else print "false";')
        self.assertEqual(self.output.last_sent, "true")

    def test_if_false_else(self):
        self.lox.execute('if (false) print "true"; else print "false";')
        self.assertEqual(self.output.last_sent, "false")

    def test_nested_if_else_should_grab_earliest_else(self):
        self.lox.execute("""
            if (true)
                if (true)
                    print "this should get printed";
                else
                    print "this should not get printed";
            """)
        self.assertEqual(self.output.last_sent, "this should get printed")
コード例 #17
0
 def setUp(self):
     self.output = TestOutputStream()
     self.lox = Lox(output = self.output)
コード例 #18
0
class LoxTests_Variables(unittest.TestCase):

    def setUp(self):
        self.output = TestOutputStream()
        self.lox = Lox(output = self.output)

    def test_declare_then_print(self):
        self.lox.execute('var a;')
        self.lox.execute('print a;')
        self.assertEqual(self.output.last_sent, "nil")

    def test_declare_with_initialiser_then_print(self):
        self.lox.execute('var a = 1;')
        self.lox.execute('print a;')
        self.assertEqual(self.output.last_sent, 1)

    def test_declare_with_initialiser_expression_then_print(self):
        self.lox.execute('var a = 1 + 1;')
        self.lox.execute('print a;')
        self.assertEqual(self.output.last_sent, 2)

    def test_declare_then_assign(self):
        self.lox.execute('var a = 1;')
        self.lox.execute('print a;')
        self.assertEqual(self.output.last_sent, 1)
        self.lox.execute('a = "asdf";')
        self.lox.execute('print a;')
        self.assertEqual(self.output.last_sent, 'asdf')

    def test_can_print_assignment(self):
        # assignment is an expression, so has a value
        self.lox.execute('var a = 1;')
        self.lox.execute('print a = 2;')
        self.assertEqual(self.output.last_sent, 2)

    def test_bad_assign_target_should_print_error(self):
        self.lox.execute('var a; var b;')
        self.lox.execute('a + b = 3;')
        self.assertIn('Invalid assignment target', self.output.last_sent)
コード例 #19
0
        description=
        "Yet another implementation of the Lox interpreter in Python",
        allow_abbrev=False)
    parser.add_argument("-c",
                        metavar="STRING",
                        type=str,
                        required=False,
                        help="source string to execute")
    parser.add_argument("source",
                        metavar="FILE",
                        nargs="?",
                        type=str,
                        default=None,
                        help="the .lox file to interpret")
    parser.add_argument(
        "--dbg",
        choices=tuple(option.name for option in Debug),
        default=list(),
        action="append",
        help="pylox debugging options, multiple --dbg arguments can be passed")
    args, extra_args = parser.parse_known_args()

    lox = Lox(reduce(lambda a, b: a | Debug[b], args.dbg,
                     Debug.BACKTRACE))  # Collapse all flags passed.
    if args.c:
        lox.run(args.c)
    elif args.source:
        lox.run_file(args.source)
    else:
        lox.run_interactive()
コード例 #20
0
import sys

from pylox.lox import Lox, LoxRepl

DEBUG = False

if __name__ == "__main__":
    args = sys.argv[1:]  # arg 0 is the name of this script
    lox = Lox(debug=DEBUG)
    if len(args) == 0:
        LoxRepl(lox).run()
    elif len(args) == 1:
        lox.run_file(args[0])
    else:
        print('nah')
コード例 #21
0
 def setUp(self):
     self.output = TestOutputStream()
     self.lox = Lox(output = self.output)
     self.runner = LoxFileRunner(self.lox)