consumer_specialize_patterns.tri (3177B)
1 -- The tricu-authored matcher preparation must preserve all IR pattern tags. 2 !import "consumers.structural" S 3 !import "consumers.lowerings.specialize" P 4 !import "prelude" !Local 5 same pattern value = and? (equal? (S.matchPattern pattern value t) ((P.compiledPattern pattern) value t)) (equal? (lazyMaybe (_ : nothing) (bindings : just (map snd bindings)) (S.matchPattern pattern value t)) (P.indexedPattern pattern value t)) 6 allChecks = foldl and? true [(same S.patAny [1 2]) 7 (same S.patLeaf t) 8 (same S.patLeaf (t t)) 9 (same (S.patStem (S.patCapture 0)) (t 9)) 10 (same (S.patStem S.patLeaf) (t (t t))) 11 (same (S.patFork (S.patCapture 0) (S.patCapture 1)) (pair 1 2)) 12 (same (S.patFork (S.patLiteral 1) (S.patCapture 2)) (pair 2 3)) 13 (same (S.patAs 0 (S.patFork S.patAny (S.patCapture 1))) (pair 3 4)) 14 (same (S.patAs 0 S.patLeaf) (t t)) 15 (same (resultOr t (S.expandPrefix "/api/" 0)) "/api/item") 16 (same (resultOr t (S.expandPrefix "/api/" 0)) "/apix/item") 17 (same (resultOr t (S.expandPrefix "/api/" 0)) "/api/")] 18 -- Direct rule lowering must preserve first-match order, failed-state 19 -- fallthrough, fresh bindings on fallback, lazy branches, and Result errors. 20 rule input state output = S.makeRule input state output 21 runSame program input expected = foldl and? true [(equal? (S.runConsumer program input) expected) 22 (equal? (P.runFull (P.prepareFully program) input) expected) 23 (equal? (P.runDirect (P.compileDirect program) input) expected) 24 (equal? (P.runDirect (P.compileIndexed program) input) expected)] 25 firstMatch = S.makeConsumer t [(rule S.patAny S.patAny (S.outLiteral 1)) (rule S.patAny S.patAny (S.outLiteral 2))] 26 stateFallback = S.makeConsumer t [(rule (S.patCapture 0) (S.patLiteral 9) (S.outCapture 0)) (rule S.patAny S.patAny (S.outCapture 0))] 27 directChecks = foldl and? true [(runSame firstMatch 8 (ok 1 t)) 28 (runSame stateFallback 8 (err "unknown capture" t)) 29 (runSame (S.makeConsumer t t) 8 (err "no matching consumer rule" t)) 30 (runSame (S.makeConsumer t [(rule S.patAny S.patAny (pair 99 t))]) 8 (err "unknown output form" t))] 31 boundRun program state input = bindResult (P.compileBound program state) (compiled _ : P.runDirect compiled input) 32 boundExample = S.makeConsumer t [(rule (S.patCapture 0) (S.patCapture 1) (S.outFork (S.outCapture 0) (S.outCapture 1)))] 33 shadowExample = S.makeConsumer t [(rule (S.patCapture 0) (S.patCapture 0) (S.outCapture 0))] 34 identityWorker = P.compileIndexed (S.makeConsumer t [(rule (S.patCapture 0) S.patAny (S.outCapture 0))]) 35 callShadow = S.makeConsumer t [(rule S.patAny (S.patCapture 0) (S.outCall (S.outLiteral identityWorker) (S.outLiteral 7) 0 (S.outCapture 0)))] 36 recurrent = S.makeConsumer t [(rule S.patAny S.patAny (S.outRecur (S.outLiteral t) (S.outLiteral t)))] 37 boundChecks = foldl and? true [(equal? (boundRun boundExample 91 7) (ok (pair 7 91) t)) 38 (equal? (boundRun shadowExample 91 7) (ok 91 t)) 39 (equal? (boundRun callShadow 91 8) (ok 7 t)) 40 (equal? (P.compileBound recurrent t) (err "cannot bind state of recurrent consumer" t))] 41 main = matchBool "scp-prepared-patterns-ok" "scp-prepared-patterns-DIFFER" (foldl and? true [allChecks directChecks boundChecks]) 42 main