示例#1
0
def generate_py_for_enum(enum_obj, output_file):
    mm = get_metamodel(enum_obj)
    if obj_is_newer_than_file(enum_obj, output_file):
        with open(output_file, "w") as f:
            f.write(f"""# generated code
# for enum f{enum_obj.name}
import numpy as np
from enum import Enum
""")
            for r in get_referenced_elements_of_enum(enum_obj):
                f.write("import {}\n".format(module_name(r)))
            f.write("\n")
            f.write("meta = {\n")
            for ev in enum_obj.enum_entries:
                pdefs = get_all_possible_properties(ev)
                pdefs = sorted(pdefs.keys())
                f.write(f"    '{ev.name}':{{")
                output_properties(f, ev, pdefs)
                f.write("},\n")
            f.write("}\n")
            f.write(f"class {enum_obj.name}(Enum):\n")
            t = fqn(enum_obj.type)
            for ev in enum_obj.enum_entries:
                v = ev.value.render_formula(**fp(enum_obj))
                f.write(f"    {ev.name} = {t}({v})\n")
            f.write("    def __repr__(self):\n")
            f.write("        return self.name\n")
            f.write("    def __str__(self):\n")
            f.write("        return self.name\n")
示例#2
0
def test_property2():
    text = r"""
    package example.one (property_set example.one.ProjExt)
    property_set ProjExt {
        property optional myprop1: STRING
        property applicable for rawtype, enum myprop2: ATTRTYPE
    }
    struct A {
        scalar x: built_in.int32 (.description="a", .myprop2=1)
    }
    """
    mm = metamodel_for_language("item")
    assert mm is not None
    model = mm.model_from_str(text)
    assert model is not None
    items = get_children_of_type("Struct", model)
    assert len(items) == 1

    pdefs = get_all_possible_properties(items[0].attributes[0])
    assert len(pdefs) >= 7

    assert "minValue" in pdefs
    assert "maxValue" in pdefs
    assert "defaultValue" in pdefs
    assert "description" in pdefs
    assert "myprop1" in pdefs
    assert "myprop2" in pdefs
    pdefs["myprop1"].internaltype == "STRING"
    pdefs["myprop2"].internaltype == "ATTRTYPE"

    pdefs = get_all_possible_mandatory_properties(items[0].attributes[0])
    assert len(pdefs) == 1
    assert "myprop2" in pdefs
示例#3
0
def test_property1():
    text = r"""
    package example

    struct Point {
      scalar x : built_in.float (.minValue=0.1, .defaultValue=1, .maxValue=1e5)
      scalar y : built_in.float (.defaultValue=0x0aB, .description="Hello")
    }
    struct Polygon {
      scalar n : built_in.uint32 (.defaultValue=16, .maxValue=1000)
      array points : Point[n]
    }
    """
    mm = metamodel_for_language("item")
    assert mm is not None
    model = mm.model_from_str(text)
    assert model is not None
    items = get_children_of_type("Struct", model)
    assert len(items) == 2

    Point = items[0]
    assert Point.name == "Point"
    assert len(Point.attributes[0].properties) == 3
    assert len(Point.attributes[1].properties) == 2
    assert Point.attributes[1].properties[0].definition.name == "defaultValue"
    assert Point.attributes[1].properties[0].numberValue.x.compute_formula(
    ) == 0xAB
    assert Point.attributes[1].properties[1].textValue.x == "Hello"

    assert get_property(Point.attributes[1], "defaultValue") == 0xAB
    assert get_property(Point.attributes[1], "description") == "Hello"

    assert has_property(Point.attributes[1], "defaultValue")
    assert has_property(Point.attributes[1], "description")
    assert not has_property(Point.attributes[1], "minValue")
    assert not has_property(Point.attributes[1], "maxValue")

    pdefs = get_all_possible_properties(
        Point, filter_applicable_to_model_object=False)
    assert len(pdefs) >= 6
