1 # .tlv file generated by https://github.com/akkartik/teliva
2 # You may edit it if you are careful; however, you may see cryptic errors if you
3 # violate Teliva's assumptions.
5 # .tlv files are representations of Teliva programs. Teliva programs consist of
6 # sequences of definitions. Each definition is a table of key/value pairs. Keys
7 # and values are both strings.
9 # Lines in .tlv files always follow exactly one of the following forms:
10 # - comment lines at the top of the file starting with '#' at column 0
11 # - beginnings of definitions starting with '- ' at column 0, followed by a
13 # - key/value pairs consisting of ' ' at column 0, containing either a
14 # spaceless value on the same line, or a multi-line value
15 # - multiline values indented by more than 2 spaces, starting with a '>'
17 # If these constraints are violated, Teliva may unceremoniously crash. Please
18 # report bugs at http://akkartik.name/contact
19 - __teliva_timestamp: original
21 >function check(x, msg)
26 > print(' '..str(x)..' is false/nil')
27 > teliva_num_test_failures = teliva_num_test_failures + 1
28 > -- overlay first test failure on editors
29 > if teliva_first_failure == nil then
30 > teliva_first_failure = msg
34 - __teliva_timestamp: original
36 >function check_eq(x, expected, msg)
37 > if eq(x, expected) then
41 > print(' expected '..str(expected)..' but got '..str(x))
42 > teliva_num_test_failures = teliva_num_test_failures + 1
43 > -- overlay first test failure on editors
44 > if teliva_first_failure == nil then
45 > teliva_first_failure = msg
49 - __teliva_timestamp: original
52 > if type(a) ~= type(b) then return false end
53 > if type(a) == 'table' then
54 > if #a ~= #b then return false end
55 > for k, v in pairs(a) do
60 > for k, v in pairs(b) do
69 - __teliva_timestamp: original
72 >-- slow; used only for debugging
74 > if type(x) == 'table' then
76 > result = result..#x..'{'
77 > for k, v in pairs(x) do
78 > result = result..str(k)..'='..str(v)..', '
80 > result = result..'}'
82 > elseif type(x) == 'string' then
87 - __teliva_timestamp: original
89 >-- To show app-specific hotkeys in the menu bar, add hotkey/command
90 >-- arrays of strings to the menu array.
92 - __teliva_timestamp: original
94 >Window = curses.stdscr()
95 - __teliva_timestamp: original
98 > task.spawn(main_task)
103 - __teliva_timestamp: original
105 >function main_task()
107 > local c = task.Channel:new()
108 > task.spawn(counter, c)
113 - __teliva_timestamp:
114 >Sat Feb 26 21:50:11 2022
125 - __teliva_timestamp:
126 >Sat Feb 26 21:54:53 2022
128 >function filter_task(p, cin, cout)
130 > local i = cin:recv()
136 - __teliva_timestamp:
137 >Sat Feb 26 21:55:46 2022
139 >function main_task()
140 > local primes = task.Channel:new()
141 > task.spawn(sieve, primes)
143 > print(primes:recv())
146 - __teliva_timestamp:
147 >Sat Feb 26 21:59:37 2022
149 >filter out multiples of a single number
152 > local iota = task.Channel:new()
153 > task.spawn(counter, iota)
154 > task.spawn(filter_task, 2, iota, ch)
156 - __teliva_timestamp:
157 >Sat Feb 26 22:08:07 2022
159 >implement the complete sieve algorithm
161 >-- Set up a Sieve of Eratosthenes (https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)
162 >-- for computing prime numbers by chaining tasks, one per prime.
163 >-- Each task is responsible for filtering out all multiples of its prime.
164 >function sieve(primes_ch)
165 > local c = task.Channel:new()
166 > task.spawn(counter, c)
168 > local p, newc = c:recv(), task.Channel:new()
170 > task.spawn(filter_task, p, c, newc)
174 - __teliva_timestamp:
175 >Sat Feb 26 22:09:47 2022
179 >function main_task()
180 > local primes = task.Channel:new()
181 > task.spawn(sieve, primes)
183 > Window:addstr(primes:recv())
188 - __teliva_timestamp:
189 >Sat Feb 26 22:09:47 2022
191 >clear screen when it fills up; pause on keypress
193 >In Teliva getch() implicitly refreshes the screen.
195 >function main_task()
196 > Window:nodelay(true)
198 > local primes = task.Channel:new()
199 > task.spawn(sieve, primes)
200 > local h, w = Window:getmaxyx()
202 > Window:addstr(primes:recv())
204 > local c = Window:getch()
205 > if c then break end -- key pressed
206 > local y, x = Window:getyx()
211 > print('key pressed; done')
212 > Window:nodelay(false)
214 - __teliva_timestamp:
215 >Sat Feb 26 22:27:25 2022
217 >Sieve of Eratosthenes
218 >https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
220 >A demonstration of tasks and channels, the primitives for (cooperative) concurrency in Teliva.
222 >We string together a cascade of tasks connected by channels. Every prime number gets a new task that prints the first incoming number, and then filters out multiples of it from the incoming channel.
224 >This approach has the advantage that we don't need to create an array of n numbers to compute primes less than n.
226 >However, we still need to create p tasks and p channels if there are p primes less than n. Probably not worth it, given tasks and channels are much larger than numbers. This is just a demo.
228 >The noticeable periodic pauses are perhaps due to garbage collection.