Esempio n. 1
0
def test_expression_pointer_decl():
    e2 = crep.cpp_value("dude", top_level_scope(), ctyp.terminal("int"))
    assert False == e2.is_pointer()

    e3 = crep.cpp_value("dude", top_level_scope(),
                        ctyp.terminal("int", is_pointer=True))
    assert True == e3.is_pointer()
Esempio n. 2
0
def test_sequence_type():
    tc = gc_scope_top_level()
    s_value = crep.cpp_value('0.0', tc, ctyp.terminal('int', False))
    i_value = crep.cpp_value('1.0', tc, ctyp.terminal('object', False))

    seq = crep.cpp_sequence(s_value, i_value, tc)

    assert seq.sequence_value().cpp_type().type == 'int'
Esempio n. 3
0
def test_variable_type_update():
    tc = gc_scope_top_level()
    expr = "a"
    ctype = ctyp.terminal('int', False)

    v = crep.cpp_variable(expr, tc, ctype)
    v.update_type(ctyp.terminal('float', False))

    assert v.cpp_type().type == 'float'
Esempio n. 4
0
def test_variable_type__with_initial_update():
    tc = gc_scope_top_level()
    expr = "a"
    c_type = ctyp.terminal('int', False)
    c_init = crep.cpp_value('0.0', tc, ctyp.terminal('int', False))

    v = crep.cpp_variable(expr, tc, c_type, c_init)
    v.update_type(ctyp.terminal('float', False))

    assert v.cpp_type().type == 'float'
    assert v.initial_value().cpp_type().type == 'float'
def test_as_root_as_single_column():
    q = query_ast_visitor()
    node = ast.parse('1/1')
    value_obj = crep.cpp_value('i', gc_scope_top_level(), ctyp.terminal('int'))
    sequence = crep.cpp_sequence(
        value_obj,
        crep.cpp_value('i', gc_scope_top_level(), ctyp.terminal('int')),
        gc_scope_top_level())
    node.rep = sequence  # type: ignore
    as_root = q.get_as_ROOT(node)

    assert isinstance(as_root, rh.cpp_ttree_rep)
Esempio n. 6
0
def test_deepest_scope_equal():
    g = generated_code()
    s1 = statement.iftest("true")
    s2 = statement.set_var("v1", "true")
    g.add_statement(s1)
    scope_1 = g.current_scope()

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

    assert v1 == deepest_scope(v1, v2)
    assert v2 == deepest_scope(v2, v1)
Esempio n. 7
0
def determine_type_mf(parent_type, function_name):
    '''
    Determine the return type of the member function. Do our best to make
    an intelligent case when we can.

    parent_type:        the type of the parent
    function_name:      the name of the function we are calling
    '''
    # If we don't know the type...
    if parent_type is None:
        raise RuntimeError("Internal Error: Trying to call member function for a type we do not know!")
    # If we are doing one of the normal "terminals", then we can just bomb. This should not happen!

    rtn_type = ctyp.method_type_info(str(parent_type), function_name)
    if rtn_type is not None:
        return rtn_type

    # We didn't know it. Lets make a guess, and error out if we are clearly making a mistake.
    base_types = ['double', 'float', 'int']
    s_parent_type = str(parent_type)
    if s_parent_type in base_types:
        raise xAODTranslationError(f'Unable to call method {function_name} on type {str(parent_type)}.')

    # Ok - we give up. Return a double.
    logging.getLogger(__name__).warning(f"Warning: assumping that the method '{str(s_parent_type)}.{function_name}(...)' has return type 'double'. Use cpp_types.add_method_type_info to suppress (or correct) this warning.")
    return ctyp.terminal('double')
Esempio n. 8
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
Esempio n. 9
0
def getAttributeFloatAst(call_node: ast.Call):
    r'''
    Return an attribute on one of the xAOD objects.
    '''
    # Get the name of the moment out
    if len(call_node.args) != 1:
        raise Exception(
            "Calling getAttributeFloat - only one argument is allowed")
    if not isinstance(call_node.args[0], ast.Str):
        raise Exception(
            "Calling getAttributeFloat - only acceptable argument is a string")

    r = cpp_ast.CPPCodeValue()
    # We don't need include files for this - just quick access
    r.args = [
        'moment_name',
    ]
    r.replacement_instance_obj = ('obj_j', call_node.func.value.id
                                  )  # type: ignore
    r.running_code += [
        'float result = obj_j->getAttribute<float>(moment_name);'
    ]
    r.result = 'result'
    r.result_rep = lambda sc: crep.cpp_variable(
        unique_name("jet_attrib"), scope=sc, cpp_type=ctyp.terminal('float'))

    # Replace it as the function that is going to get called.
    call_node.func = r  # type: ignore

    return call_node
