specialize.tri (15782B)
1 !import prelude * 2 !import consumers_structural as S 3 !import consumers_pattern_slots as Slots 4 !export * 5 -- Bounded tricu-authored staging: prepareConsumer compiles patterns; 6 -- prepareFully also compiles output templates; compileDirect additionally 7 -- lowers the finite rule list to executable first-match branches. 8 -- Capture lookup, Result plumbing and dynamic invocation remain at runtime. 9 -- Keep authored IR separately; executable representations are not interchangeable. 10 11 compiledStem inner value bindings = triage nothing (subtree : inner subtree bindings) (_ _ : nothing) value 12 compiledFork first second value bindings = triage nothing (_ : nothing) (leftValue rightValue : lazyMaybe (_ : nothing) (leftBindings : second rightValue leftBindings) (first leftValue bindings)) value 13 compiledAs inner slot value bindings = 14 inner value (pair (pair slot value) bindings) 15 16 compiledPattern_ self pattern = matchPair (tag payload : 17 lazyBool (_ : value bindings : just bindings) 18 (_ : lazyBool 19 (_ : value bindings : triage (just bindings) (_ : nothing) 20 (_ _ : nothing) value) 21 (_ : lazyBool 22 (_ : compiledStem (self payload)) 23 (_ : lazyBool 24 (_ : matchPair (left right : 25 compiledFork (self left) (self right)) payload) 26 (_ : lazyBool 27 (_ : value bindings : just (pair (pair payload value) bindings)) 28 (_ : lazyBool 29 (_ : value bindings : lazyBool (_ : just bindings) 30 (_ : nothing) (equal? payload value)) 31 (_ : lazyBool 32 (_ : matchPair (slot child : compiledAs (self child) slot) payload) 33 (_ : value bindings : nothing) 34 (equal? tag 6)) 35 (equal? tag 5)) 36 (equal? tag 4)) 37 (equal? tag 3)) 38 (equal? tag 2)) 39 (equal? tag 1)) 40 (equal? tag 0)) pattern 41 compiledPattern pattern = y compiledPattern_ pattern 42 43 compiledRule rule = matchPair (inputPattern more : matchPair 44 (statePattern output : pair (compiledPattern inputPattern) 45 (pair (compiledPattern statePattern) output)) more) rule 46 prepareConsumer consumer = S.makeConsumer (fst consumer) (map compiledRule (snd consumer)) 47 48 choosePrepared_ self rules input state = 49 lazyList (_ : nothing) 50 (rule rest : matchPair (inputMatcher more : matchPair 51 (stateMatcher output : lazyMaybe 52 (_ : self rest input state) 53 (inputBindings : lazyMaybe 54 (_ : self rest input state) 55 (bindings : just (pair output bindings)) 56 (stateMatcher state inputBindings)) 57 (inputMatcher input t)) more) rule) 58 rules 59 choosePrepared rules input state = y choosePrepared_ rules input state 60 61 runPrepared_ self input program state = 62 lazyMaybe (_ : err "no matching consumer rule" t) 63 (selected : matchPair (output bindings : 64 S.evalOutput output bindings 65 (nextInput nextState : self nextInput program nextState) 66 (worker argument initial : self argument worker initial)) selected) 67 (choosePrepared (snd program) input state) 68 runPrepared program input = y runPrepared_ input program (fst program) 69 70 -- Second stage: compile output-template tags and child traversal as well. 71 -- Results, dynamic workers, capture lookup and the host reducer are unchanged. 72 compiledForkOutput left right bindings recur invoke = 73 bindResult (left bindings recur invoke) (leftValue _ : 74 bindResult (right bindings recur invoke) (rightValue _ : 75 ok (pair leftValue rightValue) t)) 76 compiledStemOutput child bindings recur invoke = 77 bindResult (child bindings recur invoke) (value _ : ok (t value) t) 78 compiledRecurOutput input state bindings recur invoke = 79 bindResult (input bindings recur invoke) (nextInput _ : 80 bindResult (state bindings recur invoke) (nextState _ : 81 recur nextInput nextState)) 82 compiledCallOutput worker input returnSlot receiver bindings recur invoke = 83 bindResult (worker bindings recur invoke) (workerValue _ : 84 bindResult (input bindings recur invoke) (argument _ : 85 bindResult (invoke workerValue argument (fst workerValue)) (returned _ : 86 receiver (pair (pair returnSlot returned) bindings) recur invoke))) 87 compiledBecomeOutput worker input state bindings recur invoke = 88 bindResult (worker bindings recur invoke) (target _ : 89 bindResult (input bindings recur invoke) (argument _ : 90 bindResult (state bindings recur invoke) (initial _ : 91 invoke target argument initial))) 92 compiledEqualOutput left right bindings recur invoke = 93 bindResult (left bindings recur invoke) (a _ : 94 bindResult (right bindings recur invoke) (b _ : ok (equal? a b) t)) 95 compiledOutput_ self output = matchPair (tag payload : 96 lazyBool (_ : bindings recur invoke : ok payload t) 97 (_ : lazyBool 98 (_ : bindings recur invoke : S.capture bindings payload) 99 (_ : lazyBool 100 (_ : matchPair (left right : 101 compiledForkOutput (self left) (self right)) payload) 102 (_ : lazyBool 103 (_ : matchPair (input state : 104 compiledRecurOutput (self input) (self state)) payload) 105 (_ : lazyBool 106 (_ : matchPair (worker more : matchPair (input continuation : 107 matchPair (returnSlot receiver : 108 compiledCallOutput (self worker) (self input) returnSlot 109 (self receiver)) continuation) more) payload) 110 (_ : lazyBool 111 (_ : compiledStemOutput (self payload)) 112 (_ : lazyBool 113 (_ : matchPair (worker more : matchPair (input state : 114 compiledBecomeOutput (self worker) (self input) 115 (self state)) more) payload) 116 (_ : lazyBool 117 (_ : matchPair (left right : 118 compiledEqualOutput (self left) (self right)) payload) 119 (_ : bindings recur invoke : err "unknown output form" t) 120 (equal? tag 8)) 121 (equal? tag 6)) 122 (equal? tag 5)) 123 (equal? tag 4)) 124 (equal? tag 3)) 125 (equal? tag 2)) 126 (equal? tag 1)) 127 (equal? tag 0)) output 128 compiledOutput output = y compiledOutput_ output 129 130 compiledFullRule rule = matchPair (inputPattern more : matchPair 131 (statePattern output : pair (compiledPattern inputPattern) 132 (pair (compiledPattern statePattern) (compiledOutput output))) more) rule 133 prepareFully consumer = S.makeConsumer (fst consumer) (map compiledFullRule (snd consumer)) 134 135 runFull_ self input program state = 136 lazyMaybe (_ : err "no matching consumer rule" t) 137 (selected : matchPair (output bindings : output bindings 138 (nextInput nextState : self nextInput program nextState) 139 (worker argument initial : self argument worker initial)) selected) 140 (choosePrepared (snd program) input state) 141 runFull program input = y runFull_ input program (fst program) 142 143 -- A bounded further lowering for known consumers: turn the finite rule list 144 -- into executable first-match branches. Runtime data still selects branches; 145 -- there is no rule-list walk or pattern/template tag traversal per call. 146 -- Dynamic workers must themselves be compiled with compileDirect. 147 directBranch inputMatcher stateMatcher output fallback input state recur invoke = 148 lazyMaybe (_ : fallback input state recur invoke) 149 (inputBindings : lazyMaybe (_ : fallback input state recur invoke) 150 (bindings : output bindings recur invoke) 151 (stateMatcher state inputBindings)) 152 (inputMatcher input t) 153 compileDirectRules_ self rules = 154 lazyList (_ : input state recur invoke : err "no matching consumer rule" t) 155 (rule rest : matchPair (inputPattern more : matchPair 156 (statePattern output : directBranch (compiledPattern inputPattern) 157 (compiledPattern statePattern) (compiledOutput output) 158 (self rest)) more) rule) 159 rules 160 compileDirectRules rules = y compileDirectRules_ rules 161 compileDirect program = S.makeConsumer (fst program) (compileDirectRules (snd program)) 162 runDirect_ self input program state = (snd program) input state (nextInput nextState : self nextInput program nextState) (worker argument initial : self argument worker initial) 163 runDirect program input = y runDirect_ input program (fst program) 164 165 166 -- Indexed matchers retain values only, in the same capture order. 167 indexedAs inner value bindings = inner value (pair value bindings) 168 indexedPattern_ self pattern = matchPair (tag payload : 169 lazyBool (_ : value bindings : just bindings) 170 (_ : lazyBool 171 (_ : value bindings : triage (just bindings) (_ : nothing) 172 (_ _ : nothing) value) 173 (_ : lazyBool 174 (_ : compiledStem (self payload)) 175 (_ : lazyBool 176 (_ : matchPair (left right : 177 compiledFork (self left) (self right)) payload) 178 (_ : lazyBool 179 (_ : value bindings : just (pair value bindings)) 180 (_ : lazyBool 181 (_ : value bindings : lazyBool (_ : just bindings) 182 (_ : nothing) (equal? payload value)) 183 (_ : lazyBool 184 (_ : matchPair (slot child : indexedAs (self child)) payload) 185 (_ : value bindings : nothing) 186 (equal? tag 6)) 187 (equal? tag 5)) 188 (equal? tag 4)) 189 (equal? tag 3)) 190 (equal? tag 2)) 191 (equal? tag 1)) 192 (equal? tag 0)) pattern 193 indexedPattern pattern = y indexedPattern_ pattern 194 indexedCallOutput worker input returnSlot receiver bindings recur invoke = bindResult (worker bindings recur invoke) (workerValue _ : bindResult (input bindings recur invoke) (argument _ : bindResult (invoke workerValue argument (fst workerValue)) (returned _ : receiver (pair returned bindings) recur invoke))) 195 196 -- Slot names are static. Compile their search into finite binding projections. 197 -- Matchers build value lists, without runtime slot/value pairs. Missing slots 198 -- retain the original Result error. 199 indexedHead bindings = ok (fst bindings) t 200 indexedTail next bindings = next (snd bindings) 201 indexedCapture_ self slots slot = lazyList (_ : bindings : err "unknown capture" t) (name rest : lazyBool (_ : indexedHead) (_ : indexedTail (self rest slot)) (equal? name slot)) slots 202 indexedCapture slots slot bindings = y indexedCapture_ slots slot bindings 203 -- Compatibility entry point for the indexed-lowering experiments. 204 patternSlots pattern slots = Slots.patternSlots pattern slots 205 -- Literal workers are already executable direct/indexed consumers. Link their 206 -- application here instead of routing through the runtime invoke argument. 207 linkedCall worker input slot receiver bindings recur invoke = bindResult (input bindings recur invoke) (argument _ : bindResult (runDirect worker argument) (returned _ : receiver (pair returned bindings) recur invoke)) 208 linkedBecome worker input state bindings recur invoke = bindResult (input bindings recur invoke) (argument _ : bindResult (state bindings recur invoke) (initial _ : y runDirect_ argument worker initial)) 209 indexedOutput_ self output slots = matchPair (tag payload : 210 lazyBool (_ : bindings recur invoke : ok payload t) 211 (_ : lazyBool 212 (_ : bindings recur invoke : indexedCapture slots payload bindings) 213 (_ : lazyBool 214 (_ : matchPair (left right : 215 compiledForkOutput (self left slots) (self right slots)) payload) 216 (_ : lazyBool 217 (_ : matchPair (input state : 218 compiledRecurOutput (self input slots) (self state slots)) payload) 219 (_ : lazyBool 220 (_ : matchPair (worker more : matchPair (input continuation : 221 matchPair (returnSlot receiver : 222 lazyBool (_ : linkedCall (snd worker) (self input slots) returnSlot (self receiver (pair returnSlot slots))) 223 (_ : indexedCallOutput (self worker slots) (self input slots) returnSlot (self receiver (pair returnSlot slots))) (equal? (fst worker) 0)) continuation) more) payload) 224 (_ : lazyBool 225 (_ : compiledStemOutput (self payload slots)) 226 (_ : lazyBool 227 (_ : matchPair (worker more : matchPair (input state : 228 lazyBool (_ : linkedBecome (snd worker) (self input slots) (self state slots)) 229 (_ : compiledBecomeOutput (self worker slots) (self input slots) (self state slots)) (equal? (fst worker) 0)) more) payload) 230 (_ : lazyBool 231 (_ : matchPair (left right : 232 compiledEqualOutput (self left slots) (self right slots)) payload) 233 (_ : bindings recur invoke : err "unknown output form" t) 234 (equal? tag 8)) 235 (equal? tag 6)) 236 (equal? tag 5)) 237 (equal? tag 4)) 238 (equal? tag 3)) 239 (equal? tag 2)) 240 (equal? tag 1)) 241 (equal? tag 0)) output 242 indexedOutput output slots = y indexedOutput_ output slots 243 compileIndexedRules_ self rules = lazyList (_ : input state recur invoke : err "no matching consumer rule" t) (rule rest : matchPair (inputPattern more : matchPair (statePattern output : 244 directBranch (indexedPattern inputPattern) (indexedPattern statePattern) 245 (indexedOutput output (patternSlots statePattern (patternSlots inputPattern t))) 246 (self rest)) more) rule) rules 247 compileIndexed program = S.makeConsumer (fst program) (y compileIndexedRules_ (snd program)) 248 249 -- Bind a known initial state only for non-recurrent consumers. Recur would 250 -- invalidate the static-state assumption, so reject it rather than miscompile. 251 withoutSlot_ self bindings slot = lazyList (_ : t) (entry rest : lazyBool (_ : self rest slot) (_ : pair entry (self rest slot)) (equal? (fst entry) slot)) bindings 252 withoutSlot bindings slot = y withoutSlot_ bindings slot 253 bindOutput_ self output bindings = matchPair (tag payload : 254 lazyBool (_ : ok output t) 255 (_ : lazyBool (_ : lazyResult (_ _ : ok output t) (value _ : ok (S.outLiteral value) t) (S.capture bindings payload)) 256 (_ : lazyBool (_ : matchPair (left right : bindResult (self left bindings) (a _ : bindResult (self right bindings) (b _ : ok (S.outFork a b) t))) payload) 257 (_ : lazyBool (_ : err "cannot bind state of recurrent consumer" t) 258 (_ : lazyBool (_ : matchPair (worker more : matchPair (input continuation : matchPair (slot receiver : bindResult (self worker bindings) (w _ : bindResult (self input bindings) (i _ : bindResult (self receiver (withoutSlot bindings slot)) (r _ : ok (S.outCall w i slot r) t)))) continuation) more) payload) 259 (_ : lazyBool (_ : bindResult (self payload bindings) (child _ : ok (S.outStem child) t)) 260 (_ : lazyBool (_ : matchPair (worker more : matchPair (input state : bindResult (self worker bindings) (w _ : bindResult (self input bindings) (i _ : bindResult (self state bindings) (s _ : ok (S.outBecome w i s) t)))) more) payload) 261 (_ : lazyBool (_ : matchPair (left right : bindResult (self left bindings) (a _ : bindResult (self right bindings) (b _ : ok (S.outEqual a b) t))) payload) 262 (_ : ok output t) (equal? tag 8)) (equal? tag 6)) (equal? tag 5)) (equal? tag 4)) (equal? tag 3)) (equal? tag 2)) (equal? tag 1)) (equal? tag 0)) output 263 bindOutput output bindings = y bindOutput_ output bindings 264 bindRules_ self rules state = lazyList (_ : ok t t) (rule rest : matchPair (inputPattern more : matchPair (statePattern output : 265 lazyMaybe (_ : self rest state) 266 (bindings : bindResult (bindOutput output bindings) (bound _ : bindResult (self rest state) (tail _ : ok (pair (S.makeRule inputPattern S.patAny bound) tail) t))) 267 (S.matchPattern statePattern state t)) more) rule) rules 268 bindState program state = bindResult (y bindRules_ (snd program) state) (rules _ : ok (S.makeConsumer t rules) t) 269 compileBound program state = bindResult (bindState program state) (bound _ : ok (compileIndexed bound) t)