structural.tri (11500B)
1 !import prelude * 2 !export * 3 -- Shared SCP authored IR and independent reference semantics. 4 5 -- Pattern tags: Any, Leaf, Stem, Fork, Capture, Literal, As. Capture slots are unique 6 -- within a rule; repetition/unification is deliberately not implemented. 7 patAny = pair 0 t 8 patLeaf = pair 1 t 9 patStem child = pair 2 child 10 patFork left right = pair 3 (pair left right) 11 patCapture slot = pair 4 slot 12 patLiteral value = pair 5 value 13 patAs slot child = pair 6 (pair slot child) 14 -- Build-time elaboration, NOT an IR tag. A proper list expands into nested 15 -- Fork/Literal patterns ending in a suffix Capture. Reject an improper list 16 -- before publishing IR; do not manufacture an invalid pattern as a sentinel. 17 expandPrefix_ self prefix slot = (triage 18 (ok (patCapture slot) t) 19 (_ : err "improper literal prefix" t) 20 (head rest : bindResult (self rest slot) 21 (tailPattern _ : ok (patFork (patLiteral head) tailPattern) t)) 22 prefix) 23 expandPrefix prefix slot = y expandPrefix_ prefix slot 24 25 -- Template tags: Literal (opaque), Capture, Fork, Recur, Call, Stem. 26 -- Recur continues this consumer; Call invokes a runtime-supplied consumer 27 -- and binds its result to an explicit return slot for a receiver template. 28 outLiteral value = pair 0 value 29 outCapture slot = pair 1 slot 30 outFork left right = pair 2 (pair left right) 31 outRecur input state = pair 3 (pair input state) 32 outCall worker input returnSlot receiver = 33 pair 4 (pair worker (pair input (pair returnSlot receiver))) 34 outStem child = pair 5 child 35 -- Tail delegation to any runtime-supplied consumer with explicit state. 36 outBecome worker input state = pair 6 (pair worker (pair input state)) 37 -- Intensional structural equality is a general tree operation, not a route helper. 38 outEqual left right = pair 8 (pair left right) 39 -- Match a computed tree against ordered, scoped pattern/output arms. 40 outMatch source arms = pair 9 (pair source arms) 41 42 makeRule inputPattern statePattern output = 43 pair inputPattern (pair statePattern output) 44 makeConsumer state rules = pair state rules 45 46 matchPattern_ self pattern value bindings = 47 matchPair (tag payload : 48 lazyBool 49 (_ : just bindings) 50 (_ : lazyBool 51 (_ : triage (just bindings) (_ : nothing) (_ _ : nothing) value) 52 (_ : lazyBool 53 (_ : triage nothing (child : self payload child bindings) 54 (_ _ : nothing) value) 55 (_ : lazyBool 56 (_ : matchPair (left right : 57 triage nothing (_ : nothing) 58 (leftValue rightValue : 59 lazyMaybe 60 (_ : nothing) 61 (leftBindings : self right rightValue leftBindings) 62 (self left leftValue bindings)) 63 value) payload) 64 (_ : lazyBool 65 (_ : just (pair (pair payload value) bindings)) 66 (_ : lazyBool 67 (_ : lazyBool (_ : just bindings) (_ : nothing) 68 (equal? payload value)) 69 (_ : lazyBool 70 (_ : matchPair (slot child : 71 self child value (pair (pair slot value) bindings)) payload) 72 (_ : nothing) 73 (equal? tag 6)) 74 (equal? tag 5)) 75 (equal? tag 4)) 76 (equal? tag 3)) 77 (equal? tag 2)) 78 (equal? tag 1)) 79 (equal? tag 0)) 80 pattern 81 matchPattern pattern value bindings = y matchPattern_ pattern value bindings 82 83 matchRule rule input state = 84 matchPair (inputPattern more : 85 matchPair (statePattern output : 86 lazyMaybe 87 (_ : nothing) 88 (inputBindings : 89 lazyMaybe 90 (_ : nothing) 91 (bindings : just (pair output bindings)) 92 (matchPattern statePattern state inputBindings)) 93 (matchPattern inputPattern input t)) 94 more) 95 rule 96 97 chooseRule_ self rules input state = 98 lazyList 99 (_ : nothing) 100 (rule rest : 101 lazyMaybe 102 (_ : self rest input state) 103 (selection : just selection) 104 (matchRule rule input state)) 105 rules 106 chooseRule rules input state = y chooseRule_ rules input state 107 108 capture_ self bindings slot = 109 lazyList 110 (_ : err "unknown capture" t) 111 (entry rest : 112 lazyBool 113 (_ : ok (snd entry) t) 114 (_ : self rest slot) 115 (equal? (fst entry) slot)) 116 bindings 117 capture bindings slot = y capture_ bindings slot 118 119 -- The interpreter's continuation is a tricu value, not a new host action. 120 -- All recursive template work is under the template's consumed structure. 121 matchOutputArms_ self output arms value bindings recur invoke = (lazyList 122 (_ : err "no matching output arm" t) 123 (arm rest : matchPair (pattern body : lazyMaybe 124 (_ : self output rest value bindings recur invoke) 125 (matched : output body matched recur invoke) 126 (matchPattern pattern value bindings)) arm) arms) 127 matchOutputArms output arms value bindings recur invoke = 128 y matchOutputArms_ output arms value bindings recur invoke 129 130 evalOutput_ self output bindings recur invoke initial = 131 matchPair (tag payload : 132 lazyBool 133 (_ : ok payload t) 134 (_ : lazyBool 135 (_ : capture bindings payload) 136 (_ : lazyBool 137 (_ : matchPair (left right : 138 bindResult (self left bindings recur invoke initial) (leftValue _ : 139 bindResult (self right bindings recur invoke initial) (rightValue _ : 140 ok (pair leftValue rightValue) t))) payload) 141 (_ : lazyBool 142 (_ : matchPair (input state : 143 bindResult (self input bindings recur invoke initial) (nextInput _ : 144 bindResult (self state bindings recur invoke initial) (nextState _ : 145 recur nextInput nextState))) payload) 146 (_ : lazyBool 147 (_ : matchPair (worker more : 148 matchPair (input continuation : 149 matchPair (returnSlot receiver : 150 bindResult (self worker bindings recur invoke initial) (workerValue _ : 151 bindResult (self input bindings recur invoke initial) (argument _ : 152 bindResult (invoke workerValue argument (initial workerValue)) (returned _ : 153 self receiver 154 (pair (pair returnSlot returned) bindings) 155 recur invoke initial)))) 156 continuation) more) payload) 157 (_ : lazyBool 158 (_ : bindResult (self payload bindings recur invoke initial) 159 (child _ : ok (t child) t)) 160 (_ : lazyBool 161 (_ : matchPair (worker more : matchPair (input state : 162 bindResult (self worker bindings recur invoke initial) (target _ : 163 bindResult (self input bindings recur invoke initial) (argument _ : 164 bindResult (self state bindings recur invoke initial) (newState _ : 165 invoke target argument newState)))) more) payload) 166 (_ : lazyBool 167 (_ : matchPair (left right : 168 bindResult (self left bindings recur invoke initial) (a _ : 169 bindResult (self right bindings recur invoke initial) (b _ : 170 ok (equal? a b) t))) payload) 171 (_ : lazyBool 172 (_ : matchPair (source arms : 173 bindResult (self source bindings recur invoke initial) 174 (value _ : matchOutputArms 175 (child bound recurrence invocation : 176 self child bound recurrence invocation initial) 177 arms value bindings recur invoke)) payload) 178 (_ : err "unknown output form" t) 179 (equal? tag 9)) 180 (equal? tag 8)) 181 (equal? tag 6)) 182 (equal? tag 5)) 183 (equal? tag 4)) 184 (equal? tag 3)) 185 (equal? tag 2)) 186 (equal? tag 1)) 187 (equal? tag 0)) 188 output 189 evalOutputUsing output bindings recur invoke initial = 190 y evalOutput_ output bindings recur invoke initial 191 evalOutput output bindings recur invoke = 192 evalOutputUsing output bindings recur invoke fst 193 194 runConsumer_ self input consumer state = 195 lazyMaybe 196 (_ : err "no matching consumer rule" t) 197 (selection : 198 matchPair (output bindings : 199 evalOutput output bindings 200 (nextInput nextState : self nextInput consumer nextState) 201 (worker argument initial : self argument worker initial)) 202 selection) 203 (chooseRule (snd consumer) input state) 204 runConsumer consumer input = y runConsumer_ input consumer (fst consumer) 205 206 -- Transform only designated output literals. Never descend into their 207 -- arbitrary payloads, captured input values, or structural patterns. 208 replaceOutputLiteral_ self output old replacement = 209 matchPair (tag payload : 210 lazyBool 211 (_ : outLiteral (lazyBool (_ : replacement) (_ : payload) 212 (equal? payload old))) 213 (_ : lazyBool 214 (_ : output) 215 (_ : lazyBool 216 (_ : matchPair (left right : 217 outFork (self left old replacement) (self right old replacement)) 218 payload) 219 (_ : lazyBool 220 (_ : matchPair (input state : 221 outRecur (self input old replacement) (self state old replacement)) 222 payload) 223 (_ : lazyBool 224 (_ : matchPair (worker more : 225 matchPair (input continuation : 226 matchPair (returnSlot receiver : 227 outCall (self worker old replacement) 228 (self input old replacement) returnSlot 229 (self receiver old replacement)) continuation) 230 more) payload) 231 (_ : lazyBool 232 (_ : outStem (self payload old replacement)) 233 (_ : lazyBool 234 (_ : matchPair (worker more : matchPair (input state : 235 outBecome (self worker old replacement) 236 (self input old replacement) 237 (self state old replacement)) more) payload) 238 (_ : lazyBool 239 (_ : matchPair (left right : 240 outEqual (self left old replacement) 241 (self right old replacement)) payload) 242 (_ : lazyBool 243 (_ : matchPair (source arms : 244 outMatch (self source old replacement) 245 (map (arm : matchPair (pattern body : 246 pair pattern (self body old replacement)) arm) 247 arms)) payload) 248 (_ : output) 249 (equal? tag 9)) 250 (equal? tag 8)) 251 (equal? tag 6)) 252 (equal? tag 5)) 253 (equal? tag 4)) 254 (equal? tag 3)) 255 (equal? tag 2)) 256 (equal? tag 1)) 257 (equal? tag 0)) 258 output 259 replaceOutputLiteral output old replacement = 260 y replaceOutputLiteral_ output old replacement 261 262 replaceRuleLiteral rule old replacement = 263 matchPair (inputPattern more : 264 matchPair (statePattern output : 265 makeRule inputPattern statePattern 266 (replaceOutputLiteral output old replacement)) more) rule 267 replaceLiteral consumer old replacement = 268 makeConsumer (fst consumer) (map (rule : replaceRuleLiteral rule old replacement) (snd consumer))