From 2c3dc0a67b3a64ca23645a8b524e1c977e145402 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Fri, 28 Mar 2025 02:26:33 -0600 Subject: lib9p: protogen: h.py: Pull each idl typ into its own function Clashing variable names are becoming a pain. --- lib9p/protogen/h.py | 190 +++++++++++++++++++++++++++------------------------- 1 file changed, 99 insertions(+), 91 deletions(-) (limited to 'lib9p/protogen/h.py') diff --git a/lib9p/protogen/h.py b/lib9p/protogen/h.py index 7785ca1..c84ff02 100644 --- a/lib9p/protogen/h.py +++ b/lib9p/protogen/h.py @@ -268,99 +268,11 @@ enum {c9util.ident('version')} {{ match typ: case idl.Number(): - ret += f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n" - prefix = f"{c9util.IDENT(typ.typname)}_" - namewidth = max(len(name) for name in typ.vals) - for name, val in typ.vals.items(): - ret += f"#define {prefix}{name:<{namewidth}} (({c9util.typename(typ)})UINT{typ.static_size*8}_C({val}))\n" + ret += gen_number(typ) case idl.Bitfield(): - ret += f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n" - - def bitname(val: idl.Bit | idl.BitAlias) -> str: - s = val.bitname - match val: - case idl.Bit(cat=idl.BitCat.RESERVED): - s = "_RESERVED_" + s - case idl.Bit(cat=idl.BitCat.SUBFIELD): - assert isinstance(typ, idl.Bitfield) - n = sum( - 1 - for b in typ.bits[: val.num] - if b.cat == idl.BitCat.SUBFIELD - and b.bitname == val.bitname - ) - s = f"_{s}_{n}" - case idl.Bit(cat=idl.BitCat.UNUSED): - return "" - return c9util.Ident(c9util.add_prefix(typ.typname.upper() + "_", s)) - - namewidth = max( - len(bitname(val)) for val in [*typ.bits, *typ.names.values()] - ) - - ret += "\n" - for bit in reversed(typ.bits): - vers = bit.in_versions - if bit.cat == idl.BitCat.UNUSED: - vers = typ.in_versions - ret += cutil.ifdef_push(2, c9util.ver_ifdef(vers)) - - # It is important all of the `beg` strings have - # the same length. - end = "" - match bit.cat: - case ( - idl.BitCat.USED | idl.BitCat.RESERVED | idl.BitCat.SUBFIELD - ): - if cutil.ifdef_leaf_is_noop(): - beg = "#define " - else: - beg = "# define" - case idl.BitCat.UNUSED: - beg = "/* unused" - end = " */" - - c_name = bitname(bit) - c_val = f"1<<{bit.num}" - ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n" - if aliases := [ - alias - for alias in typ.names.values() - if isinstance(alias, idl.BitAlias) - ]: - ret += "\n" - - for alias in aliases: - ret += cutil.ifdef_push(2, c9util.ver_ifdef(alias.in_versions)) - - end = "" - if cutil.ifdef_leaf_is_noop(): - beg = "#define " - else: - beg = "# define" - - c_name = bitname(alias) - c_val = alias.val - ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n" - ret += cutil.ifdef_pop(1) - del bitname + ret += gen_bitfield(typ) case idl.Struct(): # and idl.Message(): - ret += c9util.typename(typ) + " {" - if not typ.members: - ret += "};\n" - continue - ret += "\n" - - typewidth = max(len(c9util.typename(m.typ, m)) for m in typ.members) - - for member in typ.members: - if member.val: - continue - ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) - ret += f"\t{c9util.typename(member.typ, member):<{typewidth}} {'*' if member.cnt else ' '}{member.membname};\n" - ret += cutil.ifdef_pop(1) - ret += "};\n" - del typ + ret += gen_struct(typ) ret += cutil.ifdef_pop(0) ret += """ @@ -445,3 +357,99 @@ enum {c9util.ident('version')} {{ ret += "};\n" return ret + + +def gen_number(typ: idl.Number) -> str: + ret = f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n" + prefix = f"{c9util.IDENT(typ.typname)}_" + namewidth = max(len(name) for name in typ.vals) + for name, val in typ.vals.items(): + ret += f"#define {prefix}{name:<{namewidth}} (({c9util.typename(typ)})UINT{typ.static_size*8}_C({val}))\n" + return ret + + +def gen_bitfield(typ: idl.Bitfield) -> str: + ret = f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n" + + def bitname(val: idl.Bit | idl.BitAlias) -> str: + s = val.bitname + match val: + case idl.Bit(cat=idl.BitCat.RESERVED): + s = "_RESERVED_" + s + case idl.Bit(cat=idl.BitCat.SUBFIELD): + assert isinstance(typ, idl.Bitfield) + n = sum( + 1 + for b in typ.bits[: val.num] + if b.cat == idl.BitCat.SUBFIELD and b.bitname == val.bitname + ) + s = f"_{s}_{n}" + case idl.Bit(cat=idl.BitCat.UNUSED): + return "" + return c9util.Ident(c9util.add_prefix(typ.typname.upper() + "_", s)) + + namewidth = max(len(bitname(val)) for val in [*typ.bits, *typ.names.values()]) + + ret += "\n" + for bit in reversed(typ.bits): + vers = bit.in_versions + if bit.cat == idl.BitCat.UNUSED: + vers = typ.in_versions + ret += cutil.ifdef_push(2, c9util.ver_ifdef(vers)) + + # It is important all of the `beg` strings have + # the same length. + end = "" + match bit.cat: + case idl.BitCat.USED | idl.BitCat.RESERVED | idl.BitCat.SUBFIELD: + if cutil.ifdef_leaf_is_noop(): + beg = "#define " + else: + beg = "# define" + case idl.BitCat.UNUSED: + beg = "/* unused" + end = " */" + + c_name = bitname(bit) + c_val = f"1<<{bit.num}" + ret += ( + f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n" + ) + if aliases := [ + alias for alias in typ.names.values() if isinstance(alias, idl.BitAlias) + ]: + ret += "\n" + + for alias in aliases: + ret += cutil.ifdef_push(2, c9util.ver_ifdef(alias.in_versions)) + + end = "" + if cutil.ifdef_leaf_is_noop(): + beg = "#define " + else: + beg = "# define" + + c_name = bitname(alias) + c_val = alias.val + ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n" + ret += cutil.ifdef_pop(1) + return ret + + +def gen_struct(typ: idl.Struct) -> str: # and idl.Message + ret = c9util.typename(typ) + " {" + if not typ.members: + ret += "};\n" + return ret + ret += "\n" + + typewidth = max(len(c9util.typename(m.typ, m)) for m in typ.members) + + for member in typ.members: + if member.val: + continue + ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) + ret += f"\t{c9util.typename(member.typ, member):<{typewidth}} {'*' if member.cnt else ' '}{member.membname};\n" + ret += cutil.ifdef_pop(1) + ret += "};\n" + return ret -- cgit v1.2.3-2-g168b From a492c4a31f1c8b2a0d58e24ab957ef3c8f9edfd2 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Fri, 28 Mar 2025 10:03:44 -0600 Subject: lib9p: idl: Touch up the *.9p files --- lib9p/protogen/h.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib9p/protogen/h.py') diff --git a/lib9p/protogen/h.py b/lib9p/protogen/h.py index c84ff02..a9f0b39 100644 --- a/lib9p/protogen/h.py +++ b/lib9p/protogen/h.py @@ -361,10 +361,14 @@ enum {c9util.ident('version')} {{ def gen_number(typ: idl.Number) -> str: ret = f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n" - prefix = f"{c9util.IDENT(typ.typname)}_" - namewidth = max(len(name) for name in typ.vals) + + def cname(base: str) -> str: + prefix = f"{typ.typname}_".upper() + return c9util.Ident(c9util.add_prefix(prefix, base)) + + namewidth = max(len(cname(name)) for name in typ.vals) for name, val in typ.vals.items(): - ret += f"#define {prefix}{name:<{namewidth}} (({c9util.typename(typ)})UINT{typ.static_size*8}_C({val}))\n" + ret += f"#define {cname(name):<{namewidth}} (({c9util.typename(typ)})UINT{typ.static_size*8}_C({val}))\n" return ret -- cgit v1.2.3-2-g168b From 0b31e9fa29699bbf140e168a17ead1c993d42e3e Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Sat, 29 Mar 2025 18:19:37 -0600 Subject: lib9p: protogen: h.py: Tidy gen_struct() --- lib9p/protogen/h.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'lib9p/protogen/h.py') diff --git a/lib9p/protogen/h.py b/lib9p/protogen/h.py index a9f0b39..b0d38bf 100644 --- a/lib9p/protogen/h.py +++ b/lib9p/protogen/h.py @@ -442,18 +442,16 @@ def gen_bitfield(typ: idl.Bitfield) -> str: def gen_struct(typ: idl.Struct) -> str: # and idl.Message ret = c9util.typename(typ) + " {" - if not typ.members: - ret += "};\n" - return ret - ret += "\n" + if typ.members: + ret += "\n" - typewidth = max(len(c9util.typename(m.typ, m)) for m in typ.members) + typewidth = max(len(c9util.typename(m.typ, m)) for m in typ.members) - for member in typ.members: - if member.val: - continue - ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) - ret += f"\t{c9util.typename(member.typ, member):<{typewidth}} {'*' if member.cnt else ' '}{member.membname};\n" - ret += cutil.ifdef_pop(1) + for member in typ.members: + if member.val: + continue + ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) + ret += f"\t{c9util.typename(member.typ, member):<{typewidth}} {'*' if member.cnt else ' '}{member.membname};\n" + ret += cutil.ifdef_pop(1) ret += "};\n" return ret -- cgit v1.2.3-2-g168b From 9096e2d9cb6f438e49aa29aa2cfaef1717466a05 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Fri, 28 Mar 2025 11:31:26 -0600 Subject: lib9p: idl: Rework bitfields, allow full exprs more places --- lib9p/protogen/h.py | 138 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 105 insertions(+), 33 deletions(-) (limited to 'lib9p/protogen/h.py') diff --git a/lib9p/protogen/h.py b/lib9p/protogen/h.py index b0d38bf..13c3f89 100644 --- a/lib9p/protogen/h.py +++ b/lib9p/protogen/h.py @@ -362,42 +362,49 @@ enum {c9util.ident('version')} {{ def gen_number(typ: idl.Number) -> str: ret = f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n" + def lookup_sym(sym: str) -> str: + assert False + def cname(base: str) -> str: prefix = f"{typ.typname}_".upper() return c9util.Ident(c9util.add_prefix(prefix, base)) namewidth = max(len(cname(name)) for name in typ.vals) for name, val in typ.vals.items(): - ret += f"#define {cname(name):<{namewidth}} (({c9util.typename(typ)})UINT{typ.static_size*8}_C({val}))\n" + c_name = cname(name) + c_val = c9util.idl_expr(val, lookup_sym) + ret += f"#define {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val}))\n" return ret def gen_bitfield(typ: idl.Bitfield) -> str: ret = f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n" - def bitname(val: idl.Bit | idl.BitAlias) -> str: - s = val.bitname - match val: - case idl.Bit(cat=idl.BitCat.RESERVED): - s = "_RESERVED_" + s - case idl.Bit(cat=idl.BitCat.SUBFIELD): - assert isinstance(typ, idl.Bitfield) - n = sum( - 1 - for b in typ.bits[: val.num] - if b.cat == idl.BitCat.SUBFIELD and b.bitname == val.bitname - ) - s = f"_{s}_{n}" - case idl.Bit(cat=idl.BitCat.UNUSED): - return "" - return c9util.Ident(c9util.add_prefix(typ.typname.upper() + "_", s)) - - namewidth = max(len(bitname(val)) for val in [*typ.bits, *typ.names.values()]) + def lookup_sym(sym: str) -> str: + assert False - ret += "\n" + # There are 4 parts here: bits, aliases, masks, and numbers. + + # 1. bits + + def bitname(bit: idl.Bit) -> str: + prefix = f"{typ.typname}_".upper() + base = bit.bitname + match bit: + case idl.Bit(cat="RESERVED"): + base = "_RESERVED_" + base + case idl.Bit(cat=idl.BitNum()): + base += "_*" + case idl.Bit(cat="UNUSED"): + base = f"_UNUSED_{bit.num}" + return c9util.Ident(c9util.add_prefix(prefix, base)) + + namewidth = max(len(bitname(bit)) for bit in typ.bits) + + ret += "/* bits */\n" for bit in reversed(typ.bits): vers = bit.in_versions - if bit.cat == idl.BitCat.UNUSED: + if bit.cat == "UNUSED": vers = typ.in_versions ret += cutil.ifdef_push(2, c9util.ver_ifdef(vers)) @@ -405,26 +412,32 @@ def gen_bitfield(typ: idl.Bitfield) -> str: # the same length. end = "" match bit.cat: - case idl.BitCat.USED | idl.BitCat.RESERVED | idl.BitCat.SUBFIELD: + case "USED" | "RESERVED" | "UNUSED": if cutil.ifdef_leaf_is_noop(): beg = "#define " else: beg = "# define" - case idl.BitCat.UNUSED: - beg = "/* unused" + case idl.BitNum(): + beg = "/* number" end = " */" c_name = bitname(bit) - c_val = f"1<<{bit.num}" + c_val = f"UINT{typ.static_size*8}_C(1)<<{bit.num}" ret += ( f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n" ) - if aliases := [ - alias for alias in typ.names.values() if isinstance(alias, idl.BitAlias) - ]: - ret += "\n" + ret += cutil.ifdef_pop(1) + + # 2. aliases + if typ.aliases: - for alias in aliases: + def aliasname(alias: idl.BitAlias) -> str: + prefix = f"{typ.typname}_".upper() + base = alias.bitname + return c9util.Ident(c9util.add_prefix(prefix, base)) + + ret += "/* aliases */\n" + for alias in typ.aliases.values(): ret += cutil.ifdef_push(2, c9util.ver_ifdef(alias.in_versions)) end = "" @@ -433,10 +446,69 @@ def gen_bitfield(typ: idl.Bitfield) -> str: else: beg = "# define" - c_name = bitname(alias) - c_val = alias.val + c_name = aliasname(alias) + c_val = c9util.idl_expr(alias.val, lookup_sym) ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n" - ret += cutil.ifdef_pop(1) + + ret += cutil.ifdef_pop(1) + + # 3. masks + if typ.masks: + + def maskname(mask: idl.BitAlias) -> str: + prefix = f"{typ.typname}_".upper() + base = mask.bitname + return c9util.Ident(c9util.add_prefix(prefix, base) + "_MASK") + + ret += "/* masks */\n" + for mask in typ.masks.values(): + ret += cutil.ifdef_push(2, c9util.ver_ifdef(mask.in_versions)) + + end = "" + if cutil.ifdef_leaf_is_noop(): + beg = "#define " + else: + beg = "# define" + + c_name = maskname(mask) + c_val = c9util.idl_expr(mask.val, lookup_sym, bitwidth=typ.static_size * 8) + ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n" + + ret += cutil.ifdef_pop(1) + + # 4. numbers + def numname(num: idl.BitNum, base: str) -> str: + prefix = f"{typ.typname}_{num.numname}_".upper() + return c9util.Ident(c9util.add_prefix(prefix, base)) + + for num in typ.nums.values(): + namewidth = max( + len(numname(num, base)) + for base in [ + *[alias.bitname for alias in num.vals.values()], + "MASK", + ] + ) + ret += f"/* number: {num.numname} */\n" + for alias in num.vals.values(): + ret += cutil.ifdef_push(2, c9util.ver_ifdef(alias.in_versions)) + + end = "" + if cutil.ifdef_leaf_is_noop(): + beg = "#define " + else: + beg = "# define" + + c_name = numname(num, alias.bitname) + c_val = c9util.idl_expr(alias.val, lookup_sym) + ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n" + ret += cutil.ifdef_pop(1) + c_name = numname(num, "MASK") + c_val = f"{num.mask:#0{typ.static_size*8}b}" + ret += ( + f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n" + ) + return ret -- cgit v1.2.3-2-g168b