blob: 6a954d5ffb67f857fef7925a10b425aabed1621f (
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
(ns lux.reader
(:require [clojure.string :as string]
[clojure.core.match :as M :refer [matchv]]
clojure.core.match.array
[lux.base :as & :refer [|do return* return fail fail* |let]]))
;; [Utils]
(defn ^:private with-line [body]
(fn [state]
(matchv ::M/objects [(&/get$ &/$SOURCE state)]
[["lux;Nil" _]]
(fail* "[Reader Error] EOF")
[["lux;Cons" [["lux;Meta" [[file-name line-num column-num] line]]
more]]]
(matchv ::M/objects [(body file-name line-num column-num line)]
[["No" msg]]
(fail* msg)
[["Done" output]]
(return* (&/set$ &/$SOURCE more state)
output)
[["Yes" [output line*]]]
(return* (&/set$ &/$SOURCE (&/|cons line* more) state)
output))
)))
;; [Exports]
(defn ^:private re-find! [regex line]
(let [matcher (.matcher regex line)]
(when (.find matcher)
(.group matcher 0))))
(defn ^:private re-find3! [regex line]
(let [matcher (.matcher regex line)]
(when (.find matcher)
(list (.group matcher 0)
(.group matcher 1)
(.group matcher 2)))))
(defn read-regex [regex]
(with-line
(fn [file-name line-num column-num ^String line]
(if-let [^String match (re-find! regex line)]
(let [match-length (.length match)
line* (.substring line match-length)]
(if (empty? line*)
(&/V "Done" (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) match)))
(&/V "Yes" (&/T (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) match))
(&/V "lux;Meta" (&/T (&/T file-name line-num (+ column-num match-length)) line*))))))
(&/V "No" (str "[Reader Error] Pattern failed: " regex))))))
(defn read-regex2 [regex]
(with-line
(fn [file-name line-num column-num ^String line]
(if-let [[^String match tok1 tok2] (re-find3! regex line)]
(let [match-length (.length match)
line* (.substring line match-length)]
(if (empty? line*)
(&/V "Done" (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) (&/T tok1 tok2))))
(&/V "Yes" (&/T (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) (&/T tok1 tok2)))
(&/V "lux;Meta" (&/T (&/T file-name line-num (+ column-num match-length)) line*))))))
(&/V "No" (str "[Reader Error] Pattern failed: " regex))))))
(defn read-text [^String text]
(with-line
(fn [file-name line-num column-num ^String line]
(if (.startsWith line text)
(let [match-length (.length text)
line* (.substring line match-length)]
(if (empty? line*)
(&/V "Done" (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) text)))
(&/V "Yes" (&/T (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) text))
(&/V "lux;Meta" (&/T (&/T file-name line-num (+ column-num match-length)) line*))))))
(&/V "No" (str "[Reader Error] Text failed: " text))))))
(defn from [file-name]
(let [lines (&/->list (string/split-lines (slurp file-name)))]
(&/|map (fn [line+line-num]
(|let [[line-num line] line+line-num]
(&/V "lux;Meta" (&/T (&/T file-name line-num 0)
line))))
(&/|filter (fn [line+line-num]
(|let [[line-num line] line+line-num]
(not= "" line)))
(&/enumerate lines)))))
|