def test_as_root_as_dict():
    q = query_ast_visitor()
    node = ast.parse('1/1')
    dict_obj = crep.cpp_dict(
        {
            ast.Constant(value='hi'):
            crep.cpp_value('i', gc_scope_top_level(), ctyp.terminal('int'))
        }, gc_scope_top_level())
    sequence = crep.cpp_sequence(
        dict_obj,  # type: ignore
        crep.cpp_value('i', gc_scope_top_level(), ctyp.terminal('int')),
        gc_scope_top_level())
    node.rep = sequence  # type: ignore
    as_root = q.get_as_ROOT(node)

    assert isinstance(as_root, rh.cpp_ttree_rep)
Esempio n. 11
0
def test_cpp_value_as_str():
    'Make sure we can generate a str from a value - this will be important for errors'
    v1 = crep.cpp_value('dude', top_level_scope(), ctyp.terminal('int'))
    assert 'dude' in str(v1)

    v2 = crep.cpp_value('dude', top_level_scope(), None)
    assert 'dude' in str(v2)
Esempio n. 12
0
def getAttributeVectorFloatAst(call_node: ast.Call):
    r'''
    Return a cpp ast accessing a vector of doubles for an xAOD attribute
    '''
    # Get the name of the moment out
    if len(call_node.args) != 1:
        raise Exception(
            "Calling getAttributeVectorFloat - only one argument is allowed")
    if not isinstance(call_node.args[0], ast.Str):
        raise Exception(
            "Calling getAttributeVectorFloat - only acceptable argument is a string"
        )

    r = cpp_ast.CPPCodeValue()
    r.include_files += ['vector']
    r.args = [
        'moment_name',
    ]
    r.replacement_instance_obj = ('obj_j', call_node.func.value.id
                                  )  # type: ignore
    r.running_code += [
        'auto result = obj_j->getAttribute<std::vector<double>>(moment_name);'
    ]
    r.result = 'result'
    r.result_rep = lambda sc: crep.cpp_collection(
        unique_name("jet_vec_attrib_"),
        scope=sc,
        collection_type=ctyp.collection(ctyp.terminal('double')
                                        ))  # type: ignore

    # Replace it as the function that is going to get called.
    call_node.func = r  # type: ignore

    return call_node
Esempio n. 13
0
def test_variable_pointer():
    'Make sure is_pointer can deal with a non-type correctly'
    v1 = crep.cpp_value('dude', top_level_scope(), ctyp.terminal('int'))
    v2 = crep.cpp_value('dude', top_level_scope(), None)

    assert v1.cpp_type().type == 'int'
    with pytest.raises(RuntimeError) as e:
        v2.cpp_type()
Esempio n. 14
0
    def visit_BinOp(self, node):
        'An in-line add'
        if type(node.op) not in _known_binary_operators:
            raise Exception(f"Do not know how to translate Binary operator {ast.dump(node.op)}!")
        left = self.get_rep(node.left)
        right = self.get_rep(node.right)

        best_type = most_accurate_type([left.cpp_type(), right.cpp_type()])
        if type(node.op) is ast.Div:
            best_type = ctyp.terminal('double', False)

        s = deepest_scope(left, right).scope()
        r = crep.cpp_value(f"({left.as_cpp()}{_known_binary_operators[type(node.op)]}{right.as_cpp()})",
                           s, best_type)

        # Cache the result to push it back further up.
        node.rep = r
        self._result = r
Esempio n. 15
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
Esempio n. 16
0
def test_accurate_type_int_and_float():
    t1 = ctyp.terminal('int', False)
    t2 = ctyp.terminal('float', False)
    r = most_accurate_type([t1, t2])
    assert r._type == 'float'
Esempio n. 17
0
def test_accurate_type_two_int():
    t1 = ctyp.terminal('int', False)
    t2 = ctyp.terminal('int', False)
    r = most_accurate_type([t1, t2])
    assert r._type == 'int'
