Пример #1
0
def test_deepest_scope_one_greater():
    g = generated_code()
    s1 = statement.iftest("true")
    s2 = statement.iftest("true")
    g.add_statement(s1)
    scope_1 = g.current_scope()
    g.add_statement(s2)
    scope_2 = g.current_scope()

    v1 = crep.cpp_value("v1", scope_1, ctyp.terminal('int'))
    v2 = crep.cpp_value("v2", scope_2, ctyp.terminal('int'))

    assert v2 == deepest_scope(v1, v2)
    assert v2 == deepest_scope(v2, v1)
Пример #2
0
    def visit_BoolOp(self, node):
        '''A bool op like And or Or on a set of values
        This is a bit more complex than just "anding" things as we want to make sure to short-circuit the
        evaluation if we need to.
        '''

        # The result of this test
        result = crep.cpp_variable(unique_name('bool_op'), self._gc.current_scope(), cpp_type='bool')
        self._gc.declare_variable(result)

        # How we check and short-circuit depends on if we are doing and or or.
        check_expr = result.as_cpp() if type(node.op) == ast.And else '!{0}'.format(result.as_cpp())
        check = crep.cpp_value(check_expr, self._gc.current_scope(), cpp_type=ctyp.terminal('bool'))

        first = True
        scope = self._gc.current_scope()
        for v in node.values:
            if not first:
                self._gc.add_statement(statement.iftest(check))

            rep_v = self.get_rep(v)
            self._gc.add_statement(statement.set_var(result, rep_v))

            if not first:
                self._gc.set_scope(scope)
            first = False

        # Cache result variable so those above us have something to use.
        self._result = result
        node.rep = result
Пример #3
0
    def call_Where(self, node: ast.AST, args: List[ast.AST]):
        'Apply a filtering to the current loop.'

        assert len(args) == 2
        source = args[0]
        filter = args[1]
        assert isinstance(filter, ast.Lambda)

        # Make sure we are in a loop
        seq = self.as_sequence(source)

        # Simulate the filtering call - we want the resulting value to test.
        filter = lambda_unwrap(filter)
        c = ast.Call(func=filter, args=[seq.sequence_value().as_ast()])
        rep = self.get_rep(c)

        # Create an if statement
        self._gc.add_statement(statement.iftest(rep))

        # Ok - new sequence. This the same as the old sequence, only the sequence value is updated.
        # Protect against sequence of sequences (LOVE type checkers, which caught this as a possibility)
        w_val = seq.sequence_value()
        if isinstance(w_val, crep.cpp_sequence):
            raise Exception("Error: A Where clause must evaluate to a value, not a sequence")
        new_sequence_var = w_val.copy_with_new_scope(self._gc.current_scope())
        node.rep = crep.cpp_sequence(new_sequence_var, seq.iterator_value(), self._gc.current_scope())  # type: ignore

        self._result = node.rep  # type: ignore
Пример #4
0
def test_get_rep_works_and_doesnt():
    g = generated_code()
    s1 = statement.iftest("true")
    g.set_rep("dude", 5)
    assert 5 is g.get_rep("dude")
    g.pop_scope()
    assert None is g.get_rep("dude")
Пример #5
0
    def visit_IfExp(self, node):
        r'''
        We'd like to be able to use the "?" operator in C++, but the
        problem is lazy evaluation. It could be when we look at one or the
        other item, a bunch of prep work has to be done - and that will
        show up in separate statements. So we have to use if/then/else with
        a result value.
        '''

        # The result we'll store everything in.
        result = crep.cpp_variable(unique_name("if_else_result"), self._gc.current_scope(), cpp_type=ctyp.terminal("double"))
        self._gc.declare_variable(result)

        # We always have to evaluate the test.
        current_scope = self._gc.current_scope()
        test_expr = self.get_rep(node.test)
        self._gc.add_statement(statement.iftest(test_expr))
        if_scope = self._gc.current_scope()

        # Next, we do the true and false if statement.
        self._gc.add_statement(statement.set_var(result, self.get_rep(node.body)))
        self._gc.set_scope(if_scope)
        self._gc.pop_scope()
        self._gc.add_statement(statement.elsephrase())
        self._gc.add_statement(statement.set_var(result, self.get_rep(node.orelse)))
        self._gc.set_scope(current_scope)

        # Done, the result is the rep of this node!
        node.rep = result
        self._result = result
