This latest refactor adds "extractor macros" in place of the very-confusing-even-to-the-DSL-author reverse-rules-as-extractors concept. It was beautifully symmetric but also just too mind-bending to be practical. It also adds argument polarity to external extractors. This is inspired by Prolog's similar notion (see e.g. the "+x" vs. "-x" argument notation in library documentation) where the unification-based semantics allow for bidirectional flow through arguments. We don't want polymorphism or dynamism w.r.t. directions/polarities here; the polarities are static; but it is useful to be able to feed values *into* an extractor (aside from the one value being extracted). Semantically this still correlates to a term-rewriting/value-equivalence world since we can still translate all of this to a list of equality constraints. To make that work, this change also adds expressions into patterns, specifically only for extractor "input" args. This required quite a bit of internal refactoring but is only a small addition to the language semantics. I plan to build out the little instruction-selector sketch further but the one that is here (in `test3.isle`) is starting to get interesting already with the current DSL semantics.
22 lines
414 B
Common Lisp
22 lines
414 B
Common Lisp
(type u32 (primitive u32))
|
|
(type A (enum (A1 (x u32)) (A2 (x u32))))
|
|
(type B (enum (B1 (x u32)) (B2 (x u32))))
|
|
|
|
(decl Input (A) u32)
|
|
(extern extractor Input get_input) ;; fn get_input<C>(ctx: &mut C, ret: u32) -> Option<(A,)>
|
|
|
|
(decl Lower (A) B)
|
|
|
|
(rule
|
|
(Lower (A.A1 sub @ (Input (A.A2 42))))
|
|
(B.B2 sub))
|
|
|
|
(decl Extractor (B) A)
|
|
(extractor
|
|
(Extractor x)
|
|
(A.A2 x))
|
|
|
|
(rule
|
|
(Lower (Extractor b))
|
|
(B.B1 b))
|