blob: c258701680e74f25a1015eeb6132f9ec6b066833 (
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
(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))
)))
(defn ^:private with-lines [body]
(fn [state]
(matchv ::M/objects [(body (&/get$ &/$SOURCE state))]
[["lux;Right" [reader* match]]]
(return* (&/set$ &/$SOURCE reader* state)
match)
[["lux;Left" msg]]
(fail* msg)
)))
;; [Exports]
(defn ^:private re-find! [^java.util.regex.Pattern regex line]
(let [matcher (.matcher regex line)]
(when (.find matcher)
(.group matcher 0))))
(defn ^:private re-find1! [^java.util.regex.Pattern regex line]
(let [matcher (.matcher regex line)]
(when (.find matcher)
(.group matcher 1))))
(defn ^:private re-find3! [^java.util.regex.Pattern 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 (do ;; (prn '[regex line] [regex line])
(re-find! regex line))]
(let [;; _ (prn 'match match)
match-length (.length match)
line* (.substring line match-length)]
(if (.isEmpty 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 (.isEmpty 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-regex+ [regex]
(with-lines
(fn [reader]
(loop [prefix ""
reader* reader]
(matchv ::M/objects [reader*]
[["lux;Nil" _]]
(&/V "lux;Left" "[Reader Error] EOF")
[["lux;Cons" [[_ [[file-name line-num column-num] ^String line]]
reader**]]]
(if-let [^String match (do ;; (prn 'read-regex+ regex line)
(re-find1! regex line))]
(let [match-length (.length match)
line* (.substring line match-length)]
(if (.isEmpty line*)
(recur (str prefix match "\n") reader**)
(&/V "lux;Right" (&/T (&/|cons (&/V "lux;Meta" (&/T (&/T file-name line-num (+ column-num match-length)) line*))
reader**)
(&/V "lux;Meta" (&/T (&/T file-name line-num column-num) (str prefix match)))))))
(&/V "lux;Left" (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)))))
|