示例#4
0
文件: struct.py 项目: goto40/mdsd
def generate_cpp_struct(f, i):
    """
    :param f: output file obj
    :param i: item to be generated (the struct)
    """
    mm = textx.get_metamodel(i)
    f.write("//---------------------------\n")
    f.write("#ifdef SWIG\n")
    f.write("%shared_ptr({});\n".format(fqn(i)))
    f.write(
        "%template(MDSD_StructFunctions_{}) mdsd::StructFunctions<{}>;\n".format(
            i.name, fqn(i)
        )
    )
    f.write("%template(MDSD_Struct_{}) mdsd::Struct<{}>;\n".format(i.name, fqn(i)))
    f.write(
        "%template(MDSD_StructWrapper_{}) mdsd::StructWrapper<{}>;\n".format(
            i.name, fqn(i)
        )
    )
    for a in i.attributes:
        if textx.textx_isinstance(a, mm["ArrayAttribute"]):
            if a.has_fixed_size():
                f.write(define_swig_array(a.type, a.compute_formula(), mm))
            else:
                f.write(define_swig_vector(a.type, mm))
    f.write("#endif\n")
    f.write("//---------------------------\n")
    f.write(get_open_namespace_for_obj(i))
    f.write("struct {} {{\n".format(i.name))

    for c in i.constant_entries:
        f.write(
            "  static constexpr {} {} = {};\n".format(
                fqn(c.type), c.name, c.value.render_formula()
            )
        )

    for a in i.attributes:
        if a.is_embedded():
            value_type = get_cpp_return_type(a.type)
            if textx.textx_isinstance(a, mm["ScalarAttribute"]):
                f.write("  inline {} {}() const;\n".format(value_type, a.name))
            else:
                f.write(
                    "  inline {} {}(size_t idx) const;\n".format(value_type, a.name)
                )

            if textx.textx_isinstance(a, mm["ScalarAttribute"]):
                f.write("  inline void {}({} val);\n".format(a.name, value_type))
            else:
                f.write(
                    "  inline void {}(size_t idx, {} val);\n".format(a.name, value_type)
                )
            continue

        if textx.textx_isinstance(a, mm["ScalarAttribute"]):
            f.write("  {} {} = {{}};\n".format(fqn(a.type), a.name))
        elif textx.textx_isinstance(a, mm["ArrayAttribute"]):
            if a.has_fixed_size():
                f.write(
                    "  std::array<{},{}> {} = {{}};\n".format(
                        fqn(a.type), a.compute_formula(), a.name
                    )
                )
            else:
                f.write("  std::vector<{}> {} = {{}};\n".format(fqn(a.type), a.name))
        elif textx.textx_isinstance(a, mm["VariantAttribute"]):
            f.write(
                "  std::variant<{}> {} = {{}};\n".format(get_variant_types(a), a.name)
            )
        else:
            raise Exception("unexpected type")
    f.write(
        "  mdsd::StructWrapper<{0}> _GET_WRAPPER() {{ return mdsd::StructWrapper<{0}>{{this}}; }}\n".format(
            i.name
        )
    )
    f.write("\n#ifndef SWIG\n")
    f.write("  struct META {\n")

    # ----------------------------------------
    f.write(
        "    template<class STRUCT,class VISITOR, class ...T> // enable accept for this struct: \n"
    )
    f.write("    static void __accept_varargs(VISITOR &&v, T&... s) {\n")
    for a in i.attributes:
        f.write("      v.template visit<{}::META::{}>(s...);\n".format(i.name, a.name))
    f.write("    }\n")
    # ----------------------------------------

    f.write("    static constexpr const char* __name() ")
    f.write('{{ return "{}"; }}\n'.format(i.name))
    f.write(f"    static constexpr bool __is_dynamic = {tf(is_dynamic(i))};\n")

    f.write("    // META substructs:\n")
    for a in i.attributes:
        if a.is_variant():
            for m in a.mappings:
                pdefs = get_all_possible_properties(m)
                pdefs = sorted(pdefs.keys())
                f.write("    struct {} {{\n".format(meta_name_of_variant_mapping(m)))
                f.write("      using STRUCT={};\n".format(i.name))
                f.write("      static constexpr const char* __name() ")
                f.write('{{ return "{}"; }}\n'.format(a.name))
                f.write("      static constexpr bool __is_variant_entry = true;\n")
                f.write("      static constexpr bool __is_scalar = true;\n")
                f.write("      static constexpr bool __is_variant = false;\n")
                f.write("      static constexpr bool __is_array = false;\n")
                f.write("      static constexpr bool __is_enumtype = false;\n")
                f.write("      static constexpr bool __is_rawtype = false;\n")
                f.write("      static constexpr bool __is_struct = true;\n")
                f.write("      static constexpr bool __is_container = false;\n")
                insert_normal_meta_info(f, pdefs, m)
                f.write("    };\n")

    for a in i.attributes:
        f.write("    struct {} {{\n".format(a.name))
        f.write("      using STRUCT={};\n".format(i.name))
        f.write("      static constexpr const char* __name() ")
        f.write('{{ return "{}"; }}\n'.format(a.name))
        f.write("      static constexpr bool __is_variant_entry = false;\n")
        if not textx.textx_isinstance(a, mm["VariantAttribute"]):
            f.write(f"      using __type = {fqn(a.type)};")
        f.write(f"      static constexpr bool __is_dynamic = {tf(is_dynamic(a))};\n")

        if hasattr(a, "type") and a.type.name == "char":
            f.write("      static constexpr bool __has_char_content = true;\n")
        else:
            f.write("      static constexpr bool __has_char_content = false;\n")

        if a.if_attr is None:
            f.write("      static constexpr bool __has_if_restriction = false;\n")
            f.write(
                "      static constexpr bool __if_restriction(const STRUCT &) { return true; }\n\n"
            )
        else:
            f.write("      static constexpr bool __has_if_restriction = true;\n")
            f.write(
                "      static constexpr bool __if_restriction(const STRUCT &s) {{ return {}; }}\n\n".format(
                    a.if_attr.predicate.render_formula(prefix="s.")
                )
            )

        if not (a.is_embedded()):
            if (
                textx.textx_isinstance(a, mm["ArrayAttribute"])
                and a.type.name == "char"
            ):
                f.write(
                    "      static constexpr auto __get_ref(STRUCT &s) {{ return mdsd::String(s.{}); }}\n".format(
                        a.name
                    )
                )
                f.write(
                    "      static constexpr const auto __get_ref(const STRUCT &s)"
                    " {{ return mdsd::String(s.{}); }}\n".format(a.name)
                )
            else:
                f.write(
                    "      static constexpr auto& __get_ref(STRUCT &s) {{ return s.{}; }}\n".format(
                        a.name
                    )
                )
                f.write(
                    "      static constexpr const auto& __get_ref(const STRUCT &s) {{ return s.{}; }}\n".format(
                        a.name
                    )
                )
        else:
            f.write(
                "      static constexpr auto& __get_ref_of_container(STRUCT &s) {{ return s.{}; }}\n".format(
                    get_container(a).name
                )
            )
            f.write(
                "      static constexpr const auto& __get_ref_of_container(const STRUCT &s)"
                " {{ return s.{}; }}\n".format(get_container(a).name)
            )
            if textx.textx_isinstance(a, mm["ArrayAttribute"]):
                f.write(
                    "      static constexpr auto __get_ref(STRUCT &s) {{ return mdsd::makeArrayRef<{}>(\n".format(
                        fqn(a.type)
                    )
                )
                f.write(
                    "          [&s](size_t idx){{ return s.{}(idx); }},\n".format(
                        a.name
                    )
                )
                f.write(
                    "          [&s](size_t idx, {} x){{ return s.{}(idx, x); }},\n".format(
                        fqn(a.type), a.name
                    )
                )
                f.write("          {}\n".format(a.compute_formula()))
                f.write("      ); }\n")
                f.write(
                    "      static constexpr auto __get_ref(const STRUCT &s)"
                    " {{ return mdsd::makeCArrayRef<{}>(\n".format(fqn(a.type))
                )
                f.write(
                    "          [&s](size_t idx){{ return s.{}(idx); }},\n".format(
                        a.name
                    )
                )
                f.write("          {}\n".format(a.compute_formula()))
                f.write("      ); }\n")
            else:
                f.write(
                    "      static constexpr auto __get_ref(STRUCT &s) {{ return mdsd::makeRef<{}>(\n".format(
                        fqn(a.type)
                    )
                )
                f.write("          [&s](){{ return s.{}(); }},\n".format(a.name))
                f.write(
                    "          [&s]({} x){{ return s.{}(x); }}\n".format(
                        fqn(a.type), a.name
                    )
                )
                f.write("      ); }\n")
                f.write(
                    "      static constexpr auto __get_ref(const STRUCT &s) {{ return mdsd::makeCRef<{}>(\n".format(
                        fqn(a.type)
                    )
                )
                f.write("          [&s](){{ return s.{}(); }}\n".format(a.name))
                f.write("      ); }\n")

        pdefs = get_all_possible_properties(a)
        pdefs = sorted(pdefs.keys())

        if "fixpointLsbValue" in pdefs:
            if has_fixpoint(a):
                f.write("      static constexpr bool __is_fixpoint = true;\n")
                f.write(
                    f"      static constexpr double __fixpointLsbValue = {get_fixpoint_LSB_value(a)};\n"
                )
                f.write(
                    f"      static constexpr double __fixpointOffsetValue = {get_fixpoint_offset_value(a)};\n"
                )
                f.write(
                    f"      template<class FLOAT=double> static constexpr {fqn(a.type)} __float2integral(FLOAT f) "
                    f"{{ return static_cast<{fqn(a.type)}>(std::llround((f-__fixpointOffsetValue)"
                    f"/__fixpointLsbValue)); }}\n"
                )
                f.write(
                    f"      template<class FLOAT=double> static constexpr FLOAT __integral2float({fqn(a.type)} i) "
                    f"{{ return static_cast<FLOAT>(i)*__fixpointLsbValue+__fixpointOffsetValue; }}\n"
                )
            else:
                f.write("      static constexpr bool __is_fixpoint = false;\n")
        else:
            f.write("      static constexpr bool __is_fixpoint = false;\n")

        insert_normal_meta_info(f, pdefs, a)

        if textx.textx_isinstance(a, mm["VariantAttribute"]):
            f.write(
                "      template<class S, class F> // S may also be const\n"
            )
            f.write(
                "      static void __call_function_on_concrete_variant_type(S &s, F f) {\n"
            )

            f.write(
                "        switch(s.{}) {{\n".format(a.variant_selector.render_formula())
            )
            for m in a.mappings:
                f.write("          case {}: ".format(m.id))
                assert not textx.textx_isinstance(m.type, mm["RawType"])
                f.write(
                    "f.template operator()<STRUCT::META::{}>(std::get<{}>(s.{})); break;\n".format(
                        meta_name_of_variant_mapping(m), fqn(m.type), a.name
                    )
                )
            f.write('          default: throw std::runtime_error("(unexpected id)");\n')
            f.write("        }\n")

            f.write("      }\n")

            f.write("      template<class S> // S may also be const\n")
            f.write(
                "      static void __init_variant_type_if_type_is_not_matching(S &s) {\n"
            )

            f.write(
                "        switch(s.{}) {{\n".format(a.variant_selector.render_formula())
            )
            for m in a.mappings:
                f.write("          case {}: ".format(m.id))
                f.write(
                    "if (not std::holds_alternative<{}>(s.{})) {{ s.{}={}{{}}; }} break;\n".format(
                        fqn(m.type),
                        a.name,
                        a.name,
                        fqn(m.type),
                    )
                )
            f.write('          default: throw std::runtime_error("unexpected id");\n')
            f.write("        }\n")

            f.write("      }\n")
            f.write("      static constexpr bool __is_scalar = true;\n")
            f.write("      static constexpr bool __is_variant = true;\n")
            f.write("      static constexpr bool __is_array = false;\n")
            f.write("      static constexpr bool __is_enumtype = false;\n")
            f.write("      static constexpr bool __is_rawtype = false;\n")
            f.write("      static constexpr bool __is_struct = true;\n")
            f.write(
                "      static constexpr bool __is_container = {};\n".format(
                    tf(a.is_container())
                )
            )
            f.write(
                "      static constexpr bool __is_embedded = {};\n".format(
                    tf(a.is_embedded())
                )
            )
        elif textx.textx_isinstance(a, mm["ScalarAttribute"]):
            f.write("      static constexpr bool __is_scalar = true;\n")
            f.write("      static constexpr bool __is_variant = false;\n")
            f.write("      static constexpr bool __is_array = false;\n")
            if textx.textx_isinstance(a.type, mm["Enum"]):
                f.write("      static constexpr bool __is_enumtype = true;\n")
            else:
                f.write("      static constexpr bool __is_enumtype = false;\n")
            if textx.textx_isinstance(a.type, mm["RawType"]):
                f.write("      static constexpr bool __is_rawtype = true;\n")
            else:
                f.write("      static constexpr bool __is_rawtype = false;\n")
            if textx.textx_isinstance(a.type, mm["Struct"]):
                f.write("      static constexpr bool __is_struct = true;\n")
            else:
                f.write("      static constexpr bool __is_struct = false;\n")
            f.write(
                "      static constexpr bool __is_container = {};\n".format(
                    tf(a.is_container())
                )
            )
            f.write(
                "      static constexpr bool __is_embedded = {};\n".format(
                    tf(a.is_embedded())
                )
            )
            if a.is_embedded():
                start_end_bit = get_start_end_bit(a)
                f.write(
                    "      static constexpr size_t __embedded_bits = {};\n".format(
                        get_bits(a.type)
                    )
                )
                f.write(
                    "      static constexpr size_t __embedded_start_bit = {};\n".format(
                        start_end_bit[0]
                    )
                )
                f.write(
                    "      static constexpr size_t __embedded_end_bit = {};\n".format(
                        start_end_bit[1]
                    )
                )
        elif textx.textx_isinstance(a, mm["ArrayAttribute"]):
            f.write("      static constexpr bool __is_scalar = false;\n")
            f.write("      static constexpr bool __is_variant = false;\n")
            f.write("      static constexpr bool __is_array = true;\n")
            if a.has_fixed_size():
                f.write("      static constexpr bool __is_dynamic_array = false;\n")
            else:
                f.write("      static constexpr bool __is_dynamic_array = true;\n")
            f.write(
                "      static constexpr size_t __get_dim([[maybe_unused]] const {} &{}) {{ return {};}}\n".format(
                    i.name,
                    "s" if not a.has_fixed_size() else "",
                    a.render_formula(prefix="s."),
                )
            )
            txt = f"      static constexpr size_t __get_dim([[maybe_unused]] const {i.name}"
            txt += f"&{'s' if not a.has_fixed_size() else ''}, size_t _idx) {{\n"
            txt += "            switch(_idx) {\n"
            for idx in range(len(a.dims)):
                txt += f"                  case {idx}: return {a.dims[idx].dim.render_formula(prefix='s.')};\n"
            txt += '                 default: throw std::runtime_error("unexpected dimension");\n'
            txt += "            }\n"
            txt += "      }\n"
            f.write(txt)
            if textx.textx_isinstance(a.type, mm["Enum"]):
                f.write("      static constexpr bool __is_enumtype = true;\n")
            else:
                f.write("      static constexpr bool __is_enumtype = false;\n")
            if textx.textx_isinstance(a.type, mm["RawType"]):
                f.write("      static constexpr bool __is_rawtype = true;\n")
            else:
                f.write("      static constexpr bool __is_rawtype = false;\n")
            if textx.textx_isinstance(a.type, mm["Struct"]):
                f.write("      static constexpr bool __is_struct = true;\n")
            else:
                f.write("      static constexpr bool __is_struct = false;\n")
            f.write(
                "      static constexpr bool __is_container = {};\n".format(
                    tf(a.is_container())
                )
            )
            f.write(
                "      static constexpr bool __is_embedded = {};\n".format(
                    tf(a.is_embedded())
                )
            )
            if a.is_embedded():
                start_end_bit = get_start_end_bit(a)
                f.write(
                    "      static constexpr size_t __embedded_bits = {};\n".format(
                        get_bits(a.type)
                    )
                )
                f.write(
                    "      static constexpr size_t __embedded_start_bit = {};\n".format(
                        start_end_bit[0]
                    )
                )
                f.write(
                    "      static constexpr size_t __embedded_end_bit = {};\n".format(
                        start_end_bit[1]
                    )
                )
        else:
            raise Exception("unexpected type constellation")

        f.write("    }}; // meta struct {}\n".format(a.name))
    f.write("  }; //struct META\n\n")

    f.write("#endif // #ifndef SWIG\n\n")

    f.write(f"  {i.name}() {{\n")
    f.write("    mdsd::init_default_values(*this);\n")
    f.write("  }\n")

    if _extra_init_required(i):
        f.write(f"  {i.name}({_get_ctor_params(i)}) {{\n")
        f.write(f"    {_get_ctor_body(i)};\n")
        f.write("  }\n")

    f.write(
        "  static std::shared_ptr<{}> item_create() {{ return std::make_shared<{}>(); }}\n".format(
            i.name, i.name
        )
    )
    f.write("}}; //struct {}\n".format(i.name))

    for a in i.attributes:
        if a.is_embedded():
            value_type = get_cpp_return_type(a.type)
            signed_info = get_signed_or_unsigned(a.type)
            container_name = get_container(a).name

            if textx.textx_isinstance(a, mm["ScalarAttribute"]):
                f.write(
                    "  inline {} {}::{}() const {{\n".format(value_type, i.name, a.name)
                )
                f.write(
                    f"     return mdsd::read_{signed_info}_from_container<{value_type}>({container_name},"
                    f" META::{a.name}::__embedded_start_bit, META::{a.name}::__embedded_end_bit);\n"
                )
                f.write("  }\n")
            else:
                f.write(
                    "  inline {} {}::{}(size_t idx) const {{\n".format(
                        value_type, i.name, a.name
                    )
                )
                f.write(
                    f"     return mdsd::read_{signed_info}_from_container<{value_type}>({container_name},"
                    f" META::{a.name}::__embedded_start_bit-idx*META::{a.name}::__embedded_bits,"
                    f" META::{a.name}::__embedded_start_bit+1-(idx+1)*META::{a.name}::__embedded_bits);\n"
                )
                f.write("  }\n")

            if textx.textx_isinstance(a, mm["ScalarAttribute"]):
                f.write(
                    "  inline void {}::{}({} val) {{\n".format(
                        i.name, a.name, value_type
                    )
                )
                f.write(
                    f"     {container_name} = mdsd::write_to_container({container_name},"
                    f" META::{a.name}::__embedded_start_bit, META::{a.name}::__embedded_end_bit, val);\n"
                )
                f.write("  }\n")
            else:
                f.write(
                    "  inline void {}::{}(size_t idx, {} val) {{\n".format(
                        i.name, a.name, value_type
                    )
                )
                f.write(
                    f"     {container_name} = mdsd::write_to_container({container_name},"
                    f" META::{a.name}::__embedded_start_bit-idx*META::{a.name}::__embedded_bits,"
                    f" META::{a.name}::__embedded_start_bit+1-(idx+1)*META::{a.name}::__embedded_bits, val);\n"
                )
                f.write("  }\n")

    f.write("#ifndef SWIG\n")

    # ----------------------------------------
    f.write(
        "template<class VISITOR, class STRUCT> // enable accept for this struct: \n"
    )
    f.write(
        "std::enable_if_t<std::is_same_v<std::remove_const_t<STRUCT>,{}>> accept(VISITOR &&v, STRUCT &s) {{\n".format(
            i.name
        )
    )
    f.write("  STRUCT::META::template __accept_varargs<STRUCT>(v, s);\n")
    f.write("}\n")
    # ----------------------------------------

    f.write("#endif // #ifndef SWIG\n")

    f.write("} // close namespace\n")

    f.write("// swig helper:\n")
    for a in i.attributes:
        if textx.textx_isinstance(a, mm["VariantAttribute"]):
            f.write(define_swig_variant_access(i, a))
