This repository has been archived by the owner on Jan 11, 2024. It is now read-only.
forked from purs-nix/purs-nix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.nix
73 lines (68 loc) · 2.3 KB
/
parser.nix
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
with builtins;
{ l, parsec }:
let
p = parsec;
r =
rec
{ csl = re: ''(${re}?(${ws}*,${ws}*${re})*)'';
ws = "([ \r\n]|--[^\n]*\n|\\{-([^-]|-[^}])*-})";
module-name = ''([^ ${"\r\n"}()=:{},-]+)'';
fun-type-name = ''([^ ${"\r\n"}()=:{},.-]+)'';
op-name = ''(\([^ ${"\n"})]*\))'';
fun-type-export = ''(${fun-type-name}(${ws}*\(${ws}*(${csl fun-type-name}|\.\.)${ws}*\))?)'';
type-op-export = ''(type${ws}*${op-name})'';
class-export = ''(class${ws}+${fun-type-name})'';
module-export = ''(module${ws}+${module-name})'';
single-export = ''(${fun-type-export}|${op-name}|${class-export}|${module-export}|${type-op-export})'';
exports = ''((hiding)?${ws}*\(${ws}*${csl single-export}${ws}*\))'';
import-end = ''((${exports})?${ws}*(as${ws}+${module-name})?)'';
};
parse-module =
str:
let
toss = re: p.skipThen (p.matching re);
keep = re: p.bind (p.fmap head (p.matching re));
import' =
toss "import${r.ws}+" (
(keep r.module-name) (name:
toss "${r.ws}*${r.import-end}${r.ws}*" (
p.pure name)));
result =
p.runParser
(toss "${r.ws}*module${r.ws}+" (
keep "${r.module-name}" (name:
toss "${r.ws}*${r.exports}?${r.ws}*where${r.ws}*" (
p.bind (p.many import') (imports:
p.pure { inherit imports name; })))))
# `builtins.match` will stack overflow if strings are too large
(substring 0 100000 str);
in
if result.type == "success"
then result.value
else throw (l.traceSeq result "Failed to parse module.");
in
dirs:
foldl'
(acc: { path, parser-stuff }:
acc //
{ ${parser-stuff.name} =
{ depends = filter (a: !l.hasPrefix "Prim" a) parser-stuff.imports;
inherit path;
};
}
)
{}
(map
(f: { path = f;
parser-stuff = parse-module (readFile f);
}
)
(l.concatMap
(dir:
filter
(l.hasSuffix ".purs")
(l.filesystem.listFilesRecursive dir)
)
dirs
)
)