Пример #6
0
def test_insert_in_middle():
    s1 = statement.iftest("true")
    s2 = statement.set_var("v1", "true")
    g = generated_code()

    g.add_statement(s1)
    g.add_statement(s2)

    s3 = statement.iftest("fork")
    g.add_statement(s3, below=s1)

    assert 1 == len(s1._statements)
    assert 1 == len(s3._statements)

    assert s1._statements[0] is s3
    assert s3._statements[0] is s2
Пример #7
0
def test_nothing_else_starts_with_top_level_scope():
    top = gc_scope_top_level()
    g = generated_code()
    s1 = statement.iftest("true")
    g.add_statement(s1)
    scope_1 = g.current_scope()

    assert not top.starts_with(scope_1)
Пример #8
0
def test_everything_starts_with_top_level_scope():
    top = gc_scope_top_level()
    g = generated_code()
    s1 = statement.iftest("true")
    g.add_statement(s1)
    scope_1 = g.current_scope()

    assert scope_1.starts_with(top)
Пример #9
0
def test_get_rep_hidden():
    g = generated_code()
    g.set_rep("dude", 5)
    s1 = statement.iftest("true")
    g.add_statement(s1)
    g.set_rep("dude", 10)
    assert 10 is g.get_rep("dude")
    g.pop_scope()
    assert 5 is g.get_rep("dude")
Пример #10
0
def test_insert_two_levels():
    s1 = statement.iftest("true")
    s2 = statement.set_var("v1", "true")
    g = generated_code()

    g.add_statement(s1)
    g.add_statement(s2)

    assert 1 == len(s1._statements)
Пример #11
0
    def call_First(self, node: ast.AST, args: List[ast.AST]) -> Any:
        'We are in a sequence. Take the first element of the sequence and use that for future things.'

        # Unpack the source here
        assert len(args) == 1
        source = args[0]

        # Make sure we are in a loop.
        seq = self.as_sequence(source)

        # The First terminal works by protecting the code with a if (first_time) {} block.
        # We need to declare the first_time variable outside the block where the thing we are
        # looping over here is defined. This is a little tricky, so we delegate to another method.
        loop_scope = seq.iterator_value().scope()
        outside_block_scope = loop_scope[-1]

        # Define the variable to track this outside that block.
        is_first = crep.cpp_variable(unique_name('is_first'),
                                     outside_block_scope,
                                     cpp_type=ctyp.terminal('bool'),
                                     initial_value=crep.cpp_value('true', self._gc.current_scope(), ctyp.terminal('bool')))
        outside_block_scope.declare_variable(is_first)

        # Now, as long as is_first is true, we can execute things inside this statement.
        # The trick is putting the if statement in the right place. We need to locate it just one level
        # below where we defined the scope above.
        s = statement.iftest(is_first)
        s.add_statement(statement.set_var(is_first, crep.cpp_value('false', top_level_scope(), cpp_type=ctyp.terminal('bool'))))

        sv = seq.sequence_value()
        if isinstance(sv, crep.cpp_sequence):
            self._gc.set_scope(sv.iterator_value().scope()[-1])
        else:
            self._gc.set_scope(sv.scope())
        self._gc.add_statement(s)

        # If we just found the first sequence in a sequence, return that.
        # Otherwise return a new version of the value.
        first_value = sv if isinstance(sv, crep.cpp_sequence) else sv.copy_with_new_scope(self._gc.current_scope())

        node.rep = first_value  # type: ignore
        self._result = first_value
Пример #12
0
def test_get_rep_when_set_level_up():
    g = generated_code()
    g.set_rep("dude", 5)
    s1 = statement.iftest("true")
    g.add_statement(s1)
    assert 5 is g.get_rep("dude")