示例#5
0
文件: struct.py 项目: goto40/mdsd
def generate_py_for_struct(struct_obj, output_file):
    mm = get_metamodel(struct_obj)
    if obj_is_newer_than_file(struct_obj, output_file):
        with open(output_file, "w") as f:
            f.write("""# generated code
from dataclasses import dataclass, field
import numpy as np
import mdsd.item_support as support
from mdsd.item.init_values import init_default_values
from mdsd.common import get_embedded_from_uint, ArrayLike
from mdsd.common import set_embedded_in_uint
from mdsd.common import ArrayLike, str2array, array2str
from mdsd.common import int2float_fixpoint_value, float2int_fixpoint_value, FixpointArrayLike
from typing import Sequence, Union
from functools import reduce
""")
            for r in get_referenced_elements_of_struct(struct_obj):
                f.write("import {}\n".format(module_name(r)))
            f.write("\n")
            i = struct_obj

            for c in i.constant_entries:
                f.write(
                    f"{c.name} = {fqn(c.type)}({c.value.render_formula(**fp(i))})\n"
                )

            f.write("\n@dataclass(eq=False)\n")
            f.write("class {}:\n".format(i.name))
            for a in i.attributes:

                if a.is_embedded():
                    rawtype = a.type
                    if textx_isinstance(a.type, mm["Enum"]):
                        rawtype = a.type.type
                    if textx_isinstance(a, mm["ScalarAttribute"]):
                        # SCALAR EMBEDDED
                        # --------------------------------------------------------------
                        start_end_bit = get_start_end_bit(a)
                        c = get_container(a)
                        f.write(f"    @property\n")
                        f.write(f"    def {a.name}(self):\n")
                        f.write(
                            f"        ret = get_embedded_from_uint({fqn(rawtype)}, self.{c.name},[{start_end_bit[0]},{start_end_bit[1]}])\n"
                        )
                        if textx_isinstance(a.type, mm["Enum"]):
                            f.write(f"        ret = {fqn(a.type)}(ret)\n")
                        f.write(f"        return ret\n")
                        f.write(f"\n")
                        f.write(f"    @{a.name}.setter\n")
                        f.write(f"    def {a.name}(self, v):\n")
                        if textx_isinstance(a.type, mm["Enum"]):
                            f.write(f"        v = v.value\n")
                        f.write(
                            f"        assert isinstance(v, {fqn(rawtype)})\n")
                        f.write(
                            f"        self.{c.name} = set_embedded_in_uint(v, self.{c.name},[{start_end_bit[0]},{start_end_bit[1]}])\n"
                        )
                        f.write(f"\n")
                        # --------------------------------------------------------------
                    elif textx_isinstance(a, mm["ArrayAttribute"]):
                        # ARRAY EMBEDDED
                        # --------------------------------------------------------------
                        start_end_bit = get_start_end_bit(a)
                        c = get_container(a)
                        f.write(f"    @property\n")
                        f.write(f"    def {a.name}(self):\n")
                        f.write(f"        def getter(idx):\n")
                        f.write(f"            assert idx >= 0\n")
                        f.write(
                            f"            assert idx < reduce(lambda a, b: a * b, {i.name}._meta['{a.name}']['_get_dim_nd'](self))\n"
                        )
                        f.write(
                            f"            ret = get_embedded_from_uint({fqn(rawtype)}, self.{c.name},[{start_end_bit[0]}-idx*{rawtype.bits},{start_end_bit[0]}+1-(idx+1)*{rawtype.bits}])\n"
                        )
                        if textx_isinstance(a.type, mm["Enum"]):
                            f.write(f"            ret = {fqn(a.type)}(ret)\n")
                        f.write(f"            return ret\n")
                        f.write(f"        def setter(idx, v):\n")
                        f.write(f"            assert idx >= 0\n")
                        f.write(
                            f"            assert idx < reduce(lambda a, b: a * b, {i.name}._meta['{a.name}']['_get_dim_nd'](self))\n"
                        )
                        f.write(
                            f"            assert isinstance(v, {fqn(a.type)})\n"
                        )
                        if textx_isinstance(a.type, mm["Enum"]):
                            f.write(f"            v = v.value\n")
                        f.write(
                            f"            self.{c.name} = set_embedded_in_uint(v, self.{c.name},[{start_end_bit[0]}-idx*{rawtype.bits},{start_end_bit[0]}+1-(idx+1)*{rawtype.bits}])\n"
                        )
                        f.write(
                            f"        return ArrayLike( getter=getter, setter=setter, mytype={fqn(a.type)}, shape={i.name}._meta['{a.name}']['_get_dim_nd'](self) )\n"
                        )
                        f.write(f"\n")
                        f.write(f"    @{a.name}.setter\n")
                        f.write(f"    def {a.name}(self, v):\n")
                        f.write(f"        self.{a.name}.copy_from(v)\n")
                        f.write(f"\n")
                        # --------------------------------------------------------------
                        pass
                    else:
                        raise Exception("unexpected type")
                else:  # not embedded
                    if textx_isinstance(a, mm["ScalarAttribute"]):
                        if textx_isinstance(a.type, mm["RawType"]):
                            f.write("    {} : {}={}()\n".format(
                                a.name, fqn(a.type), fqn(a.type)))
                        else:
                            if textx_isinstance(a.type, mm["Enum"]):
                                f.write("    {} : {} = {}.{}\n".format(
                                    a.name,
                                    fqn(a.type),
                                    fqn(a.type),
                                    a.type.enum_entries[0].name,
                                ))
                            else:
                                f.write(
                                    "    {} : {}= field( default_factory=lambda: {}() )\n"
                                    .format(a.name, fqn(a.type), fqn(a.type)))
                        if hasattr(a, "type") and a.type.name == "char":
                            f.write(f"    @property\n")
                            f.write(f"    def {a.name}_as_str(self):\n")
                            f.write(f"        return chr(self.{a.name})\n")
                            f.write(f"\n")
                            f.write(f"    @{a.name}_as_str.setter\n")
                            f.write(f"    def {a.name}_as_str(self, v):\n")
                            f.write(
                                f"        self.{a.name} = np.uint8(ord(v))\n")
                            f.write(f"\n")
                    elif textx_isinstance(a, mm["ArrayAttribute"]):
                        if textx_isinstance(a.type, mm["RawType"]):
                            f.write("    {} : np.ndarray=None\n".format(
                                a.name))
                        else:
                            f.write("    {} : Sequence[{}]=None\n".format(
                                a.name, fqn(a.type)))
                        if hasattr(a, "type") and a.type.name == "char":
                            f.write(f"    @property\n")
                            f.write(f"    def {a.name}_as_str(self):\n")
                            f.write(
                                f"        return array2str(self.{a.name})\n")
                            f.write(f"\n")
                            f.write(f"    @{a.name}_as_str.setter\n")
                            f.write(f"    def {a.name}_as_str(self, v):\n")
                            f.write(
                                f"        self.{a.name} = str2array(v, len(self.{a.name}))\n"
                            )
                            f.write(f"\n")

                    elif textx_isinstance(a, mm["VariantAttribute"]):
                        f.write("    {} : Union[{}]=None\n".format(
                            a.name, get_variant_types(a)))
                    else:
                        raise Exception("unexpected type")

                pdefs = get_all_possible_properties(a)
                pdefs = sorted(pdefs.keys())

                if "fixpointLsbValue" in pdefs:
                    if textx_isinstance(a, mm["ScalarAttribute"]):
                        if has_fixpoint(a):
                            f.write(f"    @property\n")
                            f.write(
                                f"    def {'item_fixpoint_'+a.name}(self):\n")
                            f.write(
                                f"        return int2float_fixpoint_value(self, '{a.name}', self.{a.name})\n"
                            )
                            f.write(f"    @{'item_fixpoint_'+a.name}.setter\n")
                            f.write(
                                f"    def {'item_fixpoint_'+a.name}(self, v):\n"
                            )
                            f.write(
                                f"        self.{a.name} = float2int_fixpoint_value(self, '{a.name}', v)\n"
                            )
                    elif textx_isinstance(a, mm["ArrayAttribute"]):
                        if has_fixpoint(a):
                            f.write(f"    @property\n")
                            f.write(
                                f"    def {'item_fixpoint_'+a.name}(self):\n")
                            f.write(
                                f"        return FixpointArrayLike(self, '{a.name}')\n"
                            )
                            f.write(f"    @{'item_fixpoint_'+a.name}.setter\n")
                            f.write(
                                f"    def {'item_fixpoint_'+a.name}(self, v):\n"
                            )
                            f.write(
                                f"        self.{a.name} = float2int_fixpoint_value(self, '{a.name}', v)\n"
                            )

            f.write("\n    def __post_init__(self):\n")
            f.write("        init_default_values(self)\n")
            f.write(f"""    def __setattr__(self, attribute, value):
        if not attribute in self._meta:
            raise Exception("Illegal field {{}} in {{}}".format(attribute,self.__class__.__name__))
        else:
            if len(self._meta[attribute])==0:
                super({i.name}, self).__setattr__(attribute, value)
            elif self._meta[attribute]["_is_embedded"]:
                super({i.name}, self).__setattr__(attribute, value)
            elif value is None:
                self.__dict__[attribute] = value
            elif self._meta[attribute]["_is_variant"]:
                if isinstance(value, self._meta[attribute]["_get_type"]()):
                    self.__dict__[attribute] = value
                else:
                    raise Exception("Illegal value of type {{}} for field {{}}".format(value.__class__.__name__,attribute))
            elif self._meta[attribute]["_is_scalar"]:
                if isinstance(value, self._meta[attribute]["_get_type"]()):
                    self.__dict__[attribute] = value
                elif self._meta[attribute]["_is_rawtype"]:
                    self.__dict__[attribute] = self._meta[attribute]["_get_type"]()(value)
                else:
                    raise Exception("Illegal value of type {{}} for field {{}}".format(value.__class__.__name__,attribute))
            else:
                self.__dict__[attribute] = np.array(value, dtype=self._meta[attribute]["_get_type"]())
""")

            f.write("\n    _meta_order = [\n")
            for a in i.attributes:
                f.write(f"        '{a.name}',\n")
            f.write("\n    ]\n")
            f.write("\n    _meta = {\n")
            for a in i.attributes:
                pdefs = get_all_possible_properties(a)
                pdefs = sorted(pdefs.keys())
                if "fixpointLsbValue" in pdefs:
                    if has_fixpoint(a):
                        f.write('        "item_fixpoint_{}": {{}},'.format(
                            a.name))
                if hasattr(a, "type") and a.type.name == "char":
                    f.write(f'        "{a.name}_as_str": {{}},\n')
                if a.is_variant():
                    for m in a.mappings:
                        m_pdefs = get_all_possible_properties(m)
                        m_pdefs = sorted(m_pdefs.keys())
                        f.write(f'        "{meta_name_for_mapping(m)}": ')
                        f.write("{")
                        output_properties(f, m, m_pdefs)
                        f.write("},\n")

                f.write('        "{}": {{ '.format(a.name))
                f.write('"_name":"{}",'.format(a.name))
                if a.if_attr is None:
                    f.write('"_has_if_restriction":False,')
                    f.write('"_if_restriction":lambda _: True,')
                else:
                    f.write('"_has_if_restriction":True,')
                    f.write('"_if_restriction":lambda s:{},'.format(
                        a.if_attr.predicate.render_formula(prefix="s.")))
                if textx_isinstance(a, mm["VariantAttribute"]):
                    f.write('"_get_type_for": lambda s: {}[s.{}], '.format(
                        get_variant_type_map(a),
                        a.variant_selector.render_formula(**fp(struct_obj)),
                    ))
                    f.write('"_get_meta_for": lambda s: {}[s.{}], '.format(
                        get_variant_meta_map(struct_obj, a),
                        a.variant_selector.render_formula(**fp(struct_obj)),
                    ))
                    f.write('"_is_scalar":True,')
                    f.write('"_is_variant":True,')
                    f.write('"_is_array":False,')
                    f.write('"_is_rawtype":False,')
                    f.write('"_is_enum":False,')
                    f.write('"_is_struct":True,')
                    f.write('"_is_embedded":False,')
                    f.write('"_get_type": lambda: ({}), '.format(
                        get_variant_types(a)))
                elif textx_isinstance(a, mm["ScalarAttribute"]):
                    f.write(f'"_is_container":{a.is_container()},')
                    f.write('"_is_scalar":True,')
                    f.write('"_is_variant":False,')
                    f.write('"_is_array":False,')
                    if textx_isinstance(a.type, mm["RawType"]):
                        f.write('"_is_rawtype":True,')
                    else:
                        f.write('"_is_rawtype":False,')
                    if textx_isinstance(a.type, mm["Struct"]):
                        f.write('"_is_struct":True,')
                    else:
                        f.write('"_is_struct":False,')
                    if textx_isinstance(a.type, mm["Enum"]):
                        f.write('"_is_enum":True,')
                    else:
                        f.write('"_is_enum":False,')
                    f.write(f'"_is_embedded":{tf(a.is_embedded())},')
                    f.write('"_get_type": lambda: {}, '.format(fqn(a.type)))
                    if textx_isinstance(a.type, mm["Enum"]):
                        f.write('"_get_underlying_type": lambda: {}, '.format(
                            fqn(a.type.type)))
                    if hasattr(a, "type") and a.type.name == "char":
                        f.write('"_has_char_content":True,')
                    else:
                        f.write('"_has_char_content":False,')
                elif textx_isinstance(a, mm["ArrayAttribute"]):
                    f.write('"_is_scalar":False,')
                    f.write('"_is_variant":False,')
                    f.write('"_is_array":True,')
                    if a.has_fixed_size():
                        f.write('"_is_dynamic_array":False,')
                    else:
                        f.write('"_is_dynamic_array":True,')
                    f.write('"_get_dim":lambda x:({}),'.format(
                        a.render_formula(prefix="x.", **fp(struct_obj))))
                    f.write('"_get_dim_nd":lambda x:({},),'.format(
                        a.render_formula_comma_separated(prefix="x.",
                                                         **fp(struct_obj))))
                    if textx_isinstance(a.type, mm["RawType"]):
                        f.write('"_is_rawtype":True,')
                    else:
                        f.write('"_is_rawtype":False,')
                    if textx_isinstance(a.type, mm["Struct"]):
                        f.write('"_is_struct":True,')
                    else:
                        f.write('"_is_struct":False,')
                    if textx_isinstance(a.type, mm["Enum"]):
                        f.write('"_is_enum":True,')
                    else:
                        f.write('"_is_enum":False,')
                    f.write(f'"_is_embedded":{tf(a.is_embedded())},')
                    f.write('"_get_type": lambda: {}, '.format(fqn(a.type)))
                    if textx_isinstance(a.type, mm["Enum"]):
                        f.write('"_get_underlying_type": lambda: {}, '.format(
                            fqn(a.type.type)))
                    if hasattr(a, "type") and a.type.name == "char":
                        f.write('"_has_char_content":True,')
                    else:
                        f.write('"_has_char_content":False,')
                else:
                    raise Exception("unexpected type constellation")

                pdefs = get_all_possible_properties(a)
                pdefs = sorted(pdefs.keys())

                if "fixpointLsbValue" in pdefs:
                    if has_fixpoint(a):
                        f.write(f'"_is_fixpoint":True,')
                        f.write(
                            f'"_fixpointLsbValue": {get_fixpoint_LSB_value(a)},'
                        )
                        f.write(
                            f'"_fixpointOffsetValue": {get_fixpoint_offset_value(a)},'
                        )
                    else:
                        f.write(f'"_is_fixpoint":False,')
                else:
                    f.write(f'"_is_fixpoint":False,')

                output_properties(f, a, pdefs)

                f.write("},\n")
            f.write("    }  # end of _meta\n")
            f.write("    _meta_struct={\n")
            for up in get_all_unique_properties(i):
                f.write(
                    f"        'item_get_unique_{up[0].name}':lambda i:i.{'.'.join(map(lambda x:x.name, up[1]))},\n"
                )
                f.write(
                    f"        'item_set_unique_{up[0].name}':lambda i,v:setattr({'.'.join(['i']+list(map(lambda x: x.name, up[1][:-1])))}, '{up[1][-1].name}',v),\n"
                )
            f.write("    }  # end of _meta_struct\n")
