Example #1
0
def generate(models):
    types = set()
    for model in models.values():
        for key, value in model.allitems():
            if key == 'property':
                name = value.get('name')
                type = value.get('type')
                card = value.get('card')

                if (name != 'type') and (type != 'any') and (card == 'any'):
                    types.add(type)

            elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']:
                card = value.get('card')

                if card == 'any':
                    type = 'any' if key == 'group_ref' else value.get('type')
                    types.add(type)

    containers = []
    for type in sorted(types):
        containers.append(f'  typedef std::vector<{type}*> VectorOf{type};')
        containers.append(f'  typedef std::vector<{type}*>::iterator VectorOf{type}Itr;')
        containers.append('')
    containers = '\n'.join(containers)

    with open(config.get_template_filepath('containers.h'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<CONTAINERS>', containers)
    file_utils.set_content_if_changed(config.get_output_header_filepath('containers.h'), file_content)
    return True
Example #2
0
def generate(models):
    types = '\n'.join([f'  {name} = {id},' for name, id in get_type_map(models).items()])

    with open(config.get_template_filepath('uhdm_types.h'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<DEFINES>', types)
    file_utils.set_content_if_changed(config.get_output_header_filepath('uhdm_types.h'), file_content)
    return True
Example #3
0
def generate(models):
    with open(config.get_template_filepath('clone_tree.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<CLONE_IMPLEMENTATIONS>', '')
    file_utils.set_content_if_changed(
        config.get_output_source_filepath('clone_tree.cpp'), file_content)

    return True
Example #4
0
def generate(models):
    methods = get_methods(models, '', '')

    with open(config.get_template_filepath('VpiListener.h'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<VPI_LISTENER_METHODS>',
                                        '\n'.join(methods))
    file_utils.set_content_if_changed(
        config.get_output_header_filepath('VpiListener.h'), file_content)
    return True
Example #5
0
def generate(models):
    classnames = [model['name'] for model in models.values()]
    headers = '\n'.join(
        [f'#include "uhdm/{classname}.h"' for classname in classnames])

    with open(config.get_template_filepath('uhdm.h'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<INCLUDE_FILES>', headers)
    file_utils.set_content_if_changed(
        config.get_output_header_filepath('uhdm.h'), file_content)
    return True
Example #6
0
def generate(models):
    classnames = [
        model['name'] for model in models.values()
        if model['type'] != 'group_def'
    ]
    declarations = '\n'.join([
        f'class {classname};' for classname in sorted(classnames)
        if classname != 'BaseClass'
    ])

    with open(config.get_template_filepath('uhdm_forward_decl.h'),
              'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<UHDM_FORWARD_DECL>', declarations)
    file_utils.set_content_if_changed(
        config.get_output_header_filepath('uhdm_forward_decl.h'), file_content)
    return True
Example #7
0
def generate(models):
    module_listeners = _generate_module_listeners(models)
    class_listeners = _generate_class_listeners(models)

    with open(config.get_template_filepath('ElaboratorListener.cpp'),
              'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace(
        '<MODULE_ELABORATOR_LISTENER>',
        (' ' * 10) + ('\n' + (' ' * 10)).join(module_listeners))
    file_content = file_content.replace(
        '<CLASS_ELABORATOR_LISTENER>',
        (' ' * 4) + ('\n' + (' ' * 4)).join(class_listeners))
    file_utils.set_content_if_changed(
        config.get_output_source_filepath('ElaboratorListener.cpp'),
        file_content)

    return True
Example #8
0
def generate(models):
    templates = {}
    for filename in [
            'class_header.h', 'class_source.cpp', 'group_header.h',
            'group_header.cpp'
    ]:
        template_filepath = config.get_template_filepath(filename)
        with open(template_filepath, 'r+t') as strm:
            templates[filename] = strm.read()

    for model in models.values():
        classname = model['name']
        modeltype = model['type']

        if modeltype == 'group_def':
            _generate_group_checker(model, models, templates)
        else:
            _generate_one_class(model, models, templates)

    return True
Example #9
0
def generate(models):
    vpi_get_value_classes = set()
    vpi_get_delay_classes = set()
    for model in models.values():
        modeltype = model['type']
        if modeltype != 'obj_def':
            continue

        classname = model['name']

        baseclass = classname
        while baseclass:
            for key, value in models[baseclass].allitems():
                if key == 'property' and value.get('card') == '1':
                    type = value.get('type')

                    if type == 'value':
                        vpi_get_value_classes.add(classname)

                    if type == 'delay':
                        vpi_get_delay_classes.add(classname)

            baseclass = models[baseclass]['extends']

    # headers = [ f"#include <uhdm/{model['name']}.h>" for model in models.values() ]
    headers = [
        f"#include <uhdm/{name}.h>" for name in sorted(
            set.union(vpi_get_value_classes, vpi_get_delay_classes))
    ]

    vpi_handle_by_name_body = [
        f'  if (object->GetSerializer()->symbolMaker.GetId(name) == static_cast<SymbolFactory::ID>(-1)) {{',
        '    return nullptr;', '  }',
        '  const BaseClass *const ref = object->GetByVpiName(std::string_view(name));',
        '  return (ref != nullptr) ? NewVpiHandle(ref) : nullptr;'
    ]

    vpi_handle_body = [
        '  auto [ref, ignored1, ignored2] = object->GetByVpiType(type);',
        '  return (ref != nullptr) ? NewHandle(ref->UhdmType(), ref) : nullptr;'
    ]

    vpi_iterate_body = [
        '  auto [ignored, refType, refVector] = object->GetByVpiType(type);',
        '  return (refVector != nullptr) ? NewHandle(refType, refVector) : nullptr;'
    ]

    vpi_get_body = [
        '  BaseClass::vpi_property_value_t value = obj->GetVpiPropertyValue(property);',
        '  return std::holds_alternative<int64_t>(value) ? std::get<int64_t>(value) : 0;'
    ]

    vpi_get_str_body = [
        '  BaseClass::vpi_property_value_t value = obj->GetVpiPropertyValue(property);',
        '  return std::holds_alternative<const char *>(value) ? const_cast<char *>(std::get<const char *>(value)) : nullptr;'
    ]

    vpi_get_value_body = [
        f'  const s_vpi_value* v = nullptr;', f'  switch (handle->type) {{'
    ] + [
        f'    case uhdm{classname}: v = String2VpiValue((({classname}*)obj)->VpiValue()); break;'
        for classname in sorted(vpi_get_value_classes)
    ] + [
        '    default: break;', f'  }}', f'  if (v != nullptr) *value_p = *v;'
    ] if vpi_get_value_classes else []

    vpi_get_delay_body = [
        f'  const s_vpi_delay* v = nullptr;',
        f'  switch (handle->type) {{',
    ] + [
        f'    case uhdm{classname}: v = String2VpiDelays((({classname}*)obj)->VpiDelay()); break;'
        for classname in sorted(vpi_get_delay_classes)
    ] + [
        '    default: break;', f'  }}', f'  if (v != nullptr) *delay_p = *v;'
    ] if vpi_get_delay_classes else []

    # vpi_user.cpp
    with open(config.get_template_filepath('vpi_user.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<HEADERS>', '\n'.join(headers))
    file_content = file_content.replace('<VPI_HANDLE_BY_NAME_BODY>',
                                        '\n'.join(vpi_handle_by_name_body))
    file_content = file_content.replace('<VPI_HANDLE_BODY>',
                                        '\n'.join(vpi_handle_body))
    file_content = file_content.replace('<VPI_ITERATE_BODY>',
                                        '\n'.join(vpi_iterate_body))
    file_content = file_content.replace('<VPI_SCAN_BODY>', '')
    file_content = file_content.replace('<VPI_GET_BODY>',
                                        '\n'.join(vpi_get_body))
    file_content = file_content.replace('<VPI_GET_STR_BODY>',
                                        '\n'.join(vpi_get_str_body))
    file_content = file_content.replace('<VPI_GET_VALUE_BODY>',
                                        '\n'.join(vpi_get_value_body))
    file_content = file_content.replace('<VPI_GET_DELAY_BODY>',
                                        '\n'.join(vpi_get_delay_body))
    file_utils.set_content_if_changed(
        config.get_output_source_filepath('vpi_user.cpp'), file_content)

    return True
Example #10
0
def generate(models):
    factory_declarations = []
    factory_methods = []
    factory_purge = []
    factory_stats = []
    factory_object_type_map = []

    save_ids = []
    save_objects = []
    saves_adapters = []

    restore_ids = []
    restore_objects = []
    restore_adapters = []

    type_map = uhdm_types_h.get_type_map(models)

    for model in models.values():
        modeltype = model['type']
        if modeltype == 'group_def':
            continue

        classname = model['name']
        Classname_ = classname[:1].upper() + classname[1:]
        Classname = Classname_.replace('_', '')

        baseclass = model.get('extends', 'BaseClass') or 'BaseClass'

        if modeltype != 'class_def':
            factory_declarations.append(f'    {classname}Factory {classname}Maker;')
            factory_methods.append(f'    {classname}* Make{Classname_}() {{ return Make<{classname}>(&{classname}Maker); }}')
            factory_object_type_map.append(f'  case uhdm{classname} /* = {type_map["uhdm" + classname]} */: return {classname}Maker.objects_[index];')

            save_ids.append(f'  SetSaveId_(&{classname}Maker);')
            save_objects.append(f'  VectorOfanySaveAdapter<{classname}, {Classname}>()({classname}Maker.objects_, this, cap_root.initFactory{Classname}({classname}Maker.objects_.size()));')

            restore_ids.append(f'  SetRestoreId_(&{classname}Maker, cap_root.getFactory{Classname}().size());')
            restore_objects.append(f'  VectorOfanyRestoreAdapter<{classname}, {Classname}>()(cap_root.getFactory{Classname}(), this, {classname}Maker.objects_);')

            factory_purge.append(f'  {classname}Maker.Purge();')
            factory_stats.append(f'  stats.insert(std::make_pair("{classname}", {classname}Maker.objects_.size()));')

        factory_declarations.append(f'    VectorOf{classname}Factory {classname}VectMaker;')
        factory_methods.append(f'    std::vector<{classname}*>* Make{Classname_}Vec() {{ return Make<{classname}>(&{classname}VectMaker); }}')

        saves_adapters.append(f'template<typename U>')
        saves_adapters.append(f'struct Serializer::AnySaveAdapter<{classname}, U> {{')
        saves_adapters.append(f'  void operator()(const {classname} *const obj, Serializer *const serializer, U builder) const {{')
        saves_adapters.append(f'    AnySaveAdapter<{baseclass}, U>()(static_cast<const {baseclass}*>(obj), serializer, builder);')

        restore_adapters.append(f'template<typename U>')
        restore_adapters.append(f'struct Serializer::AnyRestoreAdapter<{classname}, U> {{')
        restore_adapters.append(f'  void operator()(U reader, Serializer *const serializer, {classname} *const obj) const {{')
        restore_adapters.append(f'    AnyRestoreAdapter<{baseclass}, U>()(reader, serializer, static_cast<{baseclass}*>(obj));')

        for key, value in model.allitems():
            if key == 'property':
                name = value.get('name')
                vpi = value.get('vpi')
                type = value.get('type')
                card = value.get('card')

                if name == 'type':
                    continue

                Vpi_ = vpi[:1].upper() + vpi[1:]
                Vpi = Vpi_.replace('_', '')

                if type in ['string', 'value', 'delay']:
                    saves_adapters.append(f'    builder.set{Vpi}(serializer->symbolMaker.Make(obj->{Vpi_}()));')
                    restore_adapters.append(f'    obj->{Vpi_}(serializer->symbolMaker.GetSymbol(reader.get{Vpi}()));')
                else:
                    saves_adapters.append(f'    builder.set{Vpi}(obj->{Vpi_}());')
                    restore_adapters.append(f'    obj->{Vpi_}(reader.get{Vpi}());')
            
            elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']:
                name = value.get('name')
                type = value.get('type')
                card = value.get('card')
                id = value.get('id')

                Type_ = type[:1].upper() + type[1:]
                Type = Type_.replace('_', '')

                if (card == 'any') and not name.endswith('s'):
                    name += 's'

                Name_ = name[:1].upper() + name[1:]
                Name = Name_.replace('_', '')

                real_type = type
                if key == 'group_ref':
                    type = 'any'

                if card == '1':
                    if key in ['class_ref', 'group_ref']:
                        saves_adapters.append(f'    if (obj->{Name_}() != nullptr) {{')
                        saves_adapters.append(f'      ::ObjIndexType::Builder tmp = builder.get{Name}();')
                        saves_adapters.append(f'      tmp.setIndex(serializer->GetId(obj->{Name_}()));')
                        saves_adapters.append(f'      tmp.setType((obj->{Name_}())->UhdmType());')
                        saves_adapters.append( '    }')

                        restore_adapters.append(f'    obj->{Name_}(({type}*)serializer->GetObject(reader.get{Name}().getType(), reader.get{Name}().getIndex() - 1));')
                    else:
                        saves_adapters.append(f'    builder.set{Name}(serializer->GetId(obj->{Name_}()));')

                        restore_adapters.append(f'    if (reader.get{Name}()) {{')
                        restore_adapters.append(f'      obj->{Name_}(serializer->{type}Maker.objects_[reader.get{Name}() - 1]);')
                        restore_adapters.append( '    }')

                else:
                    obj_key = '::ObjIndexType' if key in ['class_ref', 'group_ref'] else '::uint64_t'

                    saves_adapters.append(f'    if (obj->{Name_}() != nullptr) {{')
                    saves_adapters.append(f'      ::capnp::List<{obj_key}>::Builder {Name}s = builder.init{Name}(obj->{Name_}()->size());')
                    saves_adapters.append(f'      for (unsigned int i = 0, n = obj->{Name_}()->size(); i < n; ++i) {{')

                    restore_adapters.append(f'    if (reader.get{Name}().size() > 0) {{')
                    restore_adapters.append(f'      std::vector<{type}*>* vect = serializer->{type}VectMaker.Make();')
                    restore_adapters.append(f'      for (unsigned int i = 0, n = reader.get{Name}().size(); i < n; ++i) {{')

                    if key in ['class_ref', 'group_ref']:
                        saves_adapters.append(f'        ::ObjIndexType::Builder tmp = {Name}s[i];')
                        saves_adapters.append(f'        tmp.setIndex(serializer->GetId((*obj->{Name_}())[i]));')
                        saves_adapters.append(f'        tmp.setType(((BaseClass*)((*obj->{Name_}())[i]))->UhdmType());')

                        restore_adapters.append(f'        vect->push_back(({type}*)serializer->GetObject(reader.get{Name}()[i].getType(), reader.get{Name}()[i].getIndex() - 1));')
                    else:
                        saves_adapters.append(f'        {Name}s.set(i, serializer->GetId((*obj->{Name_}())[i]));')

                        restore_adapters.append(f'        vect->push_back(serializer->{type}Maker.objects_[reader.get{Name}()[i] - 1]);')

                    saves_adapters.append('      }')
                    saves_adapters.append('    }')

                    restore_adapters.append( '      }')
                    restore_adapters.append(f'      obj->{Name_}(vect);')
                    restore_adapters.append( '    }')

        saves_adapters.append('  }')
        saves_adapters.append('};')
        saves_adapters.append('')

        restore_adapters.append('  }')
        restore_adapters.append('};')
        restore_adapters.append('')

    uhdm_name_map = [
        'std::string UhdmName(UHDM_OBJECT_TYPE type) {',
        '  switch (type) {'
    ]
    uhdm_name_map.extend([ f'  case {name} /* = {id} */: return "{name[4:]}";' for name, id in uhdm_types_h.get_type_map(models).items() ])
    uhdm_name_map.append('  default: return "NO TYPE";')
    uhdm_name_map.append('}')
    uhdm_name_map.append('}')

    # Serializer.h
    with open(config.get_template_filepath('Serializer.h'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<FACTORIES>', '\n'.join(factory_declarations))
    file_content = file_content.replace('<FACTORIES_METHODS>', '\n'.join(factory_methods))
    file_utils.set_content_if_changed(config.get_output_header_filepath('Serializer.h'), file_content)

    # Serializer.cpp
    with open(config.get_template_filepath('Serializer.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<METHODS_CPP>', '') # Deprecated
    file_content = file_content.replace('<UHDM_NAME_MAP>', '\n'.join(uhdm_name_map))
    file_content = file_content.replace('<FACTORY_PURGE>', '\n'.join(factory_purge))
    file_content = file_content.replace('<FACTORY_STATS>', '\n'.join(factory_stats))
    file_content = file_content.replace('<FACTORY_OBJECT_TYPE_MAP>', '\n'.join(factory_object_type_map))
    file_utils.set_content_if_changed(config.get_output_source_filepath('Serializer.cpp'), file_content)

    # Serializer_save.cpp
    with open(config.get_template_filepath('Serializer_save.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<CAPNP_ID>', '\n'.join(save_ids))
    file_content = file_content.replace('<CAPNP_SAVE>', '\n'.join(save_objects))
    file_content = file_content.replace('<CAPNP_SAVE_ADAPTERS>', '\n'.join(saves_adapters))
    file_utils.set_content_if_changed(config.get_output_source_filepath('Serializer_save.cpp'), file_content)

    # Serializer_restore.cpp
    with open(config.get_template_filepath('Serializer_restore.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<CAPNP_INIT_FACTORIES>', '\n'.join(restore_ids))
    file_content = file_content.replace('<CAPNP_RESTORE_FACTORIES>', '\n'.join(restore_objects))
    file_content = file_content.replace('<CAPNP_RESTORE_ADAPTERS>', '\n'.join(restore_adapters))
    file_utils.set_content_if_changed(config.get_output_source_filepath('Serializer_restore.cpp'), file_content)

    return True
Example #11
0
def _main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-output-dirpath',
                        dest='output_dirpath',
                        type=str,
                        help='Output path')
    parser.add_argument('--parallel',
                        dest='parallel',
                        action='store_true',
                        default=True)
    parser.add_argument('--source-dirpath',
                        dest='source_dirpath',
                        type=str,
                        help='Path to UHDM source')
    args = parser.parse_args()
    config.configure(args)

    print('Generating UHDM models ...')
    print('   Loading models ...')
    models = loader.load_models()
    print(f'   ... found {len(models)} models.')

    print('   Validating ordering ...')
    # Check validity
    index = 0
    order = {}
    for name in models.keys():
        order[name] = index
        index += 1

    for name, model in models.items():
        baseclass = model['extends']
        if baseclass:
            thisIndex = order[name]
            baseIndex = order[baseclass]
            if baseIndex >= thisIndex:
                raise Exception(
                    f'Model {name} should follow {baseclass} in listing.')
    print('   ... all good.')

    params = [
        ('capnp', [models]),
        ('class_hierarchy', [models]),
        ('classes', [models]),
        ('clone_tree_cpp', [models]),
        ('containers_h', [models]),
        ('ElaboratorListener_cpp', [models]),
        ('Copier', [{
            config.get_template_filepath('BaseClass.h'):
            config.get_output_header_filepath('BaseClass.h'),
            config.get_template_filepath('clone_tree.h'):
            config.get_output_header_filepath('clone_tree.h'),
            config.get_template_filepath('ElaboratorListener.h'):
            config.get_output_header_filepath('ElaboratorListener.h'),
            config.get_template_filepath('ExprEval.h'):
            config.get_output_header_filepath('ExprEval.h'),
            config.get_template_filepath('ExprEval.cpp'):
            config.get_output_source_filepath('ExprEval.cpp'),
            config.get_template_filepath('RTTI.h'):
            config.get_output_header_filepath('RTTI.h'),
            config.get_template_filepath('SymbolFactory.h'):
            config.get_output_header_filepath('SymbolFactory.h'),
            config.get_template_filepath('SymbolFactory.cpp'):
            config.get_output_source_filepath('SymbolFactory.cpp'),
            config.get_template_filepath('uhdm_vpi_user.h'):
            config.get_output_header_filepath('uhdm_vpi_user.h'),
            config.get_template_filepath('vpi_uhdm.h'):
            config.get_output_header_filepath('vpi_uhdm.h'),
            config.get_template_filepath('vpi_visitor.h'):
            config.get_output_header_filepath('vpi_visitor.h'),
            config.get_include_filepath('sv_vpi_user.h'):
            config.get_output_header_filepath('sv_vpi_user.h'),
            config.get_include_filepath('vhpi_user.h'):
            config.get_output_header_filepath('vhpi_user.h'),
            config.get_include_filepath('vpi_user.h'):
            config.get_output_header_filepath('vpi_user.h'),
        }]),
        ('serializer', [models]),
        ('uhdm_forward_decl_h', [models]),
        ('uhdm_h', [models]),
        ('uhdm_types_h', [models]),
        ('vpi_listener', [models]),
        ('vpi_user_cpp', [models]),
        ('vpi_visitor_cpp', [models]),
        ('VpiListener_h', [models]),
        ('VpiListenerTracer_h', [models]),
    ]

    if args.parallel:
        with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor:
            results = list(executor.map(_worker, params))
    else:
        results = [_worker(args) for args in params]
    print('... all done!')

    result = sum([0 if r else 1 for r in results])
    if result:
        print('ERROR: UHDM model generation FAILED!')
    else:
        print('UHDM Models generated successfully!.')

    return result
Example #12
0
def generate(models):
    visit_object_body = []
    private_visitor_bodies = []

    ignored_objects = set(['vpiNet'])

    for model in models.values():
        modeltype = model['type']
        if modeltype == 'group_def':
            continue

        classname = model['name']
        if classname in ['net_drivers', 'net_loads']:
            continue

        vpi_name = config.make_vpi_name(classname)
        if vpi_name not in ignored_objects:
            visit_object_body.append(
                f'    case {vpi_name}: visit_{classname}(obj_h, indent, relation, visited, out, shallowVisit); break;'
            )

        private_visitor_bodies.append(
            f'static void visit_{classname}(vpiHandle obj_h, int indent, const char *relation, VisitedContainer* visited, std::ostream& out, bool shallowVisit) {{'
        )

        baseclass = model.get('extends', None)
        if baseclass:
            private_visitor_bodies.append(
                f'  visit_{baseclass}(obj_h, indent, relation, visited, out, shallowVisit);'
            )

        itr_required = False
        private_visitor_body = []

        if classname == 'part_select':
            private_visitor_body.extend(
                _get_implementation(classname, 'vpiParent', '1'))
            itr_required = True

        if modeltype != 'class_def':
            private_visitor_body.extend(
                _get_vpi_xxx_visitor('string', 'vpiFile', '1'))

        type_specified = False
        for key, value in model.allitems():
            if key == 'property':
                name = value.get('name')
                vpi = value.get('vpi')
                type = value.get('type')
                card = value.get('card')

                type_specified = name == 'type' or type_specified
                private_visitor_body.extend(
                    _get_vpi_xxx_visitor(type, vpi, card))

            elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']:
                vpi = value.get('vpi')
                card = value.get('card')

                private_visitor_body.extend(
                    _get_implementation(classname, vpi, card))
                itr_required = True

        if not type_specified and (modeltype == 'obj_def'):
            private_visitor_body.extend(
                _get_vpi_xxx_visitor('unsigned int', 'vpiType', '1'))

        if private_visitor_body:
            if itr_required:
                private_visitor_bodies.append(f'  vpiHandle itr;')
            private_visitor_bodies.extend(private_visitor_body)

        private_visitor_bodies.append(f'}}')
        private_visitor_bodies.append('')

    visitors = [f'  switch (objectType) {{'
                ] + sorted(visit_object_body) + [f'  }}']

    # vpi_visitor.cpp
    with open(config.get_template_filepath('vpi_visitor.cpp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<OBJECT_VISITORS>',
                                        '\n'.join(visitors))
    file_content = file_content.replace('<PRIVATE_OBJECT_VISITORS>',
                                        '\n'.join(private_visitor_bodies))
    file_utils.set_content_if_changed(
        config.get_output_source_filepath('vpi_visitor.cpp'), file_content)

    return True
Example #13
0
def generate(models):
    individual_model_schemas = {}
    flattened_model_schemas = []
    root_schema_index = 2
    root_schema = []

    for model in models.values():
        modeltype = model['type']
        if modeltype == 'group_def':
            continue

        classname = model['name']
        individual_model_schemas[classname] = []

        Classname_ = classname[:1].upper() + classname[1:]
        Classname = Classname_.replace('_', '')

        if modeltype != 'class_def':
            individual_model_schemas[classname].append(('uhdmId', 'UInt64'))
            individual_model_schemas[classname].append(('vpiParent', 'UInt64'))
            individual_model_schemas[classname].append(('uhdmParentType', 'UInt64'))
            individual_model_schemas[classname].append(('vpiFile', 'UInt64'))
            individual_model_schemas[classname].append(('vpiLineNo', 'UInt32'))
            individual_model_schemas[classname].append(('vpiEndLineNo', 'UInt32'))
            individual_model_schemas[classname].append(('vpiColumnNo', 'UInt16'))
            individual_model_schemas[classname].append(('vpiEndColumnNo', 'UInt16'))

            root_schema.append(f'  factory{Classname} @{root_schema_index} :List({Classname});')
            root_schema_index += 1

        for key, value in model.allitems():
            if key == 'property':
                if value.get('name') != 'type':
                    vpi = value.get('vpi')
                    type = value.get('type')
                    card = value.get('card')
                    individual_model_schemas[classname].append(_get_schema(type, vpi, card))

            elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']:
                name = value.get('name')
                type = value.get('type')
                card = value.get('card')

                if (card == 'any') and not name.endswith('s'):
                    name += 's'

                name = name.replace('_', '')

                obj_key = 'ObjIndexType' if key in ['class_ref', 'group_ref'] else 'UInt64'
                individual_model_schemas[classname].append(_get_schema(obj_key, name, card))

        if modeltype != 'class_def':
            # Process the hierarchy tree top-down
            stack = []
            baseclass = classname
            while (baseclass):
                stack.append(baseclass)
                baseclass = models[baseclass]['extends']

            capnpIndex = 0
            flattened_model_schemas.append(f'struct {Classname} {{')

            while stack:
                for name, type in individual_model_schemas[stack.pop()]:
                    if name and type:
                        flattened_model_schemas.append(f'  {name} @{capnpIndex} :{type};')
                        capnpIndex += 1

            flattened_model_schemas.append('}')
            flattened_model_schemas.append('')

    with open(config.get_template_filepath('UHDM.capnp'), 'r+t') as strm:
        file_content = strm.read()

    file_content = file_content.replace('<CAPNP_SCHEMA>', '\n'.join(flattened_model_schemas))
    file_content = file_content.replace('<CAPNP_ROOT_SCHEMA>', '\n'.join(root_schema))
    file_utils.set_content_if_changed(config.get_output_source_filepath('UHDM.capnp'), file_content)

    return True