Exemplo n.º 1
0
    def test_inner_scope_same_name(self):
        env = Environment()
        env_inner = Environment(env)
        env.define('a', 1)
        env_inner.define('a', 2)

        self.assertEqual(env.get(var_token('a')), 1)
        self.assertEqual(env_inner.get(var_token('a')), 2)
Exemplo n.º 2
0
    def test_inner_scope_assign_searches_parent_scope(self):
        env = Environment()
        env_inner = Environment(env)
        env.define('a', 1)
        env_inner.assign(var_token('a'), 2)

        self.assertEqual(env.get(var_token('a')), 2)
        self.assertEqual(env_inner.get(var_token('a')), 2)
Exemplo n.º 3
0
 def call(self, interpreter, arguments):
     """
     calls the arguemnt
     :param interpreter: environment/interpreter
     :param arguments: arguments
     :return: None
     """
     environment = Environment(self.closure)
     for i in range(len(arguments)):
         environment.define(self._declaration.params[i].lexeme,
                            arguments[i])
     try:
         interpreter.execute_block(self._declaration.body, environment)
     except Return as return_error:
         return return_error.value
     return None
Exemplo n.º 4
0
 def __init__(self):
     self.globals = Environment()
     self.environment = self.globals
Exemplo n.º 5
0
 def visit_block_stmt(self, stmt):
     self.execute_block(stmt.statements,
                        Environment(enclosing=self.environment))
Exemplo n.º 6
0
 def test_get_undefined_throws(self):
     env = Environment()
     with self.assertRaises(EnvironmentException):
         env.get(var_token('asdf'))
Exemplo n.º 7
0
 def test_inner_scope_not_accessible_from_outer(self):
     env = Environment()
     env_inner = Environment(env)
     env_inner.define('a', 1)
     with self.assertRaises(EnvironmentException):
         env.get(var_token('a'))
Exemplo n.º 8
0
 def setUp(self):
     self.env = Environment()
     self.x = Token(TokenType.VAR, "x", "x", 1)
     self.undefined_var = Token(TokenType.VAR, "undefined_var", "undefined_var", 1)
Exemplo n.º 9
0
 def test_define_assign_and_get(self):
     env = Environment()
     env.define('a', 1)
     env.assign(var_token('a'), 2)
     val = env.get(var_token('a'))
     self.assertEqual(val, 2)
Exemplo n.º 10
0
class TestEnvironment(unittest.TestCase):
    def setUp(self):
        self.env = Environment()
        self.x = Token(TokenType.VAR, "x", "x", 1)
        self.undefined_var = Token(TokenType.VAR, "undefined_var", "undefined_var", 1)

    def test_define_with_value(self):
        self.env.define(self.x.lexeme, 10)
        self.assertEqual(10, self.env.get(self.x))

    def test_defined_without_value(self):
        self.env.define(self.x.lexeme, None)
        self.assertIsNone(self.env.get(self.x))

    def test_get_undefined_var(self):
        self.assertRaises(RuntimeException, lambda: self.env.get(self.undefined_var))

    def test_assign_undefined_var(self):
        self.assertRaises(RuntimeError, lambda: self.env.assign(self.undefined_var, 10))

    def test_assign(self):
        self.env.define(self.x.lexeme, 10)
        self.assertEqual(10, self.env.get(self.x))
        self.env.assign(self.x, 20)
        self.assertEqual(20, self.env.get(self.x))
Exemplo n.º 11
0
 def __init__(self, verbose=False):
     self.verbose = verbose
     self.environment = Environment()
