Beispiel #1
0
class PyLox(object):
    """
    Command-line runner to execute Lox source code. Provides an interface
    to run as REPL prompt or on a pylox source file.
    """
    def __init__(self, verbose=False):
        self.verbose = verbose
        self.interpreter = Interpreter(self.verbose)

    def run_prompt(self):
        while True:
            source = input(PYLOX_PROMPT)
            self.try_read_and_evaluate(source)

    def run_file(self, path):
        with open(path) as f:
            source = f.read()
            self.try_read_and_evaluate(source)

    def try_read_and_evaluate(self, source):
        tokens = Scanner(source, verbose=self.verbose).scan_tokens()
        if self.verbose:
            print(" tokens -> {}".format(tokens))
        parser = Parser(tokens)
        try:
            statements = parser.parse()
        except Exception as e:
            print("Error parsing statements: {}".format(e))
            return

        if self.verbose:
            print(" statements -> {}".format(statements))
        self.interpreter.interpret(statements)
Beispiel #2
0
class InterpreterTests_Expressions(unittest.TestCase):
    def setUp(self):
        self.interpreter = Interpreter()

    def test_grouping_should_equal_inner_value(self):
        inner_expression = Literal(1)
        grouping = Grouping(inner_expression)

        result = self.interpreter.visit_grouping_expression(grouping)

        self.assertEqual(result, 1)

    def test_literal_should_equal_value(self):
        literal = Literal(2)

        result = self.interpreter.visit_literal_expression(literal)

        self.assertEqual(result, 2)

    def test_unary_not(self):
        unary = Unary(new_token(t.BANG), Literal(False))

        result = self.interpreter.visit_unary_expression(unary)

        self.assertEqual(result, True)

    def test_unary_minus(self):
        unary = Unary(new_token(t.MINUS), Literal(2))

        result = self.interpreter.visit_unary_expression(unary)

        self.assertEqual(result, -2)
Beispiel #3
0
 def test_var(self):
     line = 'var beverage = "espresso";\nprint beverage;'
     scanner = Scanner(line)
     tokens = scanner.scan_tokens()
     parser = Parser(tokens, "")
     statements = parser.parse()
     Interpreter().interpret(statements)
Beispiel #4
0
class InterpreterTests_BinaryEqualityExpressions(unittest.TestCase):
    def setUp(self):
        self.interpreter = Interpreter()

    def test_equality_numbers(self):
        binary = Binary(Literal(2), new_token(t.EQUAL_EQUAL), Literal(2))

        result = self.interpreter.visit_binary_expression(binary)

        self.assertEqual(result, True)

    def test_equality_bools(self):
        binary = Binary(Literal(True), new_token(t.EQUAL_EQUAL),
                        Literal(False))

        result = self.interpreter.visit_binary_expression(binary)

        self.assertEqual(result, False)

    def test_equality_number_and_bool(self):
        binary = Binary(Literal(1), new_token(t.EQUAL_EQUAL), Literal(True))

        result = self.interpreter.visit_binary_expression(binary)

        self.assertEqual(result, False)

    @unittest.skip(
        'this is a known issue (see readme). Hopefully gets fixed in blog...')
    def test_double_equality(self):
        # 1 == 1 == 1
        comparison = Binary(
            Binary(Literal(1), new_token(t.EQUAL_EQUAL), Literal(1)),
            new_token(t.EQUAL_EQUAL), Literal(1))

        result = self.interpreter.visit_binary_expression(comparison)

        self.assertEqual(result, True)
Beispiel #5
0
class InterpreterTests_BinaryExpressions(unittest.TestCase):
    def setUp(self):
        self.interpreter = Interpreter()

    def test_multiply(self):
        binary = Binary(Literal(2), new_token(t.STAR), Literal(4))

        result = self.interpreter.visit_binary_expression(binary)

        self.assertEqual(result, 8)

    def test_add_numbers(self):
        binary = Binary(Literal(1), new_token(t.PLUS), Literal(1))

        result = self.interpreter.visit_binary_expression(binary)

        self.assertEqual(result, 2)

    def test_add_strings(self):
        binary = Binary(Literal("hello "), new_token(t.PLUS), Literal("kitty"))

        result = self.interpreter.visit_binary_expression(binary)

        self.assertEqual(result, "hello kitty")

    def test_add_number_and_string(self):
        binary = Binary(Literal(1), new_token(t.PLUS), Literal("kitty"))

        with self.assertRaises(InterpreterException) as context:
            result = self.interpreter.visit_binary_expression(binary)

            self.assertEqual(context.expression, binary)

    def test_comparison(self):
        comparison = Binary(Literal(1), new_token(t.LESS), Literal(2))

        result = self.interpreter.visit_binary_expression(comparison)

        self.assertEqual(result, True)

    def test_equality(self):
        comparison = Binary(Literal(1), new_token(t.EQUAL_EQUAL), Literal(1))

        result = self.interpreter.visit_binary_expression(comparison)

        self.assertEqual(result, True)
Beispiel #6
0
 def __init__(self):
     self.had_error = False
     self.had_runtime_error = False
     self.interpreter = Interpreter()
Beispiel #7
0
class Lox:
    """ Lox class"""
    def __init__(self):
        self.had_error = False
        self.had_runtime_error = False
        self.interpreter = Interpreter()

    def run_file(self, file):
        """ Runs file
        :param file: input file
        """
        with open(file) as content:
            program = content.read()

        self.run(program)
        if self.had_error:
            sys.exit(65)
        elif self.had_runtime_error:
            sys.exit(70)

    def run_prompt(self):
        """ Runs prompt """
        print("Running prompt")
        while True:
            line = input(">> ")
            self.run(line)
            # If we had an error, we should reset at new prompt
            self.had_error = False
            self.had_runtime_error = False

    def run(self, line):
        """ Runs the input
        :param line: line to tokenize and eval
        """
        scanner = Scanner(line)
        tokens = scanner.scan_tokens()
        parser = Parser(tokens, self.error)
        statements = parser.parse()
        self.interpreter.interpret(statements)
        if self.had_error:
            return

    def error(self, line, message):
        """ error
        :param line: the location of error
        :param message: error message
        """
        self.report(line + " " + message)

    def runtimeerror(self, error):
        """
        set runtimeerror message
        :param error: error message
        :return: None
        """
        error_message = "{0} \n [line {1}]".format(error.get_message(), error.token.line)
        print(error_message)
        self.had_runtime_error = True

    def report(self, line, where=None, message=None):
        """ error
        :param line: line of error
        :param where: location of error
        :param: message: error message
        """
        self.had_error = True
        raise Exception("[Line {0}] Error {1}: {2} ".format(line, where, message))
Beispiel #8
0
 def __init__(self, verbose=False):
     self.verbose = verbose
     self.interpreter = Interpreter(self.verbose)
Beispiel #9
0
import sys
import readline
from typing import List
from pylox import interpreter

from pylox.scanner import Scanner
from pylox.tokens import TokenType, Token
from pylox.parser import Parser
from pylox.ast_printer import AstPrinter
from pylox.interpreter import RuntimeException, Interpreter

## static states

gHadError = False
gHadRuntimeError = False
gInterpreter = Interpreter()

## run utils


def run_file(path: str) -> None:
    with open(path, encoding='utf-8') as f:
        run(f.read())
    if gHadError:
        sys.exit(65)
    if gHadRuntimeError:
        sys.exit(70)


def run_prompt(prompt: str = "lox> ") -> None:
    while True:
Beispiel #10
0
 def setUp(self):
     self.interpreter = Interpreter()