reprospect.test.sass.composite module

Thin user-facing factories for the matchers in reprospect.test.sass.composite_impl.

class reprospect.test.sass.composite.Fluentizer(matcher: InstructionMatcher)View on GitHub

Bases: InstructionMatcher

Note

It is not decorated with dataclasses.dataclass() because of https://github.com/mypyc/mypyc/issues/1061.

__init__(matcher: InstructionMatcher) NoneView on GitHub
final match(inst: Instruction | str) InstructionMatch | NoneView on GitHub
matcher: Final[InstructionMatcher]
one_or_more_times() OneOrMoreInSequenceMatcherView on GitHub

Match matcher one or more times (consecutively).

times(num: int) InSequenceAtMatcher | OrderedInSequenceMatcherView on GitHub

Match matcher num times (consecutively).

Note

If num is 0, it tests for the absence of a match.

with_modifier(modifier: str, index: int | None = None) FluentizerView on GitHub
>>> from reprospect.test.sass.composite import instruction_is
>>> from reprospect.test.sass.instruction import AnyMatcher
>>> matcher = instruction_is(AnyMatcher()).with_modifier(modifier='U32').with_operand(index=0, operand='R4')
>>> matcher.match(inst='IMAD.WIDE.U32 R4, R7, 0x4, R4')
InstructionMatch(opcode='IMAD', modifiers=('WIDE', 'U32'), operands=('R4', 'R7', '0x4', 'R4'), predicate=None, additional=None)
with_operand(operand: str | AddressMatcher | ConstantMatcher | RegisterMatcher, index: int | None = None) FluentizerView on GitHub
>>> from reprospect.test.sass.composite   import instruction_is
>>> from reprospect.test.sass.instruction import Fp32AddMatcher, RegisterMatcher
>>> from reprospect.tools.sass.decode     import RegisterType
>>> matcher = instruction_is(Fp32AddMatcher()).with_operand(index = 1, operand = RegisterMatcher(rtype = RegisterType.GPR, index = 8))
>>> matcher.match(inst = 'FADD R5, R9, R10')
>>> matcher.match(inst = 'FADD R5, R8, R9')
InstructionMatch(opcode='FADD', modifiers=(), operands=('R5', 'R8', 'R9'), predicate=None, additional={'dst': ['R5']})
with_operands(operands: Collection[tuple[int, str | AddressMatcher | ConstantMatcher | RegisterMatcher]]) FluentizerView on GitHub

Similar to with_operand() for many operands.

>>> from reprospect.test.sass.composite   import instruction_is
>>> from reprospect.test.sass.instruction import Fp32AddMatcher
>>> matcher = instruction_is(Fp32AddMatcher()).with_operands(
...     operands = ((1, 'R8'), (2, 'R9')),
... )
>>> matcher.match(inst = 'FADD R5, R9, R10')
>>> matcher.match(inst = 'FADD R5, R8, R9')
InstructionMatch(opcode='FADD', modifiers=(), operands=('R5', 'R8', 'R9'), predicate=None, additional={'dst': ['R5']})
zero_or_more_times() ZeroOrMoreInSequenceMatcherView on GitHub

Match matcher zero or more times (consecutively).

reprospect.test.sass.composite.any_of(*matchers: InstructionMatcher | SequenceMatcher) AnyOfMatcherView on GitHub

Match a sequence of instructions against any of the matchers.

Note

Returns the first match.

>>> from reprospect.test.sass.composite   import any_of
>>> from reprospect.test.sass.instruction import OpcodeModsMatcher
>>> matcher = any_of(
...     OpcodeModsMatcher(opcode = 'YIELD', operands = False),
...     OpcodeModsMatcher(opcode = 'NOP', operands = False),
... )
>>> matcher.match(instructions = ('FADD R1, R1, R2',)) is None
True
>>> matcher.match(instructions=('NOP',)) is not None
True
>>> matcher.matched
1
reprospect.test.sass.composite.findall(matcher: InstructionMatcher, instructions: Sequence[Instruction | str]) list[InstructionMatch]View on GitHub
reprospect.test.sass.composite.findall(matcher: SequenceMatcher, instructions: Sequence[Instruction | str]) list[list[InstructionMatch]]