Exemplo n.º 12
0
class Interpreter(object):
    def __init__(self, verbose=False):
        self.verbose = verbose
        self.environment = Environment()

    def interpret(self, statements):
        try:
            for stmt in statements:
                self.execute(stmt)
        except Exception as e:
            print("Runtime Exception: {}".format(e))

    def evaluate(self, expr):
        return expr.accept(self)

    def visit(self, expr):
        if isinstance(expr, BinaryExpr):
            return self.visit_binary_expr(expr)
        elif isinstance(expr, UnaryExpr):
            return self.visit_unary_expr(expr)
        elif isinstance(expr, LiteralExpr):
            return self.visit_literal_expr(expr)
        elif isinstance(expr, GroupingExpr):
            return self.visit_grouping_expr(expr)
        elif isinstance(expr, Print):
            return self.visit_print_stmt(expr)
        elif isinstance(expr, Expression):
            return self.visit_expression_stmt(expr)
        elif isinstance(expr, Var):
            return self.visit_var_stmt(expr)
        elif isinstance(expr, Variable):
            return self.visit_variable_expr(expr)
        elif isinstance(expr, Assign):
            return self.visit_assign_expr(expr)

    def visit_literal_expr(self, expr):
        return expr.value

    def visit_grouping_expr(self, expr):
        return self.evaluate(expr.expression)

    def visit_unary_expr(self, expr):
        right = self.evaluate(expr.right)
        if expr.operator.token_type == TokenType.MINUS:
            self._check_number_operand(expr.operator, right)
            return -1 * right
        if expr.operator.token_type == TokenType.BANG:
            return not self.is_truthy(right)
        return None

    def visit_binary_expr(self, expr):
        left = self.evaluate(expr.left)
        right = self.evaluate(expr.right)
        operator_type = expr.operator.token_type
        if operator_type == TokenType.GREATER:
            self._check_number_operands(expr.operator, left, right)
            return left > right
        if operator_type == TokenType.GREATER_EQUAL:
            self._check_number_operands(expr.operator, left, right)
            return left >= right
        if operator_type == TokenType.LESS:
            self._check_number_operands(expr.operator, left, right)
            return left < right
        if operator_type == TokenType.LESS_EQUAL:
            self._check_number_operands(expr.operator, left, right)
            return left <= right
        if operator_type == TokenType.MINUS:
            self._check_number_operands(expr.operator, left, right)
            return left - right
        if operator_type == TokenType.SLASH:
            self._check_number_operands(expr.operator, left, right)
            return left / right
        if operator_type == TokenType.STAR:
            self._check_number_operands(expr.operator, left, right)
            return left * right
        if operator_type == TokenType.PLUS:
            self._check_number_operands(expr.operator, left, right)
            return left + right
        if operator_type == TokenType.EQUAL_EQUAL:
            return self.is_equal(left, right)
        if operator_type == TokenType.BANG_EQUAL:
            return not self.is_equal(left, right)
        return None

    def visit_expression_stmt(self, stmt):
        self.evaluate(stmt.expression)
        return None

    def visit_print_stmt(self, stmt):
        value = self.evaluate(stmt.expression)
        print(value)
        return None

    def visit_var_stmt(self, stmt):
        if stmt.initializer:
            value = self.evaluate(stmt.initializer)
        else:
            value = None
        self.environment.define(stmt.name.lexeme, value)
        return None

    def visit_variable_expr(self, expr):
        return self.environment.get(expr.name)

    def visit_assign_expr(self, expr):
        value = self.evaluate(expr.value)
        self.environment.assign(expr.name, value)
        return value

    def execute(self, stmt):
        return stmt.accept(self)

    def is_truthy(self, obj):
        if obj is None:
            return False
        if isinstance(obj, bool):
            return
        return True

    def is_equal(self, obj1, obj2):
        if obj1 is None and obj2 is None:
            return True
        if obj1 is None:
            return False
        return obj1 == obj2

    def _check_number_operand(self, operator, operand):
        if type(operand) == float:
            return
        raise RuntimeException(operator, "Operand must be a number.")

    def _check_number_operands(self, operator, left, right):
        if type(left) == float and type(right) == float:
            return
        raise RuntimeException(operator, "Operands must be numbers.")
Exemplo n.º 13
0
 def __init__(self) -> None:
     self.environment: Environment = Environment()
Exemplo n.º 14
0
 def visit_block(self, stmt: Stmt.Block) -> None:
     self.execute_block(stmt.statements, Environment(self.environment))