hi! I’d like to reduce some noise from a nested structure: the patterns I’d like to simplify are
{:type "CallStmt", :stmt {:func "g0.data.x.p", :args [{:type "local", :value 0} {:type "local", :value 1}], :result 2, :file 0, :col 0, :row 0}}
⬇️
[:CallStmt {:func "g0.data.x.p", :args [{:type "local", :value 0} {:type "local", :value 1}], :result 2}]
and I got that base case done, more or less, via
(m/match {:type "CallStmt", :stmt {:func "g0.data.x.p", :args [{:type "local", :value 0} {:type "local", :value 1}], :result 2, :file 0, :col 0, :row 0}}
{:type ?t :stmt {:func ?f :args ?a :result ?r}}
[(keyword ?t) {:func ?f :args ?a :result ?r}])
but I’ve got a bunch of problems still:
1. I’d like to omit :file, :row, :col, not enumerate what to keep — not every stmt has a :func for example
2. this is just the base, it’s a nested structure that I’d like to — and fail to — cleanup (see thread)here’s a complete example
{:static {:strings [{:value "result"} {:value "xs"} {:value "y"}], :files [{:value "foo.rego"}]}, :plans {:plans [{:name "x/p", :blocks [{:stmts [{:type "CallStmt", :stmt {:func "g0.data.x.p", :args [{:type "local", :value 0} {:type "local", :value 1}], :result 2, :file 0, :col 0, :row 0}} {:type "AssignVarStmt", :stmt {:source {:type "local", :value 2}, :target 3, :file 0, :col 0, :row 0}} {:type "MakeObjectStmt", :stmt {:target 4, :file 0, :col 0, :row 0}} {:type "ObjectInsertStmt", :stmt {:key {:type "string_index", :value 0}, :value {:type "local", :value 3}, :object 4, :file 0, :col 0, :row 0}} {:type "ResultSetAddStmt", :stmt {:value 4, :file 0, :col 0, :row 0}}]}]}]}, :funcs {:funcs [{:name "g0.data.x.p", :params [0 1], :return 2, :blocks [{:stmts [{:type "ResetLocalStmt", :stmt {:target 3, :file 0, :col 1, :row 4}} {:type "DotStmt", :stmt {:source {:type "local", :value 0}, :key {:type "string_index", :value 1}, :target 4, :file 0, :col 5, :row 5}} {:type "ScanStmt", :stmt {:source 4, :key 5, :value 6, :block {:stmts [{:type "AssignVarStmt", :stmt {:source {:type "local", :value 5}, :target 7, :file 0, :col 5, :row 5}} {:type "AssignVarStmt", :stmt {:source {:type "local", :value 6}, :target 8, :file 0, :col 5, :row 5}} {:type "DotStmt", :stmt {:source {:type "local", :value 0}, :key {:type "string_index", :value 2}, :target 9, :file 0, :col 5, :row 6}} {:type "AssignVarStmt", :stmt {:source {:type "local", :value 9}, :target 10, :file 0, :col 5, :row 6}} {:type "EqualStmt", :stmt {:a {:type "local", :value 8}, :b {:type "local", :value 10}, :file 0, :col 5, :row 7}} {:type "AssignVarOnceStmt", :stmt {:source {:type "bool", :value true}, :target 3, :file 0, :col 1, :row 4}}]}, :file 0, :col 5, :row 5}}]} {:stmts [{:type "IsDefinedStmt", :stmt {:source 3, :file 0, :col 1, :row 4}} {:type "AssignVarOnceStmt", :stmt {:source {:type "local", :value 3}, :target 2, :file 0, :col 1, :row 4}}]} {:stmts [{:type "ReturnLocalStmt", :stmt {:source 2, :file 0, :col 1, :row 4}}]}], :path ["g0" "x" "p"]}]}}(I’ll keep posting what I come up with trying to figure this out on my own)
(m/rewrites
(m/$ {:type ?t :stmt {:func (m/some ?f) :args ?a :result ?r}})
[(m/keyword ?t) :func ?f :args ?a :result ?r]
)
woah, so this actually does the trick for any CallStmt that appears anywhere, but haven’t figured out how to deal with the :func being absent for other typesnot really. trying to ignore the :func, I’ve changed it to
(m/rewrites
(m/$ {:type ?t :stmt {:args ?a :result ?r}})
[(m/keyword ?t) :args ?a :result ?r])
but that only does the right thing on the first statement it encounters, the rest has :args nil :result nilso I think this is the wrong approach. I’m considered m/cata… 💭
yup this looks better
(m/rewrite plan
{:plans {:plans [!p ...]}}
{:plans [(m/cata !p) ...]}
{:name ?n :blocks [!b ...]}
[?n (m/cata !b) ...]
{:stmts [!s ...]}
[(m/cata !s) ...]
{:type ?t :stmt ?stmt}
[?t . ?stmt])
now only (1.) is left
{:type (m/some ?t) :stmt (m/some !s)}
((m/keyword ?t) . (m/cata {:stmt !s}))
{:stmt {:file _ :col _ :row _ & ?rest}}
?rest
I think this does the trickI think I get the hang of it https://gist.github.com/srenatus/97f693ca911f060380a3305ba02fe55e