Find all matches for matcher in a sequence of instructions. Similarly to re.findall(), return an empty list if no match found.

>>> from reprospect.test.sass.composite import findall
>>> from reprospect.test.sass.instruction import OpcodeModsMatcher
>>> findall(
...     OpcodeModsMatcher(opcode='FADD', operands=True),
...     (
...         'NOP',
...         'FADD R1, R1, R2',
...         'NOP',
...         'FADD R3, R4, R5',
... ))
[InstructionMatch(opcode='FADD', modifiers=(), operands=('R1', 'R1', 'R2'), predicate=None, additional=None), InstructionMatch(opcode='FADD', modifiers=(), operands=('R3', 'R4', 'R5'), predicate=None, additional=None)]
reprospect.test.sass.composite.findunique(matcher: InstructionMatcher, instructions: Sequence[Instruction | str]) InstructionMatchView on GitHub
reprospect.test.sass.composite.findunique(matcher: SequenceMatcher, instructions: Sequence[Instruction | str]) list[InstructionMatch]

Ensure that findall() matches once.

reprospect.test.sass.composite.instruction_count_is(matcher: InstructionMatcher, count: int) CountInSequenceMatcherView on GitHub

Match only if the matcher matches count times in the sequence.

>>> from reprospect.test.sass.composite import instruction_count_is
>>> from reprospect.test.sass.instruction import Fp32AddMatcher
>>> matcher = instruction_count_is(Fp32AddMatcher(), count=2)
>>> matcher.match(instructions=('FADD R2, R2, R3',))
>>> matcher.match(instructions=('FADD R2, R2, R3', 'FADD R4, R4, R5'))
[InstructionMatch(opcode='FADD', modifiers=(), operands=('R2', 'R2', 'R3'), predicate=None, additional={'dst': ['R2']}), InstructionMatch(opcode='FADD', modifiers=(), operands=('R4', 'R4', 'R5'), predicate=None, additional={'dst': ['R4']})]
reprospect.test.sass.composite.instruction_is(matcher: InstructionMatcher) FluentizerView on GitHub

Match the current instruction with matcher.

>>> from reprospect.test.sass.composite   import instruction_is
>>> from reprospect.test.sass.instruction import Fp32AddMatcher
>>> instruction_is(Fp32AddMatcher()).match(inst = 'FADD R2, R2, R3')
InstructionMatch(opcode='FADD', modifiers=(), operands=('R2', 'R2', 'R3'), predicate=None, additional={'dst': ['R2']})
>>> instruction_is(Fp32AddMatcher()).one_or_more_times().match(instructions = ('FADD R2, R2, R3', 'FADD R4, R4, R5'))
[InstructionMatch(opcode='FADD', modifiers=(), operands=('R2', 'R2', 'R3'), predicate=None, additional={'dst': ['R2']}), InstructionMatch(opcode='FADD', modifiers=(), operands=('R4', 'R4', 'R5'), predicate=None, additional={'dst': ['R4']})]
reprospect.test.sass.composite.instructions_are(*matchers: InstructionMatcher | SequenceMatcher) OrderedInSequenceMatcherView on GitHub

Match a sequence of instructions against matchers.

>>> from reprospect.test.sass.composite   import instructions_are
>>> from reprospect.test.sass.instruction import OpcodeModsMatcher
>>> instructions_are(
...     OpcodeModsMatcher(opcode = 'YIELD', operands = False),
...     instruction_is(OpcodeModsMatcher(opcode = 'NOP', operands = False)).zero_or_more_times(),
... ).match(instructions = ('YIELD', 'NOP', 'NOP'))
[InstructionMatch(opcode='YIELD', modifiers=(), operands=(), predicate=None, additional=None), InstructionMatch(opcode='NOP', modifiers=(), operands=(), predicate=None, additional=None), InstructionMatch(opcode='NOP', modifiers=(), operands=(), predicate=None, additional=None)]
reprospect.test.sass.composite.instructions_contain(matcher: InstructionMatcher | SequenceMatcher) InSequenceMatcherView on GitHub

