tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

b3b105527413625cc748a0a2934f0326c918f18b88d52502c6094ce705c59d3d.tri (2258B)


      1 !import base as B
      2 !import io as IO
      3 !import io_storage as Storage
      4 !import io_text as Text
      5 !export *
      6 
      7 -- Compiler storage policy over IO, imported explicitly as compiler_io.
      8 -- Explicit application policy: resident source/metadata bytes and encoded trees
      9 -- are limited to 64 MiB. Heap use, expanded-tree size and CPU work require
     10 -- separate resource controls.
     11 byteLimit = 67108864
     12 version = 2
     13 io = IO.io
     14 pure = IO.pure
     15 bind = IO.bind
     16 abortIO = IO.fail
     17 thenIO first second = bind first (_ : second)
     18 mapIO action f = bind action (value : pure (f value))
     19 void action = bind action (_ : pure t)
     20 onOk action next = bind action (reply : B.matchResult (_ _ : pure reply) next reply)
     21 onOk_ action next = IO.onOk action next
     22 onResult action failed succeeded = bind action (reply : B.matchResult failed succeeded reply)
     23 onResult_ action failed succeeded = onResult action (problem _ : failed problem) (value _ : succeeded value)
     24 
     25 readFile  path  = Storage.readBytes path byteLimit
     26 sha256Hex bytes = Storage.hashBytes byteLimit bytes
     27 readSourceFile path = IO.scope (owner : do IO.onOk
     28   reader <- IO.openReader owner path
     29   Text.readSource reader byteLimit)
     30 encodeSourceText text = Text.encodeText byteLimit text
     31 -- Compiler callers create directories in parent-first order. A missing ancestor
     32 -- produces an error. Sync the parent entry before use.
     33 createDirectory path = do IO.onOk
     34   IO.ensureDirectory path
     35   IO.syncDirectory (Storage.parentPath path)
     36 fileExists path = bind (IO.statPath path) (reply : case reply of
     37   ((t t), (["file" _], t)) = pure (B.ok (t t) t)
     38   ((t t), (_, t)) = pure (B.ok t t)
     39   (t, (["not-found" _ _ _], t)) = pure (B.ok t t)
     40   _ = pure reply)
     41 writeBytesIfAbsent path bytes = Storage.publishBytes (Storage.parentPath path) path 0 byteLimit bytes
     42 atomicWriteBytes   path bytes = Storage.publishBytes (Storage.parentPath path) path 1 byteLimit bytes
     43 hashIndexedTree tree = do IO.onOk
     44   info <- IO.hashIndexedTree byteLimit tree
     45   case info of
     46     [_ digest] = pure (B.ok digest t)
     47     _ = IO.fail "Invalid indexed hash reply"
     48 writeIndexedTreeIfAbsent path digest tree =
     49   Storage.publishTree (Storage.parentPath path) path byteLimit digest tree
     50 readIndexedTree path digest =
     51   Storage.readTree (Storage.parentPath path) path byteLimit digest