actual recursive unification for transforms
Still stops at the first solution but that's not too bad.
This commit is contained in:
parent
71563fcf33
commit
3680b56765
|
@ -0,0 +1 @@
|
|||
test/
|
|
@ -0,0 +1,14 @@
|
|||
#! /usr/bin/env make -f
|
||||
|
||||
py = g35pe2_ml_patch.py
|
||||
src = $(filter-out $(wildcard test/*-E2.g1a),$(wildcard test/*.g1a))
|
||||
out = $(src:.g1a=-E2.g1a)
|
||||
|
||||
test: $(out)
|
||||
|
||||
test/%-E2.g1a: test/%.g1a $(py)
|
||||
@echo -e "\n\e[33;1mPatching $<...\x1b[0m"
|
||||
@ python $(py) $< $@
|
||||
|
||||
# Always redo all the tests
|
||||
.PHONY: test
|
|
@ -104,29 +104,39 @@ class Transform:
|
|||
self.insn = [(make_pattern(p), make_pattern(repl))
|
||||
for p, repl in patterns]
|
||||
|
||||
def match_transform_recursive(insn, vars, offsets, data, start, end):
|
||||
if not insn:
|
||||
return (vars, offsets)
|
||||
|
||||
p, repl = insn[0]
|
||||
n = len(p.nibbles) // 2
|
||||
insn = insn[1:]
|
||||
|
||||
# Try all matching offsets
|
||||
for offset in range(start, end, 2):
|
||||
d = data[offset:offset+n]
|
||||
v = match_pattern(p, d, vars)
|
||||
if v != False:
|
||||
o = offsets + [offset]
|
||||
v2, o2 = match_transform_recursive(insn, v, o, data, start, end)
|
||||
if v2 != False:
|
||||
# TODO: Yield here to explore all options
|
||||
return (v2, o2)
|
||||
|
||||
return (False, [])
|
||||
|
||||
|
||||
def match_transform(tr, base_vars, data, start, end):
|
||||
"""Matches all instructions from <tr> in <data> between <start> and <end>,
|
||||
returning either (False, []) or a pair (<vars>, [<offset>...])
|
||||
indicating where instructions matched and with what variables."""
|
||||
indicating where instructions matched and with what variables. Only the
|
||||
first solution found to the unification problem is returned."""
|
||||
|
||||
start, end = align(start, end, 2)
|
||||
vars = base_vars.copy()
|
||||
offsets = []
|
||||
|
||||
for p, repl in tr.insn:
|
||||
n = len(p.nibbles) // 2
|
||||
|
||||
for offset in range(start, end, 2):
|
||||
d = data[offset:offset+n]
|
||||
v = match_pattern(p, d, vars)
|
||||
if v != False:
|
||||
offsets.append(offset)
|
||||
vars = v
|
||||
break
|
||||
else:
|
||||
return (False, [])
|
||||
|
||||
return (vars, offsets)
|
||||
return match_transform_recursive(tr.insn, vars, offsets, data, start, end)
|
||||
|
||||
def apply_transform(tr, vars, offsets, data):
|
||||
"""Apply replacements from <tr> on <data> in-place, using the <offsets> and
|
||||
|
|
Loading…
Reference in New Issue