Check that a sequence of instructions contains at least one instruction matching matcher.

Note

Stops on the first match.

>>> from reprospect.test.sass.composite   import instructions_are, instructions_contain
>>> from reprospect.test.sass.instruction import OpcodeModsMatcher
>>> matcher = instructions_contain(instructions_are(
...     OpcodeModsMatcher(opcode = 'YIELD', operands = False),
...     OpcodeModsMatcher(opcode = 'FADD', operands = True),
... ))
>>> matcher.match(instructions = ('NOP', 'NOP', 'YIELD', 'FADD R1, R1, R2'))
[InstructionMatch(opcode='YIELD', modifiers=(), operands=(), predicate=None, additional=None), InstructionMatch(opcode='FADD', modifiers=(), operands=('R1', 'R1', 'R2'), predicate=None, additional=None)]
>>> matcher.next_index
4
reprospect.test.sass.composite.interleaved_instructions_are(*matchers: InstructionMatcher | SequenceMatcher) OrderedInterleavedInSequenceMatcherView on GitHub

Match a sequence of instructions against matchers, allowing matched instructions to be interleaved with unmatched instructions.

>>> from reprospect.test.sass.composite import interleaved_instructions_are
>>> from reprospect.test.sass.instruction import OpcodeModsMatcher
>>> matcher = interleaved_instructions_are(
...     OpcodeModsMatcher(opcode = 'YIELD', operands = False),
...     OpcodeModsMatcher(opcode = 'NOP', operands = False),
... )
>>> matcher.match(instructions = ('YIELD', 'NOP')) is not None
True
>>> matcher.match(instructions = ('NOP', 'YIELD')) is None
True
>>> matcher.match(instructions = ('YIELD', 'FADD R0, R1, R2', 'NOP')) is not None
True
reprospect.test.sass.composite.unordered_instructions_are(*matchers: InstructionMatcher | SequenceMatcher) UnorderedInSequenceMatcherView on GitHub

Match a sequence of instructions against matchers (unordered).

>>> from reprospect.test.sass.composite   import unordered_instructions_are
>>> from reprospect.test.sass.instruction import OpcodeModsMatcher
>>> unordered_instructions_are(
...     OpcodeModsMatcher(opcode = 'YIELD', operands = False),
...     OpcodeModsMatcher(opcode = 'NOP', operands = False),
... ).match(instructions = ('NOP', 'YIELD'))
[InstructionMatch(opcode='NOP', modifiers=(), operands=(), predicate=None, additional=None), InstructionMatch(opcode='YIELD', modifiers=(), operands=(), predicate=None, additional=None)]
reprospect.test.sass.composite.unordered_interleaved_instructions_are(*matchers: InstructionMatcher | SequenceMatcher) UnorderedInterleavedInSequenceMatcherView on GitHub

Match a sequence of instructions against matchers (unordered), allowing matched instructions to be interleaved with unmatched instructions.

>>> from reprospect.test.sass.composite import unordered_interleaved_instructions_are
>>> from reprospect.test.sass.instruction import OpcodeModsMatcher
>>> matcher = unordered_interleaved_instructions_are(
...     OpcodeModsMatcher(opcode = 'YIELD', operands = False),
...     OpcodeModsMatcher(opcode = 'NOP', operands = False),
... )
>>> matcher.match(instructions = ('YIELD', 'NOP')) is not None
True
>>> matcher.match(instructions = ('NOP', 'YIELD')) is not None
True
>>> matcher.match(instructions = ('YIELD', 'FADD R0, R1, R2', 'NOP')) is not None
True
>>> matcher.match(instructions = ('YIELD',)) is None
True