Exemplo n.º 1
0
def do_pass(plant):
    """ This pass follows the links up to the nodes which are the one defining
    the actual channels.
    """
    # Collect the needed information and the nodes to consider.
    v = AstVisitor({'node'          : node,
                    'linux'         : sys,
                    'lynxsecure'    : hypervisor,
                    'certikos'      : hypervisor,
                    'lynxsecure_vm' : machine,
                    'certikos_vm'   : machine,
                    'machine'       : machine },
                   onleaf=follow_links(AstVisitor.leaf_bf), #@UndefinedVariable
                   kind='bf')
    # Create a dict having ast nodes as keys (qnames),
    plantinfo = tools.DictfromField('_qname')()
    plantinfo.nodes = []
    plantinfo.topics = []
    plantinfo.machines = []
    plantinfo.plant = plant
    v.visit(plant, plantinfo)

    channels.do_pass(plantinfo)

    return plantinfo
Exemplo n.º 2
0
def gen(ast):
    name_dag = dict()
    decls = dict()
    defs = dict()
    d = dict({
        'assgns': '',
        'vdecls': '',
        'include_user_module_header': '',
        'post_init_hook': ''
    })
    visitor = AstVisitor({'module_settings': module_settings},
                         default=collect_node,
                         onleaf=collect_leaf,
                         kind='red')
    visitor.visit(ast, (name_dag, decls, defs, d))
    names_sccs = tarjan(name_dag)
    d['header_defsdecls'] = ''
    #First declare the types
    for scc in names_sccs:
        #write all typedefs first to allow circular refs
        if len(scc) > 1:
            #For now, since types are not recursive, we should not have scc.
            #             internal_error("We have a scc of size {}".format(len(scc)))
            pass
        for tname in scc:
            tdecl = decls.get(tname, None)
            if tdecl:
                d['header_defsdecls'] += tdecl
        #write the definitions
        for tname in scc:
            tdef = defs.get(tname, None)
            if tdef:
                str
                d['header_defsdecls'] += tdef

    d['asttype'] = qn.c_typename(ast)
    d['astvalue'] = qn.c_varname(ast)
    d['astinit'] = qn.c_modinit(ast)
    d['astfun'] = qn.c_astfun(ast)

    d['ast_includes'] = d['includes_init'] = ''
    for n in infos.loaded_modules:
        d['ast_includes'] += '\n#include "{}"'.format(qn.file_ast(n))
        d['includes_init'] += '\n  {}();'.format(qn.c_modinit(n))

    d['ast_h_filename'] = qn.file_ast(ast, '.h')
    d['ast_c_filename'] = qn.file_ast(ast, '.c')

    return (d['ast_c_filename'], cpp_template.format(**d), d['ast_h_filename'],
            header_template.format(**d))
Exemplo n.º 3
0
def do_pass(ast, root_namespace):
    """ Transform alias nodes into leafs of type Alias,
    behaving like the Ident it points to.
    This has to be done with a frozen ast or extra care is needed after this.
    """
    def _alias(visitor, node, _):
        internal_assert(len(node._children) == 1, "incorrect alias node")
        ident = node._children[0]
        internal_assert(isinstance(ident, Ident), "incorrect alias node")
        a = Alias(node._qname, node._location, ident)
        return a, _

    visitor = AstVisitor({'_alias': _alias}, inplace=True, kind='mapacc')
    visitor.visit(ast, ())
    update_idents(ast, root_namespace)
Exemplo n.º 4
0
def reduce(astnode, filter_pred):
    def default(visitor, n, _):
        t = types.of(n)
        if isinstance(t, str):  # Basic value
            return language.interpret_value(t, n._val), _
        else:
            return (str(n._qname), visitor.visit(filter_pred(n._children),
                                                 _)[0]), _

    def array(visitor, a, _):
        return (str(a._qname), [visitor.visit(x, _)[0]
                                for x in a['VALUES']]), _

    def struct(visitor, s, _):
        return (str(s._qname),
                {x._name: visitor.visit(x, _)[0]
                 for x in s['FIELDS']}), _

    visitor = AstVisitor(
        {
            'array': array,
            'struct': struct,
            'topic': struct
        },
        default=default,
        onleaf=follow_links(AstVisitor.leaf_mapacc),  #@UndefinedVariable
        kind='mapacc')
    return visitor.visit(astnode, ())[0]
Exemplo n.º 5
0
def gen_launchfiles(plantinfo, package_name, package_folder):
    """ This pass is in charge of generating the launch files specific to a plant.
    The corresponding package is supposed to be already generated.
    @return: the list of generated file handles
    """

    ## Do the actual plant pass to generate the needed launch files.

    d = dict()
    d['source_file'] = str(infos.source_file)
    v = AstVisitor(
        fun_dict_of((machine, node)),
        onleaf=follow_links(AstVisitor.leaf_bf),  #@UndefinedVariable
        kind='bf')
    d['package_path'] = package_folder
    d['launch_files'] = []
    v.visit(plantinfo.plant, d)

    return d['launch_files']
