tricu

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

lines.tri (2170B)


      1 !import io_v2 as IO
      2 !import io_v2_text as Text
      3 !import base as B
      4 !import native_math as N
      5 !export collect
      6 !export count
      7 !export first
      8 !export stdinLines
      9 !export cancelled
     10 !export closed
     11 
     12 -- Collection is only a test/demo convenience; count discards each line instead.
     13 walk cursor limit events = IO.bind (Text.readLine cursor limit) (reply : case reply of
     14   ((t t), ([event next], t)) = case event of
     15     ["eof"] = IO.pure (B.ok (B.reverse events) t)
     16     _ = walk next limit (B.pair event events)
     17   (t, (cause, t)) = IO.pure (B.err [(B.reverse events) cause] t)
     18   _ = IO.fail "Invalid line Result")
     19 force t next = next t
     20 force (t bit rest) next = case bit of
     21   t = force rest next
     22   (t t) = force rest next
     23   _ = IO.fail "Invalid count"
     24 force _ _ = IO.fail "Invalid count"
     25 countLoop cursor limit n = force n (_ : IO.require (Text.readLine cursor limit) (reply : case reply of
     26   [["eof"] _] = IO.pure n
     27   [_ next] = case N.add n 1 of
     28     number = countLoop next limit number
     29   _ = IO.fail "Invalid line Result"))
     30 collect path limit = IO.io (IO.scope (owner : IO.require (IO.openReader owner path)
     31   (reader : walk (Text.lineCursor reader) limit [])))
     32 count path limit = IO.io (IO.scope (owner : IO.require (IO.openReader owner path)
     33   (reader : countLoop (Text.lineCursor reader) limit 0)))
     34 first path limit = IO.io (IO.scope (owner : IO.require (IO.openReader owner path)
     35   (reader : IO.bind (Text.readLine (Text.lineCursor reader) limit) (reply : case reply of
     36     ((t t), ([event _], t)) = IO.pure (B.ok event t)
     37     _ = IO.pure reply))))
     38 stdinLines limit = IO.io (IO.require IO.stdin (reader : walk (Text.lineCursor reader) limit []))
     39 cancelled = IO.io (IO.scope (_ : do IO.require
     40   reader <- IO.stdin
     41   spawned <- IO.spawn 1 1 [] (_ : Text.readLine (Text.lineCursor reader) 4096)
     42   case spawned of
     43     [task ticket] = do IO.require
     44       IO.sleepMilliseconds 50
     45       IO.cancel task "line-stop"
     46       outcome <- IO.join ticket
     47       IO.pure outcome
     48     _ = IO.fail "Invalid line task"))
     49 closed path limit = IO.io (IO.bind (IO.scope (owner : IO.require (IO.openReader owner path)
     50   (reader : IO.pure (Text.lineCursor reader)))) (cursor : Text.readLine cursor limit))