+import dataclasses as dc
import re
import sys
from collections.abc import Callable
return condition[1:]
return "!" + condition
+
+is_a_simple_defined = re.compile(r'^defined\s*\(\s*[A-Za-z0-9_]+\s*\)$').match
+
+
+@dc.dataclass(repr=False)
class Monitor:
"""
A simple C preprocessor that scans C source and computes, line by line,
Anyway this implementation seems to work well enough for the CPython sources.
"""
+ filename: str | None = None
+ _: dc.KW_ONLY
+ verbose: bool = False
- is_a_simple_defined: Callable[[str], re.Match[str] | None]
- is_a_simple_defined = re.compile(r'^defined\s*\(\s*[A-Za-z0-9_]+\s*\)$').match
-
- def __init__(self, filename: str | None = None, *, verbose: bool = False) -> None:
+ def __post_init__(self) -> None:
self.stack: TokenStack = []
self.in_comment = False
self.continuation: str | None = None
self.line_number = 0
- self.filename = filename
- self.verbose = verbose
def __repr__(self) -> str:
- return ''.join((
- '<Monitor ',
- str(id(self)),
- " line=", str(self.line_number),
- " condition=", repr(self.condition()),
- ">"))
+ return (
+ f"<Monitor {id(self)} line={self.line_number} condition={self.condition()!r}>"
+ )
def status(self) -> str:
return str(self.line_number).rjust(4) + ": " + self.condition()
if not condition:
self.fail("Invalid format for #" + token + " line: no argument!")
if token in {'if', 'elif'}:
- if not self.is_a_simple_defined(condition):
+ if not is_a_simple_defined(condition):
condition = "(" + condition + ")"
if token == 'elif':
previous_token, previous_condition = pop_stack()