示例#6
0
文件: validation.py 项目: goto40/mdsd
def check_Struct(s):
    mm = get_metamodel(s)

    # check mandatory properties in attributes
    mandatory_prop_defs = get_all_possible_mandatory_properties(s)
    attr_prop_defs = map(lambda p: p.definition, s.properties)
    for d in mandatory_prop_defs.values():
        textx_assert(d in attr_prop_defs, s,
                     f"missing mandatory property '{d.name}'")

    # check if max count of properties are not violated ("... to ... times per message)
    def get_all_properties_of_struct(s):
        lst = []
        for a in s.attributes:
            lst = lst + a.properties
            if textx_isinstance(a, mm["ScalarAttribute"]) and textx_isinstance(
                    a.type, mm["Struct"]):
                do_break = get_property(a, "is_payload")  # None or bool
                if do_break is None or not do_break:
                    lst = lst + get_all_properties_of_struct(a.type)
        return lst

    properties = get_all_properties_of_struct(s)
    properties_per_def = {}
    for p in properties:
        if p.definition not in properties_per_def:
            properties_per_def[p.definition] = [p]
        else:
            properties_per_def[p.definition].append(p)

    property_defs = get_all_possible_properties(
        s, filter_applicable_to_model_object=False).values()
    for d in property_defs:
        if d.numberOfPropRestriction is not None:
            n = len(properties_per_def.get(d, []))
            textx_assert(
                n >= d.numberOfPropRestriction.min,
                s,
                f'need at least {d.numberOfPropRestriction.min} of property "{d.name}"',
            )
            textx_assert(
                n <= d.numberOfPropRestriction.max,
                s,
                f'not more than {d.numberOfPropRestriction.max} of property "{d.name}" allowed',
            )

    # unique names:
    all_attribute_names = list(map(lambda x: x.name, s.attributes))
    all_attribute_names_unique = set(all_attribute_names)
    if len(all_attribute_names) != len(all_attribute_names_unique):
        idx = 0
        while len(all_attribute_names) > 0:
            first = all_attribute_names[0]
            del all_attribute_names[0]
            textx_assert(
                first in all_attribute_names_unique,
                s.attributes[idx],
                f"attribute name {first} is not unique",
            )
            all_attribute_names_unique.remove(first)
            idx += 1

    check_Constants(s)