From 511d31cbd18a13794411c60d9c245b76d92c56a1 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Tue, 14 Jan 2025 19:02:53 -0700 Subject: lib9p: idl: Parser: Use Python 3.13 type aliases --- lib9p/idl/__init__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib9p/idl/__init__.py') diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py index 920d02d..634b447 100644 --- a/lib9p/idl/__init__.py +++ b/lib9p/idl/__init__.py @@ -1,12 +1,12 @@ # lib9p/idl/__init__.py - A parser for .9p specification files. # -# Copyright (C) 2024 Luke T. Shumaker +# Copyright (C) 2024-2025 Luke T. Shumaker # SPDX-License-Identifier: AGPL-3.0-or-later import enum import os.path import re -from typing import Callable, Literal, TypeAlias, TypeVar, cast +from typing import Callable, Literal, TypeVar, cast __all__ = [ # entrypoint @@ -181,8 +181,7 @@ class Message(Struct): return self.members[1].val.tokens[0].val -Type: TypeAlias = Primitive | Number | Bitfield | Struct | Message -# type Type = Primitive | Number | Bitfield | Struct | Message # Change to this once we have Python 3.13 +type Type = Primitive | Number | Bitfield | Struct | Message T = TypeVar("T", Number, Bitfield, Struct, Message) # Parse ######################################################################## -- cgit v1.2.3-2-g168b From 68a9773683ae975f03cac9f327c729b3149f2689 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Tue, 14 Jan 2025 19:37:55 -0700 Subject: lib9p: idl: Parser: Fix an error message --- lib9p/idl/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib9p/idl/__init__.py') diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py index 634b447..3379bdf 100644 --- a/lib9p/idl/__init__.py +++ b/lib9p/idl/__init__.py @@ -265,7 +265,7 @@ def parse_members(ver: str, env: dict[str, Type], struct: Struct, specs: str) -> raise ValueError(f"duplicate member name {repr(member.name)}") if m.group("typ") not in env: - raise NameError(f"Unknown type {repr(m.group(2))}") + raise NameError(f"Unknown type {repr(m.group('typ'))}") member.typ = env[m.group("typ")] if cnt := m.group("cnt"): -- cgit v1.2.3-2-g168b From e1994d3d3f2bb80d039d0db567706e0739161e79 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Sun, 12 Jan 2025 21:10:34 -0700 Subject: lib9p: Limit count and offset to INT{32,64}_MAX --- lib9p/idl/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib9p/idl/__init__.py') diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py index 3379bdf..c08a89e 100644 --- a/lib9p/idl/__init__.py +++ b/lib9p/idl/__init__.py @@ -447,7 +447,7 @@ def parse_file( typs: list[Type] = [x for x in env.values() if not isinstance(x, Primitive)] for typ in [typ for typ in typs if isinstance(typ, Struct)]: - valid_syms = ["end", *["&" + m.name for m in typ.members]] + valid_syms = ["end", "s32_max", "s64_max", *["&" + m.name for m in typ.members]] for member in typ.members: for tok in [*member.max.tokens, *member.val.tokens]: if isinstance(tok, ExprSym) and tok.name not in valid_syms: -- cgit v1.2.3-2-g168b From 7f4b9794efb591c9de9906340fe2c26c838c2f52 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Tue, 14 Jan 2025 19:26:13 -0700 Subject: lib9p: idl: Add numeric constants --- lib9p/idl/__init__.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'lib9p/idl/__init__.py') diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py index c08a89e..ab45ed0 100644 --- a/lib9p/idl/__init__.py +++ b/lib9p/idl/__init__.py @@ -50,8 +50,11 @@ class Number: prim: Primitive + vals: dict[str, str] + def __init__(self) -> None: self.in_versions = set() + self.vals = {} @property def static_size(self) -> int: @@ -195,12 +198,27 @@ re_memtype = f"(?:{re_symname}|{re_priname})" # typenames that a struct member re_expr = f"(?:(?:-|\\+|[0-9]+|&?{re_symname})+)" +re_numspec = f"(?P{re_symname})\\s*=\\s*(?P\\S+)" + re_bitspec_bit = f"(?P[0-9]+)\\s*=\\s*(?P{re_symname})" re_bitspec_alias = f"(?P{re_symname})\\s*=\\s*(?P\\S+)" re_memberspec = f"(?:(?P{re_symname})\\*\\()?(?P{re_symname})\\[(?P{re_memtype})(?:,max=(?P{re_expr})|,val=(?P{re_expr}))*\\]\\)?" +def parse_numspec(ver: str, n: Number, spec: str) -> None: + spec = spec.strip() + + if m := re.fullmatch(re_numspec, spec): + name = m.group("name") + val = m.group("val") + if name in n.vals: + raise ValueError(f"{n.name}: name {repr(name)} already assigned") + n.vals[name] = val + else: + raise SyntaxError(f"invalid num spec {repr(spec)}") + + def parse_bitspec(ver: str, bf: Bitfield, spec: str) -> None: spec = spec.strip() @@ -433,6 +451,8 @@ def parse_file( match prev: case Bitfield(): parse_bitspec(version, prev, m.group("specs")) + case Number(): + parse_numspec(version, prev, m.group("specs")) case Struct(): # and Message() parse_members(version, env, prev, m.group("specs")) case _: -- cgit v1.2.3-2-g168b