tricu

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

main.tri (4446B)


      1 !import prelude *
      2 !import io *
      3 !import consumers_module as M
      4 !import consumers_link as CL
      5 !import consumers_text_summary as T
      6 !import source_resolve as Resolve
      7 !export *
      8 -- From the repository root, after `nix build .#`:
      9 --   result/bin/tricu eval demos/consumers/source-linked-summary/main.tri \
     10 --     --store "$(mktemp -d)" --unsafe-io --io --format tree
     11 -- Expect `lines: 4` from sample.txt (fourth line has no trailing newline).
     12 -- The bootstrap IO command prints a final `t` after the application output.
     13 -- Focused fresh-store check: bash test/consumer_source_link_demo.sh result/bin/tricu
     14 --
     15 -- countLines.scp counts records with compact naturals using succ.scp;
     16 -- entry.scp requests named ReadText and keeps its worker; receiver.scp
     17 -- handles success/failure and calls the counter only on success. The four
     18 -- authored sources are copied from the separately tested library/client.
     19 -- This entrypoint stages their exact source bytes, pins their digests in a
     20 -- tricu-owned CAS import descriptor, resolves verified objects, publishes and
     21 -- reloads original IR sidecars, then compiles successor and three client workers.
     22 -- The effect driver owns file IO. No Python embeds the sources or interprets
     23 -- them. The printed hashes identify the import descriptor and IR manifest,
     24 -- not an attestation or a packed worker artifact. `run path` accepts another
     25 -- file; inputFile selects the direct-entrypoint sample.
     26 
     27 -- This explicit source CAS root is separate from the bootstrap `--store`
     28 -- module-import store. A changed source makes a new pinned descriptor;
     29 -- previously pinned descriptors keep identifying their original source bytes.
     30 sourceStore = "/tmp/tricu-scp-summary-demo.v1"
     31 sourceDirectory = "demos/consumers/source-linked-summary/"
     32 inputFile = "demos/consumers/source-linked-summary/sample.txt"
     33 importRow alias hash name = pair alias (pair hash name)
     34 
     35 -- Filesystem access is limited to initial source staging and the explicit
     36 -- ReadText application effect. cmLoad below resolves exclusively from CAS.
     37 stage = do onOk_
     38   succSource <- readFile (append sourceDirectory "succ.scp")
     39   succHash <- M.cmPutSource sourceStore succSource
     40   countSource <- readFile (append sourceDirectory "countLines.scp")
     41   countHash <- M.cmPutSource sourceStore countSource
     42   entrySource <- readFile (append sourceDirectory "entry.scp")
     43   entryHash <- M.cmPutSource sourceStore entrySource
     44   receiverSource <- readFile (append sourceDirectory "receiver.scp")
     45   receiverHash <- M.cmPutSource sourceStore receiverSource
     46   M.cmPutImports sourceStore [
     47     (importRow "successor" succHash "succBinary")
     48     (importRow "counter" countHash "countLines")
     49     (importRow "entry" entryHash "summaryEntry")
     50     (importRow "receiver" receiverHash "summaryReceiver")]
     51 
     52 -- Compile the verified successor first, then inject its executable descriptor
     53 -- into the counter's initial state. Both rounds resolve the same pinned source
     54 -- descriptor; the initial worker graph is explicit application policy.
     55 prepare descriptor = (onResult_
     56   (CL.clPrepare sourceStore descriptor [(pair "successor" t)])
     57   (problem : pure (err problem t))
     58   (prepared : lazyMaybe
     59     (_ : pure (err "missing successor" t))
     60     (successor : CL.clPrepare sourceStore descriptor [
     61       (pair "counter" (T.counterState successor))
     62       (pair "entry" t)
     63       (pair "receiver" t)])
     64     (Resolve.sourceFindExternal (fst (snd prepared)) "successor")))
     65 lookupWorker workers alias =
     66   (lazyMaybe (_ : err (append "missing worker: " alias) t)
     67     (worker : ok worker t) (Resolve.sourceFindExternal workers alias))
     68 selectWorkers workers = (bindResult (lookupWorker workers "counter") (counter _ :
     69   bindResult (lookupWorker workers "entry") (entry _ :
     70     bindResult (lookupWorker workers "receiver") (receiver _ :
     71       ok (pair counter (pair entry receiver)) t))))
     72 
     73 run path = (onOk_ stage (descriptor : onOk_ (prepare descriptor) (prepared :
     74   lazyResult
     75     (problem _ : pure (err problem t))
     76     (selected _ : bind (T.summaryLexical (fst selected)
     77       (fst (snd selected)) (snd (snd selected)) path)
     78       (outcome : pure (ok (pair descriptor (pair (fst prepared) outcome)) t)))
     79     (selectWorkers (fst (snd prepared))))))
     80 main = io (onResult_ (run inputFile)
     81   (problem : putStrLn "source-linked summary failed")
     82   (report : do bind
     83     _ <- putStrLn (append "imports=" (fst report))
     84     _ <- putStrLn (append "sidecars=" (fst (snd report)))
     85     putStrLn (T.render (snd (snd report)))))