Exemplo n.º 6
0
def plant2dot(plantinfo):
    qn = str(plantinfo.plant._qname)
    # Create the hierarchical graph with all the nodes (no edges for now)
    plantd = Dot(qn,
                 simplify=True,
                 comment="Generated by radler for {}".format(qn))
    v = AstVisitor({'node' : node,
                    'lynxsecure_vm' : machine,
                    'certikos_vm'   : machine,
                    'machine'       : machine },
                   onleaf=follow_links(AstVisitor.leaf_bf), #@UndefinedVariable
                   kind='bf')
    v.visit(plantinfo.plant, plantd)

    # Add all edges
    for cl in plantinfo.channels.values():
        for c in cl:
            if c.incoming:
                plantd.add_edge(Edge(str(c.pub), str(c.sub)))
    print(plantd.to_string())
Exemplo n.º 7
0
def gen(localroot, msg_list, msg_dir, ast, extra_files=None):

    onleaf = AstVisitor.leaf_bf  # @UndefinedVariable

    visitor = AstVisitor({'node' : _from_node}, kind='bf', onleaf=onleaf)

    d = {'module'     : ast._name,
         'module_lib' : qn.cmake_ast(ast._qname.rootmodule()),
         'ast_fun'    : qn.c_astfun(ast),
         '_localroot' : localroot
         }

    clear(d, cmake_templates)
    clear(d, cmake_msgs_templates)
    clear(d, node_templates_cmake_sublevel)

    visitor.visit(ast, d)

    toload = infos.loaded_modules
    loaded_modules = ' '.join(qn.cmake_ast(n) for n in toload)
    d['find_modules'] = d['module_lib'] + ' radl_lib roscpp ' + loaded_modules
    d['run_modules'] = ' roscpp'
    d['ros_modules'] = ' '.join(n.name() for n in toload)

# Trying to be smart make dependencies hard since otherwise we can't blindly
# add any ros package as a message dependency.
#     if len(msg_list) > 0:

    msg_files = (str(relative_path(m, msg_dir)) for m in msg_list)
    d['msg_files'] = listjoin(' ', msg_files)
    d['extra_files'] = listjoin(' ', extra_files) if extra_files else ''
    d['find_modules'] += ' message_generation'
    d['run_modules'] += ' message_runtime'

    app(d, cmake_msgs_templates)

    app(d, cmake_templates)

    write_file(localroot / "CMakeLists.txt", d['cmakeliststxt'])
Exemplo n.º 8
0
def collect(package_folder, package_name, ast, generate_all):
    """ return a set of struct types to be generated.
    It is not to be generated if it has a field EXTERNAL_ROS_DEF,
    or if it is already in infos.ros_types.
    """
    def _st(visitor, node, s):
        """ s is a mapping between names and filepath of messages to generate.
        """
        if node._kind == 'topic':  #special treatment to add private fields
            t = struct_of_topic(types.of(node))
        else:
            t = types.of(node)
        ext_rd = node['EXTERNAL_ROS_DEF']
        if ext_rd:  #External def to be used
            name = ext_rd['FULLNAME']._val
            header = ext_rd['HEADER']._val
        else:
            reg_name = infos.ros_type_of_struct.get(t, None)
            if not reg_name:  #Msg name and file to create
                msgname = qn.rosmsg(node)
                s[t] = msg_msg_file(package_folder, msgname)
                msgpkg = package_name
                infos.ros_type_of_struct[t] = (msgpkg, msgname)
            else:  #Msg file already created
                (msgpkg, msgname) = reg_name
            header = msg_cpp_header(msgpkg, msgname)
            #keep only the actual string to identify the type and header file
            name = msg_cpp_qname(msgpkg, msgname)
        #Store our findings in the node for future retrieval
        node._ros_msgtype_name = name
        node._ros_msgtype_header = header
        return visitor.node_red(node, s)  #recursive call

    if generate_all:
        onleaf = onleaf = follow_links(
            AstVisitor.leaf_red)  # @UndefinedVariable
    else:
        onleaf = AstVisitor.leaf_red  # @UndefinedVariable

    visitor = AstVisitor({
        'topic': _st,
        'struct': _st
    },
                         kind='red',
                         onleaf=onleaf)
    s = visitor.visit(ast, dict())
    return s
Exemplo n.º 9
0
def _check_and_map_topics_publisher(ast):
    """ When there is one and only one publisher per topic, cross ref the publisher
    in the topic as topic._publisher"""
    def publication(visitor, pub, acc):
        """ Publication are not recursives """
        node, maping = acc
        top = pub['TOPIC']
        if top._qname in maping:
            error("Topic {} has multiple publisher.".format(top), top._location)
        maping[top._qname] = Ident.of(node)
        return pub, (node, maping)
    def node(visitor, node, acc):
        """ set the current node in the accumulator """
        _, maping = acc
        acc = node, maping
        return visitor.node_mapacc(node, acc)

    visitor = AstVisitor(locals(), inplace=True)
    _, (_, maping) = visitor.visit(ast, (None, {}))
    return maping
