1{
2 stdenv,
3 nodejs,
4 tree-sitter,
5 lib,
6}:
7
8# Build a parser grammar and put the resulting shared object in `$out/parser`
9
10{
11 # language name
12 language,
13 version,
14 src,
15 location ? null,
16 generate ? false,
17 ...
18}@args:
19
20stdenv.mkDerivation (
21 {
22 pname = "${language}-grammar";
23
24 inherit src version;
25
26 nativeBuildInputs = lib.optionals generate [
27 nodejs
28 tree-sitter
29 ];
30
31 CFLAGS = [
32 "-Isrc"
33 "-O2"
34 ];
35 CXXFLAGS = [
36 "-Isrc"
37 "-O2"
38 ];
39
40 stripDebugList = [ "parser" ];
41
42 configurePhase =
43 lib.optionalString (location != null) ''
44 cd ${location}
45 ''
46 + lib.optionalString generate ''
47 tree-sitter generate
48 '';
49
50 # When both scanner.{c,cc} exist, we should not link both since they may be the same but in
51 # different languages. Just randomly prefer C++ if that happens.
52 buildPhase = ''
53 runHook preBuild
54 if [[ -e src/scanner.cc ]]; then
55 $CXX -fPIC -c src/scanner.cc -o scanner.o $CXXFLAGS
56 elif [[ -e src/scanner.c ]]; then
57 $CC -fPIC -c src/scanner.c -o scanner.o $CFLAGS
58 fi
59 $CC -fPIC -c src/parser.c -o parser.o $CFLAGS
60 rm -rf parser
61 $CXX -shared -o parser *.o
62 runHook postBuild
63 '';
64
65 installPhase = ''
66 runHook preInstall
67 mkdir $out
68 mv parser $out/
69 if [[ -d queries ]]; then
70 cp -r queries $out
71 fi
72 runHook postInstall
73 '';
74 }
75 // removeAttrs args [
76 "language"
77 "location"
78 "generate"
79 ]
80)