Feature/matching dsl related to #20
Added barebones of matching
ToDo:
- [x] Outputs
- [ ] Matching
- [x] Constants
- [x] NumberMatching
- [x] String Matching 'world'
- [x] String Operations
- [x] StartsWith: 'hello'*
- [x] EndsWith: *'hello'
- [x] Contains: 'hello'
- [x] Match instructions already seen (e.g. "(sub {lhs: (add {x} $y)} $y)") - the first occurance of an $ will be saved and later will be compared with it and make it available to output subexpressions that matches a pattern
- [x] Ignore Argument "_"
- [x] Not Operator "!"
- [x] Match Sub Pattern
- [x] Match Binary Instructions
- [ ] Match Other Instructions
- [x] Match Type Specifier
(add {x}#const (mul {y}#instr))and(add #const {x}) - [x] Number Operations
- [x] > <
- [x] Update Docs
- [ ] Replacement
- [ ] Replace with buffered values
- [ ] Replace with constant
- [ ] Replace with new instruction
- [ ] replace with evaluation like
(add $x#const $y#const) -> eval($x + $y)
- [x] Constants
There is a problem with the replacement and I am not sure if its relevant or how we could handle it.
If I have this expression: (sub {lhs:(add $x $y)} $y) -> $x that matches and replace the sub-instruction with the value of $y. But if the value is a constant it cannot be replaced, because constants are no valid instructions therefor there forbidden in the root level of a basic block. The ReplaceWith method cannot handle non Instruction values https://github.com/dubiousconst282/DistIL/blob/018b1bdcbc70dd30424dad367245ca3d951cb556/src/DistIL/IR/Instruction.cs#L72
If I run the pattern it deletes the binary instruction. I had the idea to replace it with an + 0 but this wouldn't be optimal. Should we disallow this or do you have other ideas?
You can use ReplaceUses() instead of ReplaceWith() to replace uses of the instruction and keep it in the block, constants still derive from Value and they will be handed correctly. To avoid leaving unused instructions behind, I suggest adding a small check like if (inst.NumUses == 0) inst.Remove().
Closes #20