Exemplo n.º 10
0
def _check_and_map_topics_publisher(ast):
    """ When there is one and only one publisher per topic, cross ref the publisher
    in the topic as topic._publisher"""
    def publication(visitor, pub, acc):
        """ Publication are not recursives """
        node, maping = acc
        top = pub['TOPIC']
        if top._qname in maping:
            error("Topic {} has multiple publisher.".format(top),
                  top._location)
        maping[top._qname] = Ident.of(node)
        return pub, (node, maping)

    def node(visitor, node, acc):
        """ set the current node in the accumulator """
        _, maping = acc
        acc = node, maping
        return visitor.node_mapacc(node, acc)

    visitor = AstVisitor(locals(), inplace=True)
    _, (_, maping) = visitor.visit(ast, (None, {}))
    return maping
Exemplo n.º 11
0
def collect(ast):
    """ return a set of struct types to be generated.
    It is not to be generated if it has a field EXTERNAL_ROS_DEF,
    or if it is already in infos.ros_types.
    """
    def _st(visitor, node, s):
        """ s is a mapping between names and filepath of messages to generate.
        """
        if node._kind == 'topic':  #special treatment to add private fields
            t = struct_of_topic(types.of(node))
        else:
            t = types.of(node)
        ext_rd = node['EXTERNAL_ROS_DEF']
        if ext_rd:  #External def to be used
            name = ext_rd['FULLNAME']._val
            header = ext_rd['HEADER']._val
        else:
            reg_name = infos.ros_type_of_struct.get(t, None)
            if not reg_name:  #Msg name and file to create
                name = ast._namespace.generate('radl__msg')
                #note: the .msg file is different from the header linked to it
                s[t] = filepath(qn_msgfile(name, suffix='.msg'))
                infos.ros_type_of_struct[t] = name
            else:  #Msg file already created
                name = reg_name
            header = qn_file(name, suffix='.h')
            #keep only the actual string to identify the type and header file
            name = qn_cpp(name)
        #Store our findings in the node for future retrieval
        node._ros_msgtype_name = name
        node._ros_msgtype_header = header
        return visitor.node_mapacc(node, s)  #recursive call

    visitor = AstVisitor({'topic': _st, 'struct': _st})
    _, s = visitor.visit(ast, dict())
    return s
Exemplo n.º 12
0
def collect(ast):
    """ return a set of struct types to be generated.
    It is not to be generated if it has a field EXTERNAL_ROS_DEF,
    or if it is already in infos.ros_types.
    """
    def _st(visitor, node, s):
        """ s is a mapping between names and filepath of messages to generate.
        """
        if node._kind == 'topic': #special treatment to add private fields
            t = struct_of_topic(types.of(node))
        else:
            t = types.of(node)
        ext_rd = node['EXTERNAL_ROS_DEF']
        if ext_rd: #External def to be used
            name = ext_rd['FULLNAME']._val
            header = ext_rd['HEADER']._val
        else:
            reg_name = infos.ros_type_of_struct.get(t, None)
            if not reg_name: #Msg name and file to create
                name = ast._namespace.generate('radl__msg')
                #note: the .msg file is different from the header linked to it
                s[t] = filepath(qn_msgfile(name, suffix='.msg'))
                infos.ros_type_of_struct[t] = name
            else: #Msg file already created
                name = reg_name
            header = qn_file(name, suffix='.h')
            #keep only the actual string to identify the type and header file
            name = qn_cpp(name)
        #Store our findings in the node for future retrieval
        node._ros_msgtype_name = name
        node._ros_msgtype_header = header
        return visitor.node_mapacc(node, s) #recursive call

    visitor = AstVisitor({'topic': _st, 'struct' : _st})
    _, s = visitor.visit(ast, dict())
    return s
Exemplo n.º 13
0
def do_pass(ast):
    """ Add a _wd attribute to nodes indicating current user path."""
    visitor = AstVisitor(default=_wd, kind='bf')
    visitor.visit(ast, Path())
Exemplo n.º 14
0
def add(ast):
    """ Add a _pwd attribute to nodes indicating current user path."""
    visitor = AstVisitor(default=_pwd, mapacc=True)
    path = Path()
    visitor.visit(ast, path)
Exemplo n.º 15
0
def do_pass(ast):
    visitor = AstVisitor({'module_settings' : module_settings}, kind='red')
    visitor.visit(ast, False)
Exemplo n.º 16
0
def do_pass(ast):
    v = AstVisitor(fun_dict_of((node, )), kind='bf')
    v.visit(ast, ())
Exemplo n.º 17
0
def do_pass(ast):
    v = AstVisitor(default=onnode, onleaf=onleaf, kind='bf')
    v.visit(ast, [])
Exemplo n.º 18
0
def do_pass(ast):
    visitor = AstVisitor({'struct': onstruct, 'topic': onstruct}, kind='bf')
    visitor.visit(ast)