blob: f1ca81221251228e0587fa9e7b16bf95c68d82e6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
(fn lines [filename callback]
(case (pcall #(with-open [file (io.open filename)] (each [line (file:lines)] (callback line))))
(false err) (print (string.format "Error: Could not open file %s\n%s" filename err))))
(fn _create-corpus [lines data]
(var current-key nil)
(var corpus {})
(lines data
#(let [key (string.match $1 "^::%s+([%a-]+)")
blank (or (= nil $1) (= "" $1))]
(when (not blank)
(if (not key)
(let [list (. corpus current-key)]
(table.insert list $1)
(tset corpus current-key list))
(do
(set current-key key)
(tset corpus current-key []))))))
corpus)
(local create-corpus (partial _create-corpus lines))
(fn one-of [t]
"returns a random element of a sequential or non-sequential table"
(let [len (accumulate [l 0 _ _ (pairs t)] (+ l 1)) ;; do it the hard way
;; because nonseq tables
;; have no length?
handle (io.popen "echo $RANDOM")
output (handle:read "*a")
random (output:gsub "[\n\r]" "")
seed (math.randomseed random) ;; SIDE EFFECT
whatever (handle:close) ;; SIDE EFFECT
idx (math.random len)
keys (accumulate [acc [] k v (pairs t)] (do (table.insert acc k) acc))
rndkey (. keys idx)
it (. t rndkey)]
it))
(fn flatten [corpus origin]
(let [str (if (= "string" (type origin))
origin
(if (= "table" (type origin))
(one-of origin)
(error "Origin must be a table or a string")))
template-pattern "%[%[[%a-]+%]%]" ; [[word]]
word-pattern "%[%[([%a-]+)%]%]" ; word
(i j) (string.find str template-pattern) ; indices
word (string.match str word-pattern)] ; the actual keyword
(if (not i)
str
(let [next-str (string.format "%s%s%s"
(string.sub str 1 (- i 1))
(one-of (. corpus word))
(string.sub str (+ j 1)))]
(flatten corpus next-str j))))) ;; this is a tail call!
{: create-corpus
: flatten
}
|