summaryrefslogtreecommitdiff
path: root/lib9p/core_gen
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/core_gen')
-rw-r--r--lib9p/core_gen/idlutil.py40
1 files changed, 29 insertions, 11 deletions
diff --git a/lib9p/core_gen/idlutil.py b/lib9p/core_gen/idlutil.py
index 9843675..e92839a 100644
--- a/lib9p/core_gen/idlutil.py
+++ b/lib9p/core_gen/idlutil.py
@@ -4,7 +4,6 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
import enum
-import graphlib
import typing
import idl
@@ -22,21 +21,40 @@ __all__ = [
def topo_sorted(typs: list[idl.UserType]) -> typing.Iterable[idl.UserType]:
- ts: graphlib.TopologicalSorter[idl.UserType] = graphlib.TopologicalSorter()
+ ret: list[idl.UserType] = []
+ struct_ord: dict[str, int] = {}
+
+ def get_struct_ord(typ: idl.Struct) -> int:
+ nonlocal struct_ord
+ if typ.typname not in struct_ord:
+ deps = [
+ get_struct_ord(member.typ)
+ for member in typ.members
+ if isinstance(member.typ, idl.Struct)
+ ]
+ if len(deps) == 0:
+ struct_ord[typ.typname] = 0
+ else:
+ struct_ord[typ.typname] = 1 + max(deps)
+ return struct_ord[typ.typname]
+
for typ in typs:
match typ:
case idl.Number():
- ts.add(typ)
+ ret.append(typ)
case idl.Bitfield():
- ts.add(typ)
+ ret.append(typ)
case idl.Struct(): # and idl.Message():
- deps = [
- member.typ
- for member in typ.members
- if not isinstance(member.typ, idl.Primitive)
- ]
- ts.add(typ, *deps)
- return ts.static_order()
+ _ = get_struct_ord(typ)
+ for _ord in sorted(set(struct_ord.values())):
+ for typ in typs:
+ if not isinstance(typ, idl.Struct):
+ continue
+ if struct_ord[typ.typname] != _ord:
+ continue
+ ret.append(typ)
+ assert len(ret) == len(typs)
+ return ret
# walk() #######################################################################