tricu

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

consumer_prefix_lexical.tri (4019B)


      1 -- Literal-prefix lowering must bind the suffix once and preserve rule fallback.
      2 !import "consumers.structural" S
      3 !import "consumers.lexical-worker" L
      4 !import "consumers.validate" V
      5 !import "consumers.registry-source" RS
      6 !import "consumers.source" C
      7 !import "parser" P
      8 !import "prelude" !Local
      9 rule input state output = S.makeRule input state output
     10 -- Independent expected expansion also covers arbitrary tree-list elements.
     11 expand_ self bytes slot = (lazyList
     12   (_ : S.patCapture slot)
     13   (head rest : S.patFork (S.patLiteral head) (self rest slot))
     14   bytes)
     15 expand bytes slot = y expand_ bytes slot
     16 expansion prefix = equal? (S.expandPrefix prefix 0) (ok (expand prefix 0) t)
     17 prefixIR prefix = S.makeConsumer t [
     18   (rule (resultOr t (S.expandPrefix prefix 0)) S.patAny (S.outCapture 0))
     19   (rule S.patAny S.patAny (S.outLiteral "miss"))]
     20 compare prefix input = (equal?
     21   (L.lRunChecked (resultOr t (L.lCompile (prefixIR prefix))) input)
     22   (S.runConsumer (prefixIR prefix) input))
     23 nested = S.makeConsumer t [
     24   (rule (S.patFork (S.patCapture 1)
     25     (resultOr t (S.expandPrefix "/api/" 0)))
     26     S.patAny (S.outFork (S.outCapture 1) (S.outCapture 0)))
     27   (rule S.patAny S.patAny (S.outLiteral "miss"))]
     28 nestedWorker = resultOr t (L.lCompile nested)
     29 longPrefix = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMN"
     30 longIR = prefixIR longPrefix
     31 longWorker = resultOr t (L.lCompile longIR)
     32 longProbe input expected = (and?
     33   (equal? (L.lRunChecked longWorker input) (S.runConsumer longIR input))
     34   (equal? (S.runConsumer longIR input) expected))
     35 -- The retired pattern tag remains invalid authored IR. Improper prefixes
     36 -- fail during elaboration and never produce authored IR.
     37 removedTag = S.makeConsumer t [(rule (pair 7 (pair "/api/" 0))
     38   S.patAny (S.outLiteral t))]
     39 improper = S.expandPrefix (t t) 0
     40 improperTail = S.expandPrefix (pair 65 (t t)) 0
     41 -- The lexer produces proper strings; a forged string token still fails in
     42 -- source elaboration, before a rule containing invalid IR can be published.
     43 badRoutePosition = pair 3 4
     44 badRoute = RS.rsMethod "GET" [
     45   (C.cToken C.cString (t t) badRoutePosition badRoutePosition)
     46   (C.cToken C.cName "remainder" t t)]
     47 checks = foldl and? true [
     48   (expansion "") (expansion "a") (expansion "/api/")
     49   (expansion [t 2])
     50   (compare "a" "a") (compare "a" "ab") (compare "a" "b")
     51   (compare [t 2] [t 2 3]) (compare [t 2] [t 3])
     52   (equal? (V.vValidate removedTag)
     53     (err (V.vDiagnostic "malformed" 0 ["input pattern"]
     54       "unknown pattern tag") t))
     55   (equal? (L.lCompile removedTag) (V.vValidate removedTag))
     56   (equal? improper (err "improper literal prefix" t))
     57   (equal? improperTail (err "improper literal prefix" t))
     58   (equal? (fst badRoute) false)
     59   (equal? (P.parserDiagnosticCode (P.parserReplyPayload badRoute)) 23)
     60   (equal? (P.parserDiagnosticLocation (P.parserReplyPayload badRoute))
     61     badRoutePosition)
     62   (equal? (S.expandPrefix "" 0) (ok (S.patCapture 0) t))
     63   (equal? (S.expandPrefix "a" 0)
     64     (ok (S.patFork (S.patLiteral 97) (S.patCapture 0)) t))
     65   (compare "" "")
     66   (compare "" "data")
     67   (compare "/api/" "/api/")
     68   (compare "/api/" "/api/item")
     69   (compare "/api/" "/api")
     70   (compare "/api/" "/apix/item")
     71   (compare "/api/" "/other")
     72   (compare "/api/" t)
     73   (compare "/api/" (t t))
     74   (compare "" (pair 65 t))
     75   (resultIsOk (V.vValidate longIR))
     76   (longProbe longPrefix (ok t t))
     77   (longProbe (append longPrefix "/item") (ok "/item" t))
     78   (longProbe "abcdefghijXlmnopqrstuvwxyz0123456789ABCDEFGHIJKLMN"
     79     (ok "miss" t))
     80   (longProbe "abcdefghij" (ok "miss" t))
     81   (longProbe (pair 97 (t t)) (ok "miss" t))
     82   (equal? (L.lRunChecked (resultOr t (L.lCompile (prefixIR "/api/"))) "/api/item")
     83     (ok "item" t))
     84   (equal? (L.lRunChecked nestedWorker (pair 42 "/api/item"))
     85     (S.runConsumer nested (pair 42 "/api/item")))
     86   (equal? (L.lRunChecked nestedWorker (pair 42 "/api/item"))
     87     (ok (pair 42 "item") t))
     88   (equal? (L.lRunChecked nestedWorker (pair 42 "/wrong")) (ok "miss" t))]
     89 main = matchBool "consumer-prefix-ok" "consumer-prefix-DIFFER" checks
     90 main