tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

tail-fold.tri (3582B)


      1 !import prelude *
      2 !import consumers_structural as S
      3 !import consumers_lowerings_specialize as P
      4 !export *
      5 -- Experimental tricu-owned lowering for two-rule list consumers.
      6 -- Reject unsupported input shapes rather than changing their semantics.
      7 
      8 leafRule rule = matchPair (input more : matchPair (state output :
      9   matchPair (tag payload : lazyBool (_ : just (pair state output))
     10     (_ : nothing) (equal? tag 1)) input) more) rule
     11 consRule rule = matchPair (input more : matchPair (state output :
     12   matchPair (tag children : lazyBool (_ : matchPair (left right :
     13     matchPair (leftTag leftSlot : matchPair (rightTag rightSlot :
     14       lazyBool (_ : just (pair (pair leftSlot rightSlot) (pair state output)))
     15         (_ : nothing) (and? (equal? leftTag 4) (equal? rightTag 4))) right) left) children)
     16     (_ : nothing) (equal? tag 3)) input) more) rule
     17 
     18 -- Inputs are disjoint, so rule order cannot affect this accepted fragment.
     19 classify first second = (lazyMaybe (_ : lazyMaybe (_ : nothing) (cons : lazyMaybe (_ : nothing)
     20     (leaf : just (pair leaf cons)) (leafRule second)) (consRule first))
     21   (leaf : lazyMaybe (_ : nothing) (cons : just (pair leaf cons)) (consRule second))
     22   (leafRule first))
     23 
     24 compileLeaf statePattern output = (state recur invoke : lazyMaybe (_ : err "no matching consumer rule" t) (bindings : (P.indexedOutput output (P.patternSlots statePattern t)) bindings recur invoke) ((P.indexedPattern statePattern) state t))
     25 compileCons slots statePattern output = (byte rest state recur invoke : matchPair (byteSlot restSlot : lazyMaybe (_ : err "no matching consumer rule" t) (bindings : (P.indexedOutput output (P.patternSlots statePattern (pair restSlot (pair byteSlot t)))) bindings recur invoke) ((P.indexedPattern statePattern) state (pair rest (pair byte t)))) slots)
     26 compileBranches branches = matchPair (leaf cons : matchPair
     27   (leafState leafOutput : matchPair (slots more : matchPair
     28     (consState consOutput : pair (compileLeaf leafState leafOutput)
     29       (compileCons slots consState consOutput)) more) cons) leaf) branches
     30 
     31 -- The only per-byte input dispatch is the actual list constructor. The two
     32 -- rule functions are prepared before runtime recursion, not parsed per byte.
     33 loop_ self input state leaf cons = ((selected : selected t) (triage
     34   (_ : leaf state
     35     (nextInput nextState : self nextInput nextState leaf cons)
     36     (worker argument initial : y P.runDirect_ argument worker initial))
     37   (child : _ : err "no matching consumer rule" t)
     38   (byte rest : _ : cons byte rest state
     39     (nextInput nextState : self nextInput nextState leaf cons)
     40     (worker argument initial : y P.runDirect_ argument worker initial)) input))
     41 run program input = matchPair (initial branches : matchPair (leaf cons :
     42   y loop_ input initial leaf cons) branches) program
     43 -- Compatible with runDirect's (initial, step) protocol. Once invoked, the
     44 -- fixed-point loop handles its own recurrence, not runDirect's recur callback.
     45 asDirect program = matchPair (initial branches : matchPair (leaf cons :
     46   S.makeConsumer initial (input state recur invoke : y loop_ input state leaf cons)) branches) program
     47 compile consumer = (lazyList (_ : err "tail-fold requires exactly two rules" t) (first rest : lazyList (_ : err "tail-fold requires exactly two rules" t)
     48     (second extra : lazyList (_ : lazyMaybe
     49       (_ : err "tail-fold requires leaf and captured cons rules" t)
     50       (branches : ok (pair (fst consumer) (compileBranches branches)) t)
     51       (classify first second))
     52       (_ _ : err "tail-fold requires exactly two rules" t) extra) rest)
     53   (snd consumer))