def test_can_call_prodVtx():
    ctyp.add_method_type_info("xAOD::TruthParticle", "prodVtx", ctyp.terminal('xAODTruth::TruthVertex', is_pointer=True))
    dataset_for_testing("file://root.root") \
        .Select("lambda e: e.TruthParticles('TruthParticles').Select(lambda t: t.prodVtx().x()).Sum()") \
        .value()
Esempio n. 19
0
def guess_type_from_number(n):
    if int(n) == n:
        return ctyp.terminal("int")
    return ctyp.terminal("double")
Esempio n. 20
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
Esempio n. 21
0
def test_int_pointer():
    t_int = ctyp.terminal('int')
    assert False == t_int.is_pointer()
Esempio n. 22
0
 def visit_Str(self, node):
     node.rep = crep.cpp_value('"{0}"'.format(node.s), self._gc.current_scope(), ctyp.terminal("string"))
     self._result = node.rep
Esempio n. 23
0
def test_method_type_found():
    ctyp.add_method_type_info("bogus", "pt", ctyp.terminal('double'))
    assert 'double' == str(ctyp.method_type_info("bogus", "pt"))
Esempio n. 24
0
 def element_type(self):
     'Return the type of the elements in the collection'
     return ctyp.terminal(self._element_name, is_pointer=True)
Esempio n. 25
0
                       'ANA_CHECK (evtStore()->retrieve(result, collection_name));']
    r.result = 'result'

    is_collection = info['is_collection'] if 'is_collection' in info else True
    if is_collection:
        r.result_rep = lambda scope: crep.cpp_collection(unique_name(info['function_name'].lower()), scope=scope, collection_type=info['container_type'])  # type: ignore
    else:
        r.result_rep = lambda scope: crep.cpp_variable(unique_name(info['function_name'].lower()), scope=scope, cpp_type=info['container_type'])

    # Replace it as the function that is going to get called.
    call_node.func = r

    return call_node


# Config everything.
def create_higher_order_function(info):
    'Creates a higher-order function because python scoping is broken'
    return lambda call_node: getCollection(info, call_node)


for info in collections:
    cpp_ast.method_names[info['function_name']] = create_higher_order_function(info)


# Configure some info about the types.
ctyp.add_method_type_info("xAOD::TruthParticle", "prodVtx", ctyp.terminal('xAODTruth::TruthVertex', is_pointer=True))
ctyp.add_method_type_info("xAOD::TruthParticle", "decayVtx", ctyp.terminal('xAODTruth::TruthVertex', is_pointer=True))
ctyp.add_method_type_info("xAOD::TruthParticle", "parent", ctyp.terminal('xAOD::TruthParticle', is_pointer=True))
ctyp.add_method_type_info("xAOD::TruthParticle", "child", ctyp.terminal('xAOD::TruthParticle', is_pointer=True))
Esempio n. 26
0
def test_accurate_type_float_and_double():
    t1 = ctyp.terminal('double', False)
    t2 = ctyp.terminal('float', False)
    r = most_accurate_type([t1, t2])
    assert r._type == 'double'
Esempio n. 27
0
def test_accurate_type_single_int():
    t = ctyp.terminal('int', False)
    r = most_accurate_type([t])
    assert r._type == 'int'
Esempio n. 28
0
    def visit_Compare(self, node):
        'A compare between two things. Python supports more than that, but not implemented yet.'
        if len(node.ops) != 1:
            raise Exception("Do not support 1 < a < 10 comparisons yet!")

        left = self.get_rep(node.left)
        right = self.get_rep(node.comparators[0])

        r = crep.cpp_value('({0}{1}{2})'.format(left.as_cpp(), compare_operations[type(node.ops[0])], right.as_cpp()), self._gc.current_scope(), ctyp.terminal("bool"))
        node.rep = r
        self._result = r
Esempio n. 29
0
 def __init__(self, filename, treename, scope):
     cpp_value.__init__(self, unique_name("ttree_rep"), scope, ctyp.terminal("ttreetfile"))
     self.filename = filename
     self.treename = treename
Esempio n. 30
0
def test_terminal_type():
    t = ctyp.terminal('double', False)
    assert t.type == 'double'