tricu

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

layout.tri (4150B)


      1 !import prelude *
      2 !import source_lexer as L
      3 !import consumers_structural as SCP
      4 !export *
      5 -- Reusable authored layout transition over located source tokens.
      6 -- Entry points: layoutConsumer committed, layout, layoutWithCommit, renamedLayout.
      7 -- State is (afterNewlines?, committed?); replies use the parser protocol.
      8 -- This constructs inspectable SCP data, not a source frontend or deployment API.
      9 
     10 -- Reply/diagnostic trees follow lib/parser.tri exactly. These builders are
     11 -- template constructors; they never interpret a token or invoke a host API.
     12 replySuccess value rest consumed committed =
     13   SCP.outFork (SCP.outLiteral true) (SCP.outFork value (SCP.outFork rest
     14     (SCP.outFork (SCP.outLiteral consumed) committed)))
     15 replyFailure diagnostic rest consumed committed =
     16   SCP.outFork (SCP.outLiteral false) (SCP.outFork diagnostic (SCP.outFork rest
     17     (SCP.outFork (SCP.outLiteral consumed) committed)))
     18 diagnostic code expected found location =
     19   SCP.outFork (SCP.outLiteral code) (SCP.outFork expected (SCP.outFork found
     20     (SCP.outFork location (SCP.outLiteral t))))
     21 expectedName found location =
     22   diagnostic 2 (SCP.outLiteral L.sourceTokenName) found location
     23 
     24 -- `As` retains the entire located token as a capture while its nested
     25 -- pattern inspects the kind and, for the indented branch, its column.
     26 nameAtColumn column =
     27   SCP.patFork (SCP.patLiteral L.sourceTokenName) (SCP.patFork SCP.patAny
     28     (SCP.patFork
     29       (SCP.patFork SCP.patAny (SCP.patFork column SCP.patAny))
     30       SCP.patAny))
     31 nameAny = SCP.patFork (SCP.patLiteral L.sourceTokenName) SCP.patAny
     32 newline = SCP.patFork (SCP.patLiteral L.sourceTokenNewline) SCP.patAny
     33 anyToken = SCP.patFork (SCP.patCapture 3) (SCP.patFork SCP.patAny
     34   (SCP.patFork (SCP.patCapture 4) SCP.patAny))
     35 
     36 -- State = pair afterNewlines? committed?. The second field models an
     37 -- explicit commit *before* parsing; it is not conflated with consumption.
     38 afterNewlines = SCP.outFork (SCP.outLiteral (t t)) (SCP.outCapture 8)
     39 inlineValue = SCP.outFork (SCP.outLiteral 0) (SCP.outCapture 0)
     40 indentedValue = SCP.outFork (SCP.outCapture 2) (SCP.outCapture 0)
     41 
     42 layoutConsumer committed = SCP.makeConsumer (pair t committed) [(SCP.makeRule SCP.patLeaf (SCP.patFork SCP.patLeaf (SCP.patCapture 8))
     43       (replyFailure (expectedName (SCP.outLiteral t) (SCP.outLiteral t))
     44         (SCP.outLiteral t) false (SCP.outCapture 8)))
     45    (SCP.makeRule SCP.patLeaf (SCP.patFork (SCP.patStem SCP.patAny) (SCP.patCapture 8))
     46       (replyFailure (diagnostic 40 (SCP.outLiteral "definition body")
     47         (SCP.outLiteral t) (SCP.outLiteral t))
     48         (SCP.outLiteral t) true (SCP.outCapture 8)))
     49    (SCP.makeRule (SCP.patFork (SCP.patAs 0 newline) (SCP.patCapture 1))
     50       (SCP.patFork SCP.patAny (SCP.patCapture 8))
     51       (SCP.outRecur (SCP.outCapture 1) afterNewlines))
     52    (SCP.makeRule (SCP.patFork (SCP.patAs 0 nameAny) (SCP.patCapture 1))
     53       (SCP.patFork SCP.patLeaf (SCP.patCapture 8))
     54       (replySuccess inlineValue (SCP.outCapture 1) true (SCP.outCapture 8)))
     55    (SCP.makeRule (SCP.patFork
     56       (SCP.patAs 0 (nameAtColumn (SCP.patLiteral 1))) (SCP.patCapture 1))
     57       (SCP.patFork (SCP.patStem SCP.patAny) (SCP.patCapture 8))
     58       (replySuccess inlineValue (SCP.outCapture 1) true (SCP.outCapture 8)))
     59    (SCP.makeRule (SCP.patFork
     60       (SCP.patAs 0 (nameAtColumn (SCP.patCapture 2))) (SCP.patCapture 1))
     61       (SCP.patFork (SCP.patStem SCP.patAny) (SCP.patCapture 8))
     62       (replySuccess indentedValue (SCP.outCapture 1) true (SCP.outCapture 8)))
     63    (SCP.makeRule (SCP.patAs 0 (SCP.patFork anyToken SCP.patAny))
     64       (SCP.patFork SCP.patLeaf (SCP.patCapture 8))
     65       (replyFailure (expectedName (SCP.outCapture 3) (SCP.outCapture 4))
     66         (SCP.outCapture 0) false (SCP.outCapture 8)))
     67    (SCP.makeRule (SCP.patAs 0 (SCP.patFork anyToken SCP.patAny))
     68       (SCP.patFork (SCP.patStem SCP.patAny) (SCP.patCapture 8))
     69       (replyFailure (expectedName (SCP.outCapture 3) (SCP.outCapture 4))
     70         (SCP.outCapture 0) true (SCP.outCapture 8)))]
     71 layout = layoutConsumer false
     72 layoutWithCommit = layoutConsumer true
     73 renamedLayout = SCP.replaceLiteral layout "definition body" "missing indented value"