Merge branch 'master' of https://github.com/haskell-nix/hnix into string_context_255
This commit is contained in:
commit
fbcb258eb4
7
.dockerignore
Normal file
7
.dockerignore
Normal file
|
@ -0,0 +1,7 @@
|
|||
.git
|
||||
Dockerfile
|
||||
Makefile
|
||||
README.md
|
||||
cabal.sandbox.config
|
||||
.cabal-sandbox/
|
||||
hnix.cabal
|
41
.travis.yml
41
.travis.yml
|
@ -1,22 +1,45 @@
|
|||
language: nix
|
||||
|
||||
sudo: true
|
||||
# sudo: false
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- /nix/store
|
||||
# cache:
|
||||
# directories:
|
||||
# - /nix
|
||||
# timeout: 100000
|
||||
|
||||
cache:
|
||||
timeout: 10000
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
install:
|
||||
- nix-shell --argstr compiler ghc822 --run true
|
||||
- nix-shell --argstr compiler ghc842 --run true
|
||||
|
||||
env:
|
||||
- GHCVERSION=ghc822 NIXPKGS_TESTS=yes MATCHING_TESTS=yes TRACING=true STRICT=true PROFILING=false
|
||||
- GHCVERSION=ghc822 NIXPKGS_TESTS=yes MATCHING_TESTS=yes TRACING=false STRICT=true PROFILING=true
|
||||
- GHCVERSION=ghc842 NIXPKGS_TESTS=yes MATCHING_TESTS=yes TRACING=false STRICT=false PROFILING=false
|
||||
global:
|
||||
- NIXPKGS_TESTS=yes
|
||||
- MATCHING_TESTS=yes
|
||||
matrix:
|
||||
- GHCVERSION=ghc822 STRICT=true TRACING=false PROFILING=false
|
||||
- GHCVERSION=ghc822 STRICT=true TRACING=true PROFILING=false
|
||||
- GHCVERSION=ghc822 STRICT=true TRACING=true PROFILING=true
|
||||
- GHCVERSION=ghc842 STRICT=false TRACING=false PROFILING=false
|
||||
- GHCVERSION=ghc842 STRICT=false TRACING=true PROFILING=false
|
||||
- GHCVERSION=ghc842 STRICT=false TRACING=true PROFILING=true
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- env: GHCVERSION=ghc842 STRICT=true
|
||||
exclude:
|
||||
- env: GHCVERSION=ghc822 STRICT=false
|
||||
|
||||
script:
|
||||
- nix-build --argstr compiler $GHCVERSION --arg doProfiling $PROFILING --arg doTracing $TRACING --arg doStrict $STRICT
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- pending
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
|
|
16
Dockerfile
Normal file
16
Dockerfile
Normal file
|
@ -0,0 +1,16 @@
|
|||
FROM lnl7/nix:2.0
|
||||
|
||||
WORKDIR /tmp/build
|
||||
|
||||
COPY default.nix /tmp/build
|
||||
COPY package.yaml /tmp/build
|
||||
|
||||
# Install tools needed by builtins.fetchTarball, and then install all
|
||||
# dependencies into its own layer, which doesn't change.
|
||||
RUN nix-env -f '<nixpkgs>' -i gnutar gzip && \
|
||||
nix-shell -Q -j2 --run true
|
||||
|
||||
COPY . /tmp/build
|
||||
RUN nix-env -f . -i hnix
|
||||
|
||||
CMD ["/root/.nix-profile/bin/hnix"]
|
190
PLAN.org
190
PLAN.org
|
@ -1,190 +0,0 @@
|
|||
#+TITLE: hnix Project Plan
|
||||
|
||||
* Goals
|
||||
|
||||
The purpose of hnix is provide a fully featured, compatible implementation of
|
||||
the Nix language, sufficient to evaluate and make use of the nixpkgs package
|
||||
repository definitions. The intent is to provide a convenient basis for
|
||||
creating new tooling in Haskell for the Nix ecosystem, and to provide an
|
||||
second implementation apart from the current C++ code base used by the Nix
|
||||
project.
|
||||
|
||||
|
||||
* Architecture
|
||||
|
||||
#+name: dot-figure
|
||||
#+begin_src dot :file diagram4.svg :cmdline -Tsvg :results file
|
||||
digraph {
|
||||
bgcolor=transparent;
|
||||
rankdir=LR;
|
||||
|
||||
{
|
||||
rank=same;
|
||||
parser [label="Parser",style=filled,fillcolor=yellow,shape=box,width=2];
|
||||
value [label="Values",style=filled,fillcolor=yellow,shape=box,width=2];
|
||||
eval [label="Core Evaluator",style=filled,fillcolor=yellow,shape=box,width=2];
|
||||
expr [label="Expressions",style=filled,fillcolor=yellow,shape=box,width=2];
|
||||
pretty [label="Pretty Printer",style=filled,fillcolor=yellow,shape=box,width=2];
|
||||
}
|
||||
|
||||
{
|
||||
rank=same;
|
||||
exec [label="Executing Evaluator",style=filled,fillcolor=yellow,shape=box,width=2];
|
||||
builtins [label="Built-in Functions",style=filled,fillcolor=yellow,shape=box,width=2];
|
||||
}
|
||||
|
||||
support [label="Supporting Abstractions",style=filled,fillcolor=yellow,shape=box,width=2];
|
||||
features [label="Other Features",style=filled,fillcolor=yellow,shape=box,width=2];
|
||||
main [label="Top-Level Driver",style=filled,fillcolor=green,shape=box,width=2];
|
||||
|
||||
expr -> {
|
||||
"Atoms.hs" [color=transparent]
|
||||
"Expr.hs" [color=transparent]
|
||||
"Expr/Shorthands.hs" [color=transparent]
|
||||
"Expr/Types.hs" [color=transparent]
|
||||
"Expr/Types/Annotated.hs" [color=transparent]
|
||||
"Strings.hs" [color=transparent]
|
||||
};
|
||||
|
||||
pretty -> {
|
||||
"Pretty.hs" [color=transparent]
|
||||
"Render.hs" [color=transparent]
|
||||
"Render/Frame.hs" [color=transparent]
|
||||
};
|
||||
|
||||
parser -> {
|
||||
"Parser.hs" [color=transparent]
|
||||
"Parser/Library.hs" [color=transparent]
|
||||
"Parser/Operators.hs" [color=transparent]
|
||||
};
|
||||
|
||||
value -> {
|
||||
"Convert.hs" [color=transparent]
|
||||
"Normal.hs" [color=transparent]
|
||||
"Value.hs" [color=transparent]
|
||||
};
|
||||
|
||||
builtins -> {
|
||||
"Builtins.hs" [color=transparent]
|
||||
"XML.hs" [color=transparent]
|
||||
};
|
||||
|
||||
support -> {
|
||||
"Frames.hs" [color=transparent]
|
||||
"Scope.hs" [color=transparent]
|
||||
"Thunk.hs" [color=transparent]
|
||||
"Options.hs" [color=transparent]
|
||||
"Utils.hs" [color=transparent]
|
||||
};
|
||||
|
||||
features -> {
|
||||
"Cache.hs" [color=transparent]
|
||||
"Lint.hs" [color=transparent]
|
||||
"Reduce.hs" [color=transparent]
|
||||
"Type/..." [color=transparent]
|
||||
"TH.hs" [color=transparent]
|
||||
};
|
||||
|
||||
"Cache.hs" -> { expr parser };
|
||||
"Lint.hs" -> { expr eval };
|
||||
"Reduce.hs" -> { expr parser };
|
||||
"Type/..." -> { expr eval };
|
||||
"TH.hs" -> { expr parser };
|
||||
|
||||
eval -> {
|
||||
"Context.hs" [color=transparent]
|
||||
"Eval.hs" [color=transparent]
|
||||
};
|
||||
|
||||
exec -> {
|
||||
"Effects.hs" [color=transparent]
|
||||
"Exec.hs" [color=transparent]
|
||||
};
|
||||
|
||||
{ eval parser pretty value expr builtins exec } -> support;
|
||||
{ eval parser pretty value } -> expr;
|
||||
exec -> { eval value builtins };
|
||||
{ pretty builtins } -> value;
|
||||
main -> { parser pretty exec features };
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+ATTR_LATEX: :height 3cm
|
||||
#+results: dot-figure
|
||||
[[file:diagram4.svg]]
|
||||
|
||||
* What needs to be done
|
||||
|
||||
** PROJECT Pass the Nix language tests
|
||||
:PROPERTIES:
|
||||
:ID: BB4190F1-695D-454A-8E14-492651B4EC9F
|
||||
:CREATED: [2018-04-23 Mon 17:12]
|
||||
:URL: https://github.com/jwiegley/hnix/milestone/1
|
||||
:END:
|
||||
|
||||
We currently have just two tests remaining that need to be fixed to pass the
|
||||
Nix language tests:
|
||||
|
||||
*** TODO builtins.path:
|
||||
https://github.com/jwiegley/hnix/issues/128
|
||||
*** TODO builtins.genericClosure:
|
||||
https://github.com/jwiegley/hnix/issues/144
|
||||
|
||||
** PROJECT Successfully evaluate all of nixpkgs
|
||||
:PROPERTIES:
|
||||
:ID: E4A330E7-70C1-4E79-A94C-D63B2533EBE1
|
||||
:CREATED: [2018-04-23 Mon 17:10]
|
||||
:URL: https://github.com/jwiegley/hnix/milestone/2
|
||||
:END:
|
||||
|
||||
There are still a few problems in the evaluator with process the contents of
|
||||
the nixpkgs repository:
|
||||
|
||||
*** TODO https://github.com/jwiegley/hnix/issues/157
|
||||
*** TODO https://github.com/jwiegley/hnix/issues/193
|
||||
|
||||
** PROJECT Increase test coverage
|
||||
:PROPERTIES:
|
||||
:ID: 5998F757-F30B-4987-89BE-4E44A1BE57BF
|
||||
:CREATED: [2018-04-23 Mon 17:17]
|
||||
:END:
|
||||
|
||||
*** TODO https://github.com/jwiegley/hnix/issues/158
|
||||
|
||||
** PROJECT Improve the hnix REPL
|
||||
:PROPERTIES:
|
||||
:ID: F824236D-7D7E-43D0-8DE6-AD66055B8935
|
||||
:CREATED: [2018-04-23 Mon 17:17]
|
||||
:END:
|
||||
|
||||
*** TODO https://github.com/jwiegley/hnix/issues/164
|
||||
|
||||
** PROJECT Support concurrent evaluation
|
||||
:PROPERTIES:
|
||||
:ID: AE9B3606-009D-43FF-A1E0-0E9A5494BFAC
|
||||
:CREATED: [2018-04-23 Mon 17:18]
|
||||
:END:
|
||||
|
||||
*** TODO https://github.com/jwiegley/hnix/issues/170
|
||||
|
||||
** PROJECT Type checker
|
||||
:PROPERTIES:
|
||||
:ID: F42B3AAB-3BA8-40DC-8B29-F534019F5832
|
||||
:CREATED: [2018-04-23 Mon 17:16]
|
||||
:END:
|
||||
|
||||
** PROJECT Haskell integration using a quasi-quoter
|
||||
:PROPERTIES:
|
||||
:ID: 7800EF09-5083-4819-ACD4-877B85E98C07
|
||||
:CREATED: [2018-04-23 Mon 17:16]
|
||||
:END:
|
||||
|
||||
|
||||
* Colophon
|
||||
#+STARTUP: content fninline hidestars
|
||||
#+OPTIONS: ^:{}
|
||||
#+ARCHIVE: PLAN-archive.txt::
|
||||
#+SEQ_TODO: STARTED TODO APPT WAITING(@) DELEGATED(@) DEFERRED(@) SOMEDAY(@) PROJECT | DONE(@) CANCELED(@) NOTE
|
||||
#+TAGS: P1(1) P2(2) P3(3) Call(c) Errand(e) Home(h) Net(n) Reply(r) Waiting(w)
|
||||
#+DRAWERS: PROPERTIES LOGBOOK OUTPUT SCRIPT SOURCE DATA
|
||||
#+PROPERTY: OVERLAY (face (:background "#e8eff9"))
|
16
README.md
16
README.md
|
@ -24,6 +24,20 @@ $ cabal test
|
|||
$ LANGUAGE_TESTS=yes NIXPKGS_TESTS=yes cabal test
|
||||
$ ./dist/build/hnix/hnix --help
|
||||
```
|
||||
|
||||
## Building a Docker container
|
||||
|
||||
If you don't have Nix installed, or you'd just like to play around with `hnix`
|
||||
completely separately from your main system, you can build a Docker container:
|
||||
|
||||
```bash
|
||||
$ docker build -t hnix .
|
||||
$ docker run hnix hnix --eval --expr '1 + 2'
|
||||
|
||||
# In order to refer to files under the current directory:
|
||||
$ docker run -v $PWD/:/tmp/build run hnix hnix default.nix
|
||||
```
|
||||
|
||||
## Building with full debug info
|
||||
|
||||
To build `hnix` for debugging, and with full tracing output and stack traces,
|
||||
|
@ -33,7 +47,7 @@ use:
|
|||
$ nix-shell --arg doProfiling true
|
||||
$ cabal configure --enable-tests --enable-profiling --flags=tracing
|
||||
$ cabal build
|
||||
$ ./dist/build/hnix/hnix -v5 <args> +RTS -xc
|
||||
$ ./dist/build/hnix/hnix -v5 --trace <args> +RTS -xc
|
||||
```
|
||||
|
||||
Note that this will run quite slowly, but will give the most information as to
|
||||
|
|
624
diagram4.svg
624
diagram4.svg
|
@ -1,624 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (0)
|
||||
-->
|
||||
<!-- Title: %3 Pages: 1 -->
|
||||
<svg width="1006pt" height="962pt"
|
||||
viewBox="0.00 0.00 1005.78 962.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 958)">
|
||||
<title>%3</title>
|
||||
<!-- parser -->
|
||||
<g id="node1" class="node">
|
||||
<title>parser</title>
|
||||
<polygon fill="#ffff00" stroke="#000000" points="684,-457 540,-457 540,-421 684,-421 684,-457"/>
|
||||
<text text-anchor="middle" x="612" y="-435.3" font-family="Times,serif" font-size="14.00" fill="#000000">Parser</text>
|
||||
</g>
|
||||
<!-- expr -->
|
||||
<g id="node4" class="node">
|
||||
<title>expr</title>
|
||||
<polygon fill="#ffff00" stroke="#000000" points="684,-349 540,-349 540,-313 684,-313 684,-349"/>
|
||||
<text text-anchor="middle" x="612" y="-327.3" font-family="Times,serif" font-size="14.00" fill="#000000">Expressions</text>
|
||||
</g>
|
||||
<!-- parser->expr -->
|
||||
<g id="edge49" class="edge">
|
||||
<title>parser->expr</title>
|
||||
<path fill="none" stroke="#000000" d="M539.9728,-420.762C532.7984,-416.1215 526.5121,-410.3008 522,-403 513.5883,-389.3896 513.5883,-380.6104 522,-367 524.6791,-362.6651 527.9836,-358.8521 531.7281,-355.4981"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="534.125,-358.0728 539.9728,-349.238 529.8919,-352.4977 534.125,-358.0728"/>
|
||||
</g>
|
||||
<!-- support -->
|
||||
<g id="node8" class="node">
|
||||
<title>support</title>
|
||||
<polygon fill="#ffff00" stroke="#000000" points="872.5928,-630 728.5928,-630 728.5928,-594 872.5928,-594 872.5928,-630"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-608.3" font-family="Times,serif" font-size="14.00" fill="#000000">Supporting Abstractions</text>
|
||||
</g>
|
||||
<!-- parser->support -->
|
||||
<g id="edge42" class="edge">
|
||||
<title>parser->support</title>
|
||||
<path fill="none" stroke="#000000" d="M673.1876,-457.0009C677.1381,-459.6085 680.8052,-462.5904 684,-466 721.7816,-506.321 681.5085,-545.3561 720,-585 720.9251,-585.9528 721.8848,-586.872 722.8755,-587.7588"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="720.9373,-590.6817 731.0181,-593.9415 725.1704,-585.1067 720.9373,-590.6817"/>
|
||||
</g>
|
||||
<!-- Parser.hs -->
|
||||
<g id="node20" class="node">
|
||||
<title>Parser.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-450" rx="35.9954" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-446.3" font-family="Times,serif" font-size="14.00" fill="#000000">Parser.hs</text>
|
||||
</g>
|
||||
<!-- parser->Parser.hs -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>parser->Parser.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M684.1061,-443.2057C707.8765,-444.5922 733.6414,-446.0949 754.8815,-447.3338"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="754.7296,-450.8308 764.9165,-447.9191 755.1373,-443.8427 754.7296,-450.8308"/>
|
||||
</g>
|
||||
<!-- Parser/Library.hs -->
|
||||
<g id="node21" class="node">
|
||||
<title>Parser/Library.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-558" rx="57.6901" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-554.3" font-family="Times,serif" font-size="14.00" fill="#000000">Parser/Library.hs</text>
|
||||
</g>
|
||||
<!-- parser->Parser/Library.hs -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>parser->Parser/Library.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M671.3559,-457.1823C675.872,-459.7609 680.1591,-462.686 684,-466 709.0033,-487.5732 694.6177,-509.874 720,-531 726.603,-536.4957 734.3708,-540.8882 742.4323,-544.395"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="741.39,-547.7453 751.9783,-548.1179 743.9334,-541.2237 741.39,-547.7453"/>
|
||||
</g>
|
||||
<!-- Parser/Operators.hs -->
|
||||
<g id="node22" class="node">
|
||||
<title>Parser/Operators.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-504" rx="64.189" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-500.3" font-family="Times,serif" font-size="14.00" fill="#000000">Parser/Operators.hs</text>
|
||||
</g>
|
||||
<!-- parser->Parser/Operators.hs -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>parser->Parser/Operators.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M662.7655,-457.0389C680.8149,-463.4057 701.2949,-470.5764 720,-477 729.4204,-480.2351 739.476,-483.6413 749.177,-486.9034"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="748.1292,-490.2436 758.7231,-490.1059 750.3556,-483.6071 748.1292,-490.2436"/>
|
||||
</g>
|
||||
<!-- value -->
|
||||
<g id="node2" class="node">
|
||||
<title>value</title>
|
||||
<polygon fill="#ffff00" stroke="#000000" points="684,-695 540,-695 540,-659 684,-659 684,-695"/>
|
||||
<text text-anchor="middle" x="612" y="-673.3" font-family="Times,serif" font-size="14.00" fill="#000000">Values</text>
|
||||
</g>
|
||||
<!-- value->expr -->
|
||||
<g id="edge50" class="edge">
|
||||
<title>value->expr</title>
|
||||
<path fill="none" stroke="#000000" d="M577.1364,-658.7272C556.9771,-646.0631 533.4053,-627.1432 522,-603 510.7995,-579.2902 508.2142,-389.306 522,-367 524.6791,-362.6651 527.9836,-358.8521 531.7281,-355.4981"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="534.125,-358.0728 539.9728,-349.238 529.8919,-352.4977 534.125,-358.0728"/>
|
||||
</g>
|
||||
<!-- value->support -->
|
||||
<g id="edge43" class="edge">
|
||||
<title>value->support</title>
|
||||
<path fill="none" stroke="#000000" d="M662.7655,-658.9611C680.8149,-652.5943 701.2949,-645.4236 720,-639 725.4538,-637.1271 731.1205,-635.1968 736.808,-633.2704"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="738.0111,-636.5584 746.3655,-630.0427 735.7713,-629.9264 738.0111,-636.5584"/>
|
||||
</g>
|
||||
<!-- Convert.hs -->
|
||||
<g id="node23" class="node">
|
||||
<title>Convert.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-774" rx="40.0939" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-770.3" font-family="Times,serif" font-size="14.00" fill="#000000">Convert.hs</text>
|
||||
</g>
|
||||
<!-- value->Convert.hs -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>value->Convert.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M668.8595,-695.0797C674.1734,-697.7169 679.3155,-700.682 684,-704 704.3394,-718.4063 699.4081,-732.957 720,-747 730.191,-753.9499 742.3199,-759.2399 754.0344,-763.213"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="753.1365,-766.5994 763.7255,-766.2483 755.2287,-759.9194 753.1365,-766.5994"/>
|
||||
</g>
|
||||
<!-- Normal.hs -->
|
||||
<g id="node24" class="node">
|
||||
<title>Normal.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-720" rx="39.7935" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-716.3" font-family="Times,serif" font-size="14.00" fill="#000000">Normal.hs</text>
|
||||
</g>
|
||||
<!-- value->Normal.hs -->
|
||||
<g id="edge14" class="edge">
|
||||
<title>value->Normal.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M684.1061,-693.4405C707.8765,-698.8603 733.6414,-704.7348 754.8815,-709.5776"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="754.3886,-713.055 764.9165,-711.8656 755.9448,-706.2301 754.3886,-713.055"/>
|
||||
</g>
|
||||
<!-- Value.hs -->
|
||||
<g id="node25" class="node">
|
||||
<title>Value.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-666" rx="35.194" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-662.3" font-family="Times,serif" font-size="14.00" fill="#000000">Value.hs</text>
|
||||
</g>
|
||||
<!-- value->Value.hs -->
|
||||
<g id="edge15" class="edge">
|
||||
<title>value->Value.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M684.1061,-672.7943C708.1446,-671.3922 734.2229,-669.8711 755.5985,-668.6244"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="755.9054,-672.1125 765.6846,-668.0361 755.4978,-665.1244 755.9054,-672.1125"/>
|
||||
</g>
|
||||
<!-- eval -->
|
||||
<g id="node3" class="node">
|
||||
<title>eval</title>
|
||||
<polygon fill="#ffff00" stroke="#000000" points="684,-403 540,-403 540,-367 684,-367 684,-403"/>
|
||||
<text text-anchor="middle" x="612" y="-381.3" font-family="Times,serif" font-size="14.00" fill="#000000">Core Evaluator</text>
|
||||
</g>
|
||||
<!-- eval->expr -->
|
||||
<g id="edge51" class="edge">
|
||||
<title>eval->expr</title>
|
||||
<path fill="none" stroke="#000000" d="M612,-366.7902C612,-364.3082 612,-361.8262 612,-359.3443"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="615.5001,-359.1406 612,-349.1406 608.5001,-359.1407 615.5001,-359.1406"/>
|
||||
</g>
|
||||
<!-- eval->support -->
|
||||
<g id="edge44" class="edge">
|
||||
<title>eval->support</title>
|
||||
<path fill="none" stroke="#000000" d="M674.1928,-403.1551C677.8088,-405.7237 681.133,-408.655 684,-412 735.1087,-471.6306 667.8408,-526.2861 720,-585 720.6431,-585.724 721.3063,-586.4285 721.9879,-587.1143"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="720.0194,-590.0308 729.935,-593.7634 724.5113,-584.662 720.0194,-590.0308"/>
|
||||
</g>
|
||||
<!-- Context.hs -->
|
||||
<g id="node38" class="node">
|
||||
<title>Context.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-396" rx="40.0939" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-392.3" font-family="Times,serif" font-size="14.00" fill="#000000">Context.hs</text>
|
||||
</g>
|
||||
<!-- eval->Context.hs -->
|
||||
<g id="edge38" class="edge">
|
||||
<title>eval->Context.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M684.1061,-389.2057C706.1551,-390.4918 729.9201,-391.8779 750.1982,-393.0606"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="750.2701,-396.5707 760.457,-393.659 750.6778,-389.5826 750.2701,-396.5707"/>
|
||||
</g>
|
||||
<!-- Eval.hs -->
|
||||
<g id="node39" class="node">
|
||||
<title>Eval.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-342" rx="31.3957" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-338.3" font-family="Times,serif" font-size="14.00" fill="#000000">Eval.hs</text>
|
||||
</g>
|
||||
<!-- eval->Eval.hs -->
|
||||
<g id="edge39" class="edge">
|
||||
<title>eval->Eval.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M684.1061,-368.5595C710.4372,-362.5559 739.2156,-355.9943 761.5801,-350.8951"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="762.4008,-354.2979 771.3725,-348.6624 760.8446,-347.473 762.4008,-354.2979"/>
|
||||
</g>
|
||||
<!-- expr->support -->
|
||||
<g id="edge45" class="edge">
|
||||
<title>expr->support</title>
|
||||
<path fill="none" stroke="#000000" d="M674.377,-349.0011C677.9498,-351.6058 681.2139,-354.5873 684,-358 748.5999,-437.1291 654.0056,-507.0301 720,-585 720.6256,-585.7391 721.2721,-586.4581 721.938,-587.1575"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="719.8985,-590.0215 729.7478,-593.9257 724.483,-584.7316 719.8985,-590.0215"/>
|
||||
</g>
|
||||
<!-- Atoms.hs -->
|
||||
<g id="node11" class="node">
|
||||
<title>Atoms.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-288" rx="36.2938" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-284.3" font-family="Times,serif" font-size="14.00" fill="#000000">Atoms.hs</text>
|
||||
</g>
|
||||
<!-- expr->Atoms.hs -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>expr->Atoms.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M684.1061,-314.5595C708.8823,-308.9104 735.8253,-302.7673 757.5528,-297.8133"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="758.4823,-301.1913 767.4541,-295.5558 756.9262,-294.3664 758.4823,-301.1913"/>
|
||||
</g>
|
||||
<!-- Expr.hs -->
|
||||
<g id="node12" class="node">
|
||||
<title>Expr.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-234" rx="31.6951" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-230.3" font-family="Times,serif" font-size="14.00" fill="#000000">Expr.hs</text>
|
||||
</g>
|
||||
<!-- expr->Expr.hs -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>expr->Expr.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M636.2632,-312.7258C657.4936,-297.3718 689.6073,-275.6502 720,-261 733.1346,-254.6687 748.1368,-249.2024 761.608,-244.8766"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="763.0382,-248.0977 771.5548,-241.7955 760.967,-241.4112 763.0382,-248.0977"/>
|
||||
</g>
|
||||
<!-- Expr/Shorthands.hs -->
|
||||
<g id="node13" class="node">
|
||||
<title>Expr/Shorthands.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-180" rx="64.189" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-176.3" font-family="Times,serif" font-size="14.00" fill="#000000">Expr/Shorthands.hs</text>
|
||||
</g>
|
||||
<!-- expr->Expr/Shorthands.hs -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>expr->Expr/Shorthands.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M623.3126,-312.6959C640.8324,-285.8004 677.0276,-235.6953 720,-207 726.805,-202.4559 734.4434,-198.6135 742.2349,-195.3821"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="743.6781,-198.5775 751.769,-191.7374 741.1785,-192.039 743.6781,-198.5775"/>
|
||||
</g>
|
||||
<!-- Expr/Types.hs -->
|
||||
<g id="node14" class="node">
|
||||
<title>Expr/Types.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-126" rx="50.0912" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-122.3" font-family="Times,serif" font-size="14.00" fill="#000000">Expr/Types.hs</text>
|
||||
</g>
|
||||
<!-- expr->Expr/Types.hs -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>expr->Expr/Types.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M618.0957,-312.9934C631.0988,-277.2519 664.9433,-197.0101 720,-153 727.8666,-146.7117 737.267,-141.8573 746.8242,-138.1192"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="748.1202,-141.3734 756.3826,-134.7414 745.7879,-134.7734 748.1202,-141.3734"/>
|
||||
</g>
|
||||
<!-- Expr/Types/Annotated.hs -->
|
||||
<g id="node15" class="node">
|
||||
<title>Expr/Types/Annotated.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-72" rx="80.6858" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-68.3" font-family="Times,serif" font-size="14.00" fill="#000000">Expr/Types/Annotated.hs</text>
|
||||
</g>
|
||||
<!-- expr->Expr/Types/Annotated.hs -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>expr->Expr/Types/Annotated.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M615.3887,-312.6914C624.3824,-269.2176 652.9103,-158.9419 720,-99 724.1952,-95.2517 728.9284,-92.0211 733.9461,-89.237"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="735.7877,-92.2324 743.2308,-84.6925 732.7103,-85.9451 735.7877,-92.2324"/>
|
||||
</g>
|
||||
<!-- Strings.hs -->
|
||||
<g id="node16" class="node">
|
||||
<title>Strings.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-18" rx="37.8943" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-14.3" font-family="Times,serif" font-size="14.00" fill="#000000">Strings.hs</text>
|
||||
</g>
|
||||
<!-- expr->Strings.hs -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>expr->Strings.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M613.5796,-312.6825C618.8819,-262.5194 640.4767,-121.5725 720,-45 729.3938,-35.9547 741.9064,-29.9369 754.2649,-25.9342"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="755.4229,-29.2437 764.0807,-23.1369 753.5043,-22.5117 755.4229,-29.2437"/>
|
||||
</g>
|
||||
<!-- pretty -->
|
||||
<g id="node5" class="node">
|
||||
<title>pretty</title>
|
||||
<polygon fill="#ffff00" stroke="#000000" points="684,-857 540,-857 540,-821 684,-821 684,-857"/>
|
||||
<text text-anchor="middle" x="612" y="-835.3" font-family="Times,serif" font-size="14.00" fill="#000000">Pretty Printer</text>
|
||||
</g>
|
||||
<!-- pretty->value -->
|
||||
<g id="edge56" class="edge">
|
||||
<title>pretty->value</title>
|
||||
<path fill="none" stroke="#000000" d="M539.9728,-820.762C532.7984,-816.1215 526.5121,-810.3008 522,-803 500.9708,-768.974 500.9708,-747.026 522,-713 524.6791,-708.6651 527.9836,-704.8521 531.7281,-701.4981"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="534.125,-704.0728 539.9728,-695.238 529.8919,-698.4977 534.125,-704.0728"/>
|
||||
</g>
|
||||
<!-- pretty->expr -->
|
||||
<g id="edge52" class="edge">
|
||||
<title>pretty->expr</title>
|
||||
<path fill="none" stroke="#000000" d="M539.9728,-820.762C532.7984,-816.1215 526.5121,-810.3008 522,-803 509.2656,-782.3953 509.2656,-387.6047 522,-367 524.6791,-362.6651 527.9836,-358.8521 531.7281,-355.4981"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="534.125,-358.0728 539.9728,-349.238 529.8919,-352.4977 534.125,-358.0728"/>
|
||||
</g>
|
||||
<!-- pretty->support -->
|
||||
<g id="edge46" class="edge">
|
||||
<title>pretty->support</title>
|
||||
<path fill="none" stroke="#000000" d="M674.1928,-820.8449C677.8088,-818.2763 681.133,-815.345 684,-812 735.1087,-752.3694 667.8408,-697.7139 720,-639 720.6431,-638.276 721.3063,-637.5715 721.9879,-636.8857"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="724.5113,-639.338 729.935,-630.2366 720.0194,-633.9692 724.5113,-639.338"/>
|
||||
</g>
|
||||
<!-- Pretty.hs -->
|
||||
<g id="node17" class="node">
|
||||
<title>Pretty.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-936" rx="35.194" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-932.3" font-family="Times,serif" font-size="14.00" fill="#000000">Pretty.hs</text>
|
||||
</g>
|
||||
<!-- pretty->Pretty.hs -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>pretty->Pretty.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M636.2632,-857.2742C657.4936,-872.6282 689.6073,-894.3498 720,-909 732.4991,-915.0249 746.6894,-920.2666 759.6422,-924.4875"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="758.6681,-927.8501 769.2575,-927.5123 760.7687,-921.1727 758.6681,-927.8501"/>
|
||||
</g>
|
||||
<!-- Render.hs -->
|
||||
<g id="node18" class="node">
|
||||
<title>Render.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-882" rx="38.1938" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-878.3" font-family="Times,serif" font-size="14.00" fill="#000000">Render.hs</text>
|
||||
</g>
|
||||
<!-- pretty->Render.hs -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>pretty->Render.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M684.1061,-855.4405C708.3436,-860.9668 734.6548,-866.9658 756.1285,-871.8619"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="755.4115,-875.2882 765.9394,-874.0989 756.9677,-868.4634 755.4115,-875.2882"/>
|
||||
</g>
|
||||
<!-- Render/Frame.hs -->
|
||||
<g id="node19" class="node">
|
||||
<title>Render/Frame.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="800.5928" cy="-828" rx="57.6901" ry="18"/>
|
||||
<text text-anchor="middle" x="800.5928" y="-824.3" font-family="Times,serif" font-size="14.00" fill="#000000">Render/Frame.hs</text>
|
||||
</g>
|
||||
<!-- pretty->Render/Frame.hs -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>pretty->Render/Frame.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M684.1061,-834.7943C700.2279,-833.854 717.2672,-832.8601 733.19,-831.9314"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="733.6923,-835.4081 743.4715,-831.3317 733.2846,-828.42 733.6923,-835.4081"/>
|
||||
</g>
|
||||
<!-- exec -->
|
||||
<g id="node6" class="node">
|
||||
<title>exec</title>
|
||||
<polygon fill="#ffff00" stroke="#000000" points="504,-657 360,-657 360,-621 504,-621 504,-657"/>
|
||||
<text text-anchor="middle" x="432" y="-635.3" font-family="Times,serif" font-size="14.00" fill="#000000">Executing Evaluator</text>
|
||||
</g>
|
||||
<!-- exec->value -->
|
||||
<g id="edge53" class="edge">
|
||||
<title>exec->value</title>
|
||||
<path fill="none" stroke="#000000" d="M504.1757,-654.2371C512.6116,-656.018 521.2652,-657.8449 529.8236,-659.6517"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="529.3008,-663.1183 539.8081,-661.7595 530.7467,-656.2693 529.3008,-663.1183"/>
|
||||
</g>
|
||||
<!-- exec->eval -->
|
||||
<g id="edge54" class="edge">
|
||||
<title>exec->eval</title>
|
||||
<path fill="none" stroke="#000000" d="M494.2965,-620.9325C497.8881,-618.3433 501.1786,-615.3835 504,-612 561.8421,-542.6348 482.1579,-481.3652 540,-412 540.6172,-411.2599 541.2568,-410.54 541.9171,-409.8398"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="544.4551,-412.271 549.7035,-403.0675 539.8612,-406.9893 544.4551,-412.271"/>
|
||||
</g>
|
||||
<!-- builtins -->
|
||||
<g id="node7" class="node">
|
||||
<title>builtins</title>
|
||||
<polygon fill="#ffff00" stroke="#000000" points="504,-603 360,-603 360,-567 504,-567 504,-603"/>
|
||||
<text text-anchor="middle" x="432" y="-581.3" font-family="Times,serif" font-size="14.00" fill="#000000">Built-in Functions</text>
|
||||
</g>
|
||||
<!-- exec->builtins -->
|
||||
<g id="edge55" class="edge">
|
||||
<title>exec->builtins</title>
|
||||
<path fill="none" stroke="#000000" d="M432,-620.7902C432,-618.3082 432,-615.8262 432,-613.3443"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="435.5001,-613.1406 432,-603.1406 428.5001,-613.1407 435.5001,-613.1406"/>
|
||||
</g>
|
||||
<!-- exec->support -->
|
||||
<g id="edge47" class="edge">
|
||||
<title>exec->support</title>
|
||||
<path fill="none" stroke="#000000" d="M504.3823,-633.6979C565.8763,-629.1934 654.1242,-622.7291 718.2921,-618.0287"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="718.6585,-621.5113 728.3761,-617.29 718.1471,-614.53 718.6585,-621.5113"/>
|
||||
</g>
|
||||
<!-- Effects.hs -->
|
||||
<g id="node40" class="node">
|
||||
<title>Effects.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="612" cy="-785" rx="37.8943" ry="18"/>
|
||||
<text text-anchor="middle" x="612" y="-781.3" font-family="Times,serif" font-size="14.00" fill="#000000">Effects.hs</text>
|
||||
</g>
|
||||
<!-- exec->Effects.hs -->
|
||||
<g id="edge40" class="edge">
|
||||
<title>exec->Effects.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M444.2194,-657.2095C462.3405,-682.949 498.6783,-729.9545 540,-758 548.8731,-764.0223 559.2668,-768.9236 569.3532,-772.8145"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="568.2755,-776.1463 578.8699,-776.2389 570.6456,-769.5597 568.2755,-776.1463"/>
|
||||
</g>
|
||||
<!-- Exec.hs -->
|
||||
<g id="node41" class="node">
|
||||
<title>Exec.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="612" cy="-731" rx="31.6951" ry="18"/>
|
||||
<text text-anchor="middle" x="612" y="-727.3" font-family="Times,serif" font-size="14.00" fill="#000000">Exec.hs</text>
|
||||
</g>
|
||||
<!-- exec->Exec.hs -->
|
||||
<g id="edge41" class="edge">
|
||||
<title>exec->Exec.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M459.1923,-657.2744C480.5772,-671.171 511.4311,-690.1899 540,-704 550.9696,-709.3026 563.2686,-714.256 574.5551,-718.4353"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="573.5596,-721.7969 584.154,-721.8979 575.935,-715.2122 573.5596,-721.7969"/>
|
||||
</g>
|
||||
<!-- builtins->value -->
|
||||
<g id="edge57" class="edge">
|
||||
<title>builtins->value</title>
|
||||
<path fill="none" stroke="#000000" d="M483.6174,-603.0424C490.5536,-605.8473 497.5095,-608.8625 504,-612 528.9978,-624.0838 555.745,-640.1556 576.3675,-653.2944"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="574.5044,-656.2575 584.8077,-658.7256 578.2923,-650.3709 574.5044,-656.2575"/>
|
||||
</g>
|
||||
<!-- builtins->support -->
|
||||
<g id="edge48" class="edge">
|
||||
<title>builtins->support</title>
|
||||
<path fill="none" stroke="#000000" d="M484.0458,-566.9223C535.9823,-551.7496 617.4208,-535.8069 684,-558 702.9737,-564.3246 702.2914,-575.7045 720,-585 723.2623,-586.7124 726.6549,-588.3477 730.1213,-589.9045"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="728.8574,-593.17 739.4309,-593.8415 731.5839,-586.7228 728.8574,-593.17"/>
|
||||
</g>
|
||||
<!-- Builtins.hs -->
|
||||
<g id="node26" class="node">
|
||||
<title>Builtins.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="612" cy="-493" rx="40.0939" ry="18"/>
|
||||
<text text-anchor="middle" x="612" y="-489.3" font-family="Times,serif" font-size="14.00" fill="#000000">Builtins.hs</text>
|
||||
</g>
|
||||
<!-- builtins->Builtins.hs -->
|
||||
<g id="edge16" class="edge">
|
||||
<title>builtins->Builtins.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M477.4037,-566.8372C486.4195,-562.6739 495.668,-557.9903 504,-553 521.3894,-542.5849 522.6106,-535.4151 540,-525 549.8832,-519.0806 561.056,-513.5927 571.6003,-508.893"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="573.2609,-511.9883 581.0522,-504.8087 570.4842,-505.5625 573.2609,-511.9883"/>
|
||||
</g>
|
||||
<!-- XML.hs -->
|
||||
<g id="node27" class="node">
|
||||
<title>XML.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="612" cy="-585" rx="33.5952" ry="18"/>
|
||||
<text text-anchor="middle" x="612" y="-581.3" font-family="Times,serif" font-size="14.00" fill="#000000">XML.hs</text>
|
||||
</g>
|
||||
<!-- builtins->XML.hs -->
|
||||
<g id="edge17" class="edge">
|
||||
<title>builtins->XML.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M504.1757,-585C525.6322,-585 548.4967,-585 567.6236,-585"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="567.8324,-588.5001 577.8324,-585 567.8324,-581.5001 567.8324,-588.5001"/>
|
||||
</g>
|
||||
<!-- Frames.hs -->
|
||||
<g id="node28" class="node">
|
||||
<title>Frames.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="957.4821" cy="-720" rx="38.1938" ry="18"/>
|
||||
<text text-anchor="middle" x="957.4821" y="-716.3" font-family="Times,serif" font-size="14.00" fill="#000000">Frames.hs</text>
|
||||
</g>
|
||||
<!-- support->Frames.hs -->
|
||||
<g id="edge18" class="edge">
|
||||
<title>support->Frames.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M867.1013,-630.1879C872.0829,-632.7602 876.8493,-635.6827 881.1857,-639 904.0953,-656.5257 896.8134,-672.5802 917.1857,-693 919.6391,-695.4591 922.3481,-697.8268 925.1667,-700.0686"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="923.1467,-702.9276 933.2787,-706.0249 927.2896,-697.2852 923.1467,-702.9276"/>
|
||||
</g>
|
||||
<!-- Scope.hs -->
|
||||
<g id="node29" class="node">
|
||||
<title>Scope.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="957.4821" cy="-666" rx="35.194" ry="18"/>
|
||||
<text text-anchor="middle" x="957.4821" y="-662.3" font-family="Times,serif" font-size="14.00" fill="#000000">Scope.hs</text>
|
||||
</g>
|
||||
<!-- support->Scope.hs -->
|
||||
<g id="edge19" class="edge">
|
||||
<title>support->Scope.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M854.8248,-630.0293C863.6444,-633.0014 872.6751,-636.0688 881.1857,-639 893.4328,-643.2182 906.7532,-647.8996 918.7859,-652.1637"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="917.9438,-655.5788 928.5385,-655.6281 920.2869,-648.9826 917.9438,-655.5788"/>
|
||||
</g>
|
||||
<!-- Thunk.hs -->
|
||||
<g id="node30" class="node">
|
||||
<title>Thunk.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="957.4821" cy="-612" rx="36.2938" ry="18"/>
|
||||
<text text-anchor="middle" x="957.4821" y="-608.3" font-family="Times,serif" font-size="14.00" fill="#000000">Thunk.hs</text>
|
||||
</g>
|
||||
<!-- support->Thunk.hs -->
|
||||
<g id="edge20" class="edge">
|
||||
<title>support->Thunk.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M872.609,-612C885.5681,-612 898.7628,-612 910.7655,-612"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="910.9708,-615.5001 920.9707,-612 910.9707,-608.5001 910.9708,-615.5001"/>
|
||||
</g>
|
||||
<!-- Options.hs -->
|
||||
<g id="node31" class="node">
|
||||
<title>Options.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="957.4821" cy="-558" rx="40.0939" ry="18"/>
|
||||
<text text-anchor="middle" x="957.4821" y="-554.3" font-family="Times,serif" font-size="14.00" fill="#000000">Options.hs</text>
|
||||
</g>
|
||||
<!-- support->Options.hs -->
|
||||
<g id="edge21" class="edge">
|
||||
<title>support->Options.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M854.8248,-593.9707C863.6444,-590.9986 872.6751,-587.9312 881.1857,-585 892.591,-581.0717 904.9273,-576.7417 916.2874,-572.7211"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="917.7172,-575.9277 925.9713,-569.2854 915.3766,-569.3306 917.7172,-575.9277"/>
|
||||
</g>
|
||||
<!-- Utils.hs -->
|
||||
<g id="node32" class="node">
|
||||
<title>Utils.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="957.4821" cy="-504" rx="31.6951" ry="18"/>
|
||||
<text text-anchor="middle" x="957.4821" y="-500.3" font-family="Times,serif" font-size="14.00" fill="#000000">Utils.hs</text>
|
||||
</g>
|
||||
<!-- support->Utils.hs -->
|
||||
<g id="edge22" class="edge">
|
||||
<title>support->Utils.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M867.1013,-593.8121C872.0829,-591.2398 876.8493,-588.3173 881.1857,-585 904.0953,-567.4743 896.8134,-551.4198 917.1857,-531 920.048,-528.131 923.2582,-525.3865 926.5844,-522.8211"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="928.8527,-525.5022 934.9591,-516.8441 924.7863,-519.8045 928.8527,-525.5022"/>
|
||||
</g>
|
||||
<!-- features -->
|
||||
<g id="node9" class="node">
|
||||
<title>features</title>
|
||||
<polygon fill="#ffff00" stroke="#000000" points="324,-430 180,-430 180,-394 324,-394 324,-430"/>
|
||||
<text text-anchor="middle" x="252" y="-408.3" font-family="Times,serif" font-size="14.00" fill="#000000">Other Features</text>
|
||||
</g>
|
||||
<!-- Cache.hs -->
|
||||
<g id="node33" class="node">
|
||||
<title>Cache.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="432" cy="-493" rx="35.9954" ry="18"/>
|
||||
<text text-anchor="middle" x="432" y="-489.3" font-family="Times,serif" font-size="14.00" fill="#000000">Cache.hs</text>
|
||||
</g>
|
||||
<!-- features->Cache.hs -->
|
||||
<g id="edge23" class="edge">
|
||||
<title>features->Cache.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M286.0972,-430.1996C307.1371,-441.1401 334.8275,-455.0231 360,-466 370.4933,-470.5758 382.0353,-475.1156 392.746,-479.13"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="391.7014,-482.4752 402.2947,-482.655 394.1257,-475.9084 391.7014,-482.4752"/>
|
||||
</g>
|
||||
<!-- Lint.hs -->
|
||||
<g id="node34" class="node">
|
||||
<title>Lint.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="432" cy="-331" rx="29.795" ry="18"/>
|
||||
<text text-anchor="middle" x="432" y="-327.3" font-family="Times,serif" font-size="14.00" fill="#000000">Lint.hs</text>
|
||||
</g>
|
||||
<!-- features->Lint.hs -->
|
||||
<g id="edge24" class="edge">
|
||||
<title>features->Lint.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M286.0972,-393.8004C307.1371,-382.8599 334.8275,-368.9769 360,-358 371.7591,-352.8722 384.8351,-347.7897 396.5824,-343.441"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="397.8851,-346.6915 406.0796,-339.9758 395.4857,-340.1155 397.8851,-346.6915"/>
|
||||
</g>
|
||||
<!-- Reduce.hs -->
|
||||
<g id="node35" class="node">
|
||||
<title>Reduce.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="432" cy="-439" rx="38.9931" ry="18"/>
|
||||
<text text-anchor="middle" x="432" y="-435.3" font-family="Times,serif" font-size="14.00" fill="#000000">Reduce.hs</text>
|
||||
</g>
|
||||
<!-- features->Reduce.hs -->
|
||||
<g id="edge25" class="edge">
|
||||
<title>features->Reduce.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M324.1757,-422.8264C344.6419,-425.8963 366.3892,-429.1584 384.9519,-431.9428"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="384.4999,-435.4141 394.9085,-433.4363 385.5384,-428.4915 384.4999,-435.4141"/>
|
||||
</g>
|
||||
<!-- Type/... -->
|
||||
<g id="node36" class="node">
|
||||
<title>Type/...</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="432" cy="-277" rx="31.6951" ry="18"/>
|
||||
<text text-anchor="middle" x="432" y="-273.3" font-family="Times,serif" font-size="14.00" fill="#000000">Type/...</text>
|
||||
</g>
|
||||
<!-- features->Type/... -->
|
||||
<g id="edge26" class="edge">
|
||||
<title>features->Type/...</title>
|
||||
<path fill="none" stroke="#000000" d="M265.8767,-393.9507C284.8423,-370.3662 320.9848,-329.1224 360,-304 370.1572,-297.4597 382.13,-292.1695 393.3658,-288.0628"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="394.6661,-291.3169 402.9858,-284.7569 392.3911,-284.6969 394.6661,-291.3169"/>
|
||||
</g>
|
||||
<!-- TH.hs -->
|
||||
<g id="node37" class="node">
|
||||
<title>TH.hs</title>
|
||||
<ellipse fill="none" stroke="transparent" cx="432" cy="-385" rx="27.0966" ry="18"/>
|
||||
<text text-anchor="middle" x="432" y="-381.3" font-family="Times,serif" font-size="14.00" fill="#000000">TH.hs</text>
|
||||
</g>
|
||||
<!-- features->TH.hs -->
|
||||
<g id="edge27" class="edge">
|
||||
<title>features->TH.hs</title>
|
||||
<path fill="none" stroke="#000000" d="M324.1757,-401.1736C348.4962,-397.5256 374.6255,-393.6062 395.0705,-390.5394"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="395.8339,-393.9642 405.2041,-389.0194 394.7955,-387.0416 395.8339,-393.9642"/>
|
||||
</g>
|
||||
<!-- main -->
|
||||
<g id="node10" class="node">
|
||||
<title>main</title>
|
||||
<polygon fill="#00ff00" stroke="#000000" points="144,-607 0,-607 0,-571 144,-571 144,-607"/>
|
||||
<text text-anchor="middle" x="72" y="-585.3" font-family="Times,serif" font-size="14.00" fill="#000000">Top-Level Driver</text>
|
||||
</g>
|
||||
<!-- main->parser -->
|
||||
<g id="edge58" class="edge">
|
||||
<title>main->parser</title>
|
||||
<path fill="none" stroke="#000000" d="M144.105,-580.6785C259.1187,-566.9314 474.2378,-539.1014 504,-520 528.275,-504.4203 517.4051,-483.9297 540,-466 541.5686,-464.7552 543.2006,-463.5637 544.8832,-462.4233"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="546.8969,-465.2963 553.658,-457.1392 543.2857,-459.2997 546.8969,-465.2963"/>
|
||||
</g>
|
||||
<!-- main->pretty -->
|
||||
<g id="edge59" class="edge">
|
||||
<title>main->pretty</title>
|
||||
<path fill="none" stroke="#000000" d="M107.3382,-607.1245C184.7581,-646.5457 375.5679,-742.1457 540,-812 544.1201,-813.7503 548.3961,-815.5053 552.7165,-817.2337"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="551.615,-820.5614 562.2022,-820.963 554.1763,-814.0468 551.615,-820.5614"/>
|
||||
</g>
|
||||
<!-- main->exec -->
|
||||
<g id="edge60" class="edge">
|
||||
<title>main->exec</title>
|
||||
<path fill="none" stroke="#000000" d="M144.4183,-599.0581C203.7397,-607.2972 287.6847,-618.9562 349.5743,-627.552"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="349.311,-631.0489 359.6974,-628.958 350.274,-624.1155 349.311,-631.0489"/>
|
||||
</g>
|
||||
<!-- main->features -->
|
||||
<g id="edge61" class="edge">
|
||||
<title>main->features</title>
|
||||
<path fill="none" stroke="#000000" d="M90.5852,-570.7246C122.8708,-538.977 189.3763,-473.5799 226.1444,-437.4247"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="228.8396,-439.683 233.5159,-430.176 223.9316,-434.6919 228.8396,-439.683"/>
|
||||
</g>
|
||||
<!-- Cache.hs->parser -->
|
||||
<g id="edge28" class="edge">
|
||||
<title>Cache.hs->parser</title>
|
||||
<path fill="none" stroke="#000000" d="M462.9431,-483.7171C484.6076,-477.2177 514.4463,-468.2661 541.738,-460.0786"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="543.0853,-463.3286 551.6578,-457.1027 541.0738,-456.6238 543.0853,-463.3286"/>
|
||||
</g>
|
||||
<!-- Cache.hs->expr -->
|
||||
<g id="edge29" class="edge">
|
||||
<title>Cache.hs->expr</title>
|
||||
<path fill="none" stroke="#000000" d="M465.9687,-486.881C479.3511,-482.9283 493.9027,-476.4782 504,-466 539.1088,-429.5668 504.8912,-394.4332 540,-358 540.9119,-357.0537 541.8601,-356.1403 542.8405,-355.2586"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="545.0868,-357.9472 550.9184,-349.1016 540.8435,-352.38 545.0868,-357.9472"/>
|
||||
</g>
|
||||
<!-- Lint.hs->eval -->
|
||||
<g id="edge30" class="edge">
|
||||
<title>Lint.hs->eval</title>
|
||||
<path fill="none" stroke="#000000" d="M458.9478,-339.0843C480.8881,-345.6664 512.875,-355.2625 541.9404,-363.9821"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="541.0826,-367.3788 551.6666,-366.9 543.0941,-360.674 541.0826,-367.3788"/>
|
||||
</g>
|
||||
<!-- Lint.hs->expr -->
|
||||
<g id="edge31" class="edge">
|
||||
<title>Lint.hs->expr</title>
|
||||
<path fill="none" stroke="#000000" d="M462.128,-331C480.693,-331 505.4786,-331 529.5403,-331"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="529.7879,-334.5001 539.7878,-331 529.7878,-327.5001 529.7879,-334.5001"/>
|
||||
</g>
|
||||
<!-- Reduce.hs->parser -->
|
||||
<g id="edge32" class="edge">
|
||||
<title>Reduce.hs->parser</title>
|
||||
<path fill="none" stroke="#000000" d="M471.0573,-439C488.2172,-439 509.0613,-439 529.3981,-439"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="529.6421,-442.5001 539.6421,-439 529.6421,-435.5001 529.6421,-442.5001"/>
|
||||
</g>
|
||||
<!-- Reduce.hs->expr -->
|
||||
<g id="edge33" class="edge">
|
||||
<title>Reduce.hs->expr</title>
|
||||
<path fill="none" stroke="#000000" d="M466.8705,-430.7543C479.4696,-426.5875 493.2287,-420.5473 504,-412 526.5949,-394.0703 517.4051,-375.9297 540,-358 541.5686,-356.7552 543.2006,-355.5637 544.8832,-354.4233"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="546.8969,-357.2963 553.658,-349.1392 543.2857,-351.2997 546.8969,-357.2963"/>
|
||||
</g>
|
||||
<!-- Type/...->eval -->
|
||||
<g id="edge34" class="edge">
|
||||
<title>Type/...->eval</title>
|
||||
<path fill="none" stroke="#000000" d="M461.8077,-283.6488C475.674,-287.8169 491.7647,-294.2909 504,-304 526.5949,-321.9297 517.4051,-340.0703 540,-358 541.5686,-359.2448 543.2006,-360.4363 544.8832,-361.5767"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="543.2857,-364.7003 553.658,-366.8608 546.8969,-358.7037 543.2857,-364.7003"/>
|
||||
</g>
|
||||
<!-- Type/...->expr -->
|
||||
<g id="edge35" class="edge">
|
||||
<title>Type/...->expr</title>
|
||||
<path fill="none" stroke="#000000" d="M460.5215,-285.5565C482.4245,-292.1273 513.6329,-301.4899 542.0365,-310.0109"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="541.3623,-313.4627 551.9463,-312.9839 543.3738,-306.758 541.3623,-313.4627"/>
|
||||
</g>
|
||||
<!-- TH.hs->parser -->
|
||||
<g id="edge36" class="edge">
|
||||
<title>TH.hs->parser</title>
|
||||
<path fill="none" stroke="#000000" d="M457.0282,-392.5085C479.0813,-399.1244 512.2785,-409.0836 542.2975,-418.0892"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="541.33,-421.4531 551.914,-420.9742 543.3415,-414.7483 541.33,-421.4531"/>
|
||||
</g>
|
||||
<!-- TH.hs->expr -->
|
||||
<g id="edge37" class="edge">
|
||||
<title>TH.hs->expr</title>
|
||||
<path fill="none" stroke="#000000" d="M457.0282,-377.4915C479.0813,-370.8756 512.2785,-360.9164 542.2975,-351.9108"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="543.3415,-355.2517 551.914,-349.0258 541.33,-348.5469 543.3415,-355.2517"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 36 KiB |
|
@ -2,7 +2,7 @@
|
|||
--
|
||||
-- see: https://github.com/sol/hpack
|
||||
--
|
||||
-- hash: 5eba5b1b4e2ae5297dcad048052e5bc02fc2f42aa37016fbea866ecbf3f4a380
|
||||
-- hash: 5dd7aaae46b28fedd3791ab641dc5093bf7e2bca549578aea96ec23ed791ed22
|
||||
|
||||
name: hnix
|
||||
version: 0.5.0
|
||||
|
@ -60,8 +60,6 @@ library
|
|||
Nix.Normal
|
||||
Nix.Options
|
||||
Nix.Parser
|
||||
Nix.Parser.Library
|
||||
Nix.Parser.Operators
|
||||
Nix.Pretty
|
||||
Nix.Reduce
|
||||
Nix.Render
|
||||
|
@ -206,6 +204,7 @@ test-suite hnix-tests
|
|||
, megaparsec
|
||||
, mtl
|
||||
, optparse-applicative
|
||||
, pretty-show
|
||||
, process
|
||||
, quickcheck-instances
|
||||
, serialise
|
||||
|
|
|
@ -116,7 +116,7 @@ main = do
|
|||
A.encodeToLazyText (stripAnnotation expr)
|
||||
|
||||
| verbose opts >= DebugInfo =
|
||||
liftIO $ print $ stripAnnotation expr
|
||||
liftIO $ putStr $ PS.ppShow $ stripAnnotation expr
|
||||
|
||||
| cache opts, Just path <- mpath =
|
||||
liftIO $ writeCache (addExtension (dropExtension path) "nixc") expr
|
||||
|
|
|
@ -134,6 +134,7 @@ tests:
|
|||
- Diff
|
||||
- megaparsec
|
||||
- tasty-quickcheck
|
||||
- pretty-show
|
||||
|
||||
benchmarks:
|
||||
hnix-benchmarks:
|
||||
|
|
|
@ -37,7 +37,6 @@ import Nix.Frames
|
|||
import Nix.Normal
|
||||
import Nix.Options
|
||||
import Nix.Parser
|
||||
import Nix.Parser.Library (Result(..))
|
||||
import Nix.Pretty
|
||||
import Nix.Reduce
|
||||
import Nix.Render.Frame
|
||||
|
|
|
@ -56,7 +56,6 @@ import Lens.Family2
|
|||
import Lens.Family2.Stock (_1)
|
||||
import Lens.Family2.TH
|
||||
import Nix.Atoms
|
||||
import Nix.Parser.Library (SourcePos(..))
|
||||
import Nix.Utils
|
||||
import Text.Megaparsec.Pos
|
||||
import Text.Read.Deriving
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
module Nix.Expr.Types.Annotated
|
||||
( module Nix.Expr.Types.Annotated
|
||||
, module Data.Functor.Compose
|
||||
, module Nix.Parser.Library
|
||||
, SourcePos(..), unPos, mkPos
|
||||
)where
|
||||
|
||||
|
@ -39,8 +38,8 @@ import Data.Text (Text, pack)
|
|||
import GHC.Generics
|
||||
import Nix.Atoms
|
||||
import Nix.Expr.Types
|
||||
import Nix.Parser.Library (SourcePos(..))
|
||||
import Text.Megaparsec (unPos, mkPos)
|
||||
import Text.Megaparsec.Pos (SourcePos(..))
|
||||
import Text.Read.Deriving
|
||||
import Text.Show.Deriving
|
||||
|
||||
|
|
|
@ -1,28 +1,58 @@
|
|||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE DeriveDataTypeable #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
|
||||
{-# OPTIONS_GHC -Wno-missing-signatures #-}
|
||||
|
||||
module Nix.Parser (
|
||||
parseNixFile,
|
||||
parseNixFileLoc,
|
||||
parseNixText,
|
||||
parseNixTextLoc,
|
||||
Result(..)
|
||||
) where
|
||||
module Nix.Parser
|
||||
( parseNixFile
|
||||
, parseNixFileLoc
|
||||
, parseNixText
|
||||
, parseNixTextLoc
|
||||
, parseFromFileEx
|
||||
, parseFromText
|
||||
, Result(..)
|
||||
, reservedNames
|
||||
, OperatorInfo(..)
|
||||
, NSpecialOp(..)
|
||||
, NAssoc(..)
|
||||
, NOperatorDef
|
||||
, getUnaryOperator
|
||||
, getBinaryOperator
|
||||
, getSpecialOperator
|
||||
) where
|
||||
|
||||
import Control.Applicative hiding (many, some)
|
||||
import Control.DeepSeq
|
||||
import Control.Monad
|
||||
import Control.Monad.IO.Class
|
||||
import Data.Char (isAlpha, isDigit, isSpace)
|
||||
import Data.Data (Data(..))
|
||||
import Data.Foldable (concat)
|
||||
import Data.Functor
|
||||
import Data.Functor.Identity
|
||||
import Data.HashSet (HashSet)
|
||||
import qualified Data.HashSet as HashSet
|
||||
import Data.List.NonEmpty (NonEmpty(..))
|
||||
import qualified Data.List.NonEmpty as NE
|
||||
import Data.Text hiding (map)
|
||||
import qualified Data.Map as Map
|
||||
import Data.Text (Text)
|
||||
import Data.Text hiding (map, foldr1, concat, concatMap, zipWith)
|
||||
import qualified Data.Text.IO as T
|
||||
import Data.Typeable (Typeable)
|
||||
import Data.Void
|
||||
import GHC.Generics hiding (Prefix)
|
||||
import Nix.Expr hiding (($>))
|
||||
import Nix.Parser.Library
|
||||
import Nix.Parser.Operators
|
||||
import Nix.Strings
|
||||
import Text.Megaparsec
|
||||
import Text.Megaparsec.Char
|
||||
import qualified Text.Megaparsec.Char.Lexer as L
|
||||
import Text.Megaparsec.Expr
|
||||
import Text.PrettyPrint.ANSI.Leijen (Doc, text)
|
||||
|
||||
infixl 3 <+>
|
||||
(<+>) :: MonadPlus m => m a -> m a -> m a
|
||||
|
@ -315,3 +345,202 @@ parseNixText =
|
|||
|
||||
parseNixTextLoc :: Text -> Result NExprLoc
|
||||
parseNixTextLoc = parseFromText (whiteSpace *> nixToplevelForm <* eof)
|
||||
|
||||
{- Parser.Library -}
|
||||
|
||||
skipLineComment' :: Tokens Text -> Parser ()
|
||||
skipLineComment' prefix =
|
||||
string prefix
|
||||
*> void (takeWhileP (Just "character") (\x -> x /= '\n' && x /= '\r'))
|
||||
|
||||
whiteSpace :: Parser ()
|
||||
whiteSpace = L.space space1 lineCmnt blockCmnt
|
||||
where
|
||||
lineCmnt = skipLineComment' "#"
|
||||
blockCmnt = L.skipBlockComment "/*" "*/"
|
||||
|
||||
lexeme :: Parser a -> Parser a
|
||||
lexeme p = p <* whiteSpace
|
||||
|
||||
symbol :: Text -> Parser Text
|
||||
symbol = lexeme . string
|
||||
|
||||
reservedEnd :: Char -> Bool
|
||||
reservedEnd x = isSpace x ||
|
||||
x == '{' || x == '(' || x == '[' ||
|
||||
x == '}' || x == ')' || x == ']' ||
|
||||
x == ';' || x == ':' || x == '.' ||
|
||||
x == '"' || x == '\'' || x == ','
|
||||
|
||||
reserved :: Text -> Parser ()
|
||||
reserved n = lexeme $ try $
|
||||
string n *> lookAhead (void (satisfy reservedEnd) <|> eof)
|
||||
|
||||
identifier = lexeme $ try $ do
|
||||
ident <- cons <$> satisfy (\x -> isAlpha x || x == '_')
|
||||
<*> takeWhileP Nothing identLetter
|
||||
guard (not (ident `HashSet.member` reservedNames))
|
||||
return ident
|
||||
where
|
||||
identLetter x = isAlpha x || isDigit x || x == '_' || x == '\'' || x == '-'
|
||||
|
||||
parens = between (symbol "(") (symbol ")")
|
||||
braces = between (symbol "{") (symbol "}")
|
||||
-- angles = between (symbol "<") (symbol ">")
|
||||
brackets = between (symbol "[") (symbol "]")
|
||||
semi = symbol ";"
|
||||
comma = symbol ","
|
||||
-- colon = symbol ":"
|
||||
-- dot = symbol "."
|
||||
equals = symbol "="
|
||||
question = symbol "?"
|
||||
|
||||
integer :: Parser Integer
|
||||
integer = lexeme L.decimal
|
||||
|
||||
float :: Parser Double
|
||||
float = lexeme L.float
|
||||
|
||||
reservedNames :: HashSet Text
|
||||
reservedNames = HashSet.fromList
|
||||
[ "let", "in"
|
||||
, "if", "then", "else"
|
||||
, "assert"
|
||||
, "with"
|
||||
, "rec"
|
||||
, "inherit"
|
||||
, "true", "false" ]
|
||||
|
||||
type Parser = ParsecT Void Text Identity
|
||||
|
||||
data Result a = Success a | Failure Doc deriving Show
|
||||
|
||||
parseFromFileEx :: MonadIO m => Parser a -> FilePath -> m (Result a)
|
||||
parseFromFileEx p path = do
|
||||
txt <- liftIO (T.readFile path)
|
||||
return $ either (Failure . text . parseErrorPretty' txt) Success
|
||||
$ parse p path txt
|
||||
|
||||
parseFromText :: Parser a -> Text -> Result a
|
||||
parseFromText p txt =
|
||||
either (Failure . text . parseErrorPretty' txt) Success $
|
||||
parse p "<string>" txt
|
||||
|
||||
{- Parser.Operators -}
|
||||
|
||||
data NSpecialOp = NHasAttrOp | NSelectOp
|
||||
deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)
|
||||
|
||||
data NAssoc = NAssocNone | NAssocLeft | NAssocRight
|
||||
deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)
|
||||
|
||||
data NOperatorDef
|
||||
= NUnaryDef Text NUnaryOp
|
||||
| NBinaryDef Text NBinaryOp NAssoc
|
||||
| NSpecialDef Text NSpecialOp NAssoc
|
||||
deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)
|
||||
|
||||
annotateLocation :: Parser a -> Parser (Ann SrcSpan a)
|
||||
annotateLocation p = do
|
||||
begin <- getPosition
|
||||
res <- p
|
||||
end <- getPosition
|
||||
pure $ Ann (SrcSpan begin end) res
|
||||
|
||||
annotateLocation1 :: Parser (NExprF NExprLoc) -> Parser NExprLoc
|
||||
annotateLocation1 = fmap annToAnnF . annotateLocation
|
||||
|
||||
manyUnaryOp f = foldr1 (.) <$> some f
|
||||
|
||||
operator "-" = lexeme . try $ string "-" <* notFollowedBy (char '>')
|
||||
operator "/" = lexeme . try $ string "/" <* notFollowedBy (char '/')
|
||||
operator "<" = lexeme . try $ string "<" <* notFollowedBy (char '=')
|
||||
operator ">" = lexeme . try $ string ">" <* notFollowedBy (char '=')
|
||||
operator n = symbol n
|
||||
|
||||
opWithLoc :: Text -> o -> (Ann SrcSpan o -> a) -> Parser a
|
||||
opWithLoc name op f = do
|
||||
Ann ann _ <- annotateLocation $ {- dbg (unpack name) $ -} operator name
|
||||
return $ f (Ann ann op)
|
||||
|
||||
binaryN name op = (NBinaryDef name op NAssocNone,
|
||||
InfixN (opWithLoc name op nBinary))
|
||||
binaryL name op = (NBinaryDef name op NAssocLeft,
|
||||
InfixL (opWithLoc name op nBinary))
|
||||
binaryR name op = (NBinaryDef name op NAssocRight,
|
||||
InfixR (opWithLoc name op nBinary))
|
||||
prefix name op = (NUnaryDef name op,
|
||||
Prefix (manyUnaryOp (opWithLoc name op nUnary)))
|
||||
-- postfix name op = (NUnaryDef name op,
|
||||
-- Postfix (opWithLoc name op nUnary))
|
||||
|
||||
nixOperators
|
||||
:: Parser (Ann SrcSpan (NAttrPath NExprLoc))
|
||||
-> [[(NOperatorDef, Operator Parser NExprLoc)]]
|
||||
nixOperators selector =
|
||||
[ -- This is not parsed here, even though technically it's part of the
|
||||
-- expression table. The problem is that in some cases, such as list
|
||||
-- membership, it's also a term. And since terms are effectively the
|
||||
-- highest precedence entities parsed by the expression parser, it ends up
|
||||
-- working out that we parse them as a kind of "meta-term".
|
||||
|
||||
-- {- 1 -} [ (NSpecialDef "." NSelectOp NAssocLeft,
|
||||
-- Postfix $ do
|
||||
-- sel <- seldot *> selector
|
||||
-- mor <- optional (reserved "or" *> term)
|
||||
-- return $ \x -> nSelectLoc x sel mor) ]
|
||||
|
||||
{- 2 -} [ (NBinaryDef " " NApp NAssocLeft,
|
||||
-- Thanks to Brent Yorgey for showing me this trick!
|
||||
InfixL $ nApp <$ symbol "") ]
|
||||
, {- 3 -} [ prefix "-" NNeg ]
|
||||
, {- 4 -} [ (NSpecialDef "?" NHasAttrOp NAssocLeft,
|
||||
Postfix $ symbol "?" *> (flip nHasAttr <$> selector)) ]
|
||||
, {- 5 -} [ binaryR "++" NConcat ]
|
||||
, {- 6 -} [ binaryL "*" NMult
|
||||
, binaryL "/" NDiv ]
|
||||
, {- 7 -} [ binaryL "+" NPlus
|
||||
, binaryL "-" NMinus ]
|
||||
, {- 8 -} [ prefix "!" NNot ]
|
||||
, {- 9 -} [ binaryR "//" NUpdate ]
|
||||
, {- 10 -} [ binaryL "<" NLt
|
||||
, binaryL ">" NGt
|
||||
, binaryL "<=" NLte
|
||||
, binaryL ">=" NGte ]
|
||||
, {- 11 -} [ binaryN "==" NEq
|
||||
, binaryN "!=" NNEq ]
|
||||
, {- 12 -} [ binaryL "&&" NAnd ]
|
||||
, {- 13 -} [ binaryL "||" NOr ]
|
||||
, {- 14 -} [ binaryN "->" NImpl ]
|
||||
]
|
||||
|
||||
data OperatorInfo = OperatorInfo
|
||||
{ precedence :: Int
|
||||
, associativity :: NAssoc
|
||||
, operatorName :: Text
|
||||
} deriving (Eq, Ord, Generic, Typeable, Data, Show)
|
||||
|
||||
getUnaryOperator :: NUnaryOp -> OperatorInfo
|
||||
getUnaryOperator = (m Map.!) where
|
||||
m = Map.fromList $ concat $ zipWith buildEntry [1..]
|
||||
(nixOperators (error "unused"))
|
||||
buildEntry i = concatMap $ \case
|
||||
(NUnaryDef name op, _) -> [(op, OperatorInfo i NAssocNone name)]
|
||||
_ -> []
|
||||
|
||||
getBinaryOperator :: NBinaryOp -> OperatorInfo
|
||||
getBinaryOperator = (m Map.!) where
|
||||
m = Map.fromList $ concat $ zipWith buildEntry [1..]
|
||||
(nixOperators (error "unused"))
|
||||
buildEntry i = concatMap $ \case
|
||||
(NBinaryDef name op assoc, _) -> [(op, OperatorInfo i assoc name)]
|
||||
_ -> []
|
||||
|
||||
getSpecialOperator :: NSpecialOp -> OperatorInfo
|
||||
getSpecialOperator NSelectOp = OperatorInfo 1 NAssocLeft "."
|
||||
getSpecialOperator o = m Map.! o where
|
||||
m = Map.fromList $ concat $ zipWith buildEntry [1..]
|
||||
(nixOperators (error "unused"))
|
||||
buildEntry i = concatMap $ \case
|
||||
(NSpecialDef name op assoc, _) -> [(op, OperatorInfo i assoc name)]
|
||||
_ -> []
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
{-# OPTIONS_GHC -Wno-missing-signatures #-}
|
||||
|
||||
module Nix.Parser.Library
|
||||
( module Nix.Parser.Library
|
||||
, module X
|
||||
) where
|
||||
|
||||
import Control.Applicative hiding (many)
|
||||
import Control.Monad
|
||||
import Control.Monad.IO.Class
|
||||
import Data.Char (isAlpha, isDigit, isSpace)
|
||||
import Data.Functor.Identity
|
||||
import Data.HashSet (HashSet)
|
||||
import qualified Data.HashSet as HashSet
|
||||
import Data.Text
|
||||
import qualified Data.Text.IO as T
|
||||
import Data.Void
|
||||
import Text.Megaparsec as X
|
||||
import Text.Megaparsec.Char as X
|
||||
import qualified Text.Megaparsec.Char.Lexer as L
|
||||
import Text.PrettyPrint.ANSI.Leijen as X (Doc, text)
|
||||
|
||||
skipLineComment' :: Tokens Text -> Parser ()
|
||||
skipLineComment' prefix =
|
||||
string prefix
|
||||
*> void (takeWhileP (Just "character") (\x -> x /= '\n' && x /= '\r'))
|
||||
|
||||
whiteSpace :: Parser ()
|
||||
whiteSpace = L.space space1 lineCmnt blockCmnt
|
||||
where
|
||||
lineCmnt = skipLineComment' "#"
|
||||
blockCmnt = L.skipBlockComment "/*" "*/"
|
||||
|
||||
lexeme :: Parser a -> Parser a
|
||||
lexeme p = p <* whiteSpace
|
||||
|
||||
symbol = lexeme . string
|
||||
|
||||
reservedEnd :: Char -> Bool
|
||||
reservedEnd x = isSpace x ||
|
||||
x == '{' || x == '(' || x == '[' ||
|
||||
x == '}' || x == ')' || x == ']' ||
|
||||
x == ';' || x == ':' || x == '.' ||
|
||||
x == '"' || x == '\'' || x == ','
|
||||
|
||||
reserved :: Text -> Parser ()
|
||||
reserved n = lexeme $ try $
|
||||
string n *> lookAhead (void (satisfy reservedEnd) <|> eof)
|
||||
|
||||
identifier = lexeme $ try $ do
|
||||
ident <- cons <$> satisfy (\x -> isAlpha x || x == '_')
|
||||
<*> takeWhileP Nothing identLetter
|
||||
guard (not (ident `HashSet.member` reservedNames))
|
||||
return ident
|
||||
where
|
||||
identLetter x = isAlpha x || isDigit x || x == '_' || x == '\'' || x == '-'
|
||||
|
||||
parens = between (symbol "(") (symbol ")")
|
||||
braces = between (symbol "{") (symbol "}")
|
||||
angles = between (symbol "<") (symbol ">")
|
||||
brackets = between (symbol "[") (symbol "]")
|
||||
semi = symbol ";"
|
||||
comma = symbol ","
|
||||
colon = symbol ":"
|
||||
dot = symbol "."
|
||||
equals = symbol "="
|
||||
question = symbol "?"
|
||||
|
||||
integer :: Parser Integer
|
||||
integer = lexeme L.decimal
|
||||
|
||||
float :: Parser Double
|
||||
float = lexeme L.float
|
||||
|
||||
reservedNames :: HashSet Text
|
||||
reservedNames = HashSet.fromList
|
||||
[ "let", "in"
|
||||
, "if", "then", "else"
|
||||
, "assert"
|
||||
, "with"
|
||||
, "rec"
|
||||
, "inherit"
|
||||
, "true", "false" ]
|
||||
|
||||
type Parser = ParsecT Void Text Identity
|
||||
|
||||
data Result a = Success a | Failure Doc deriving Show
|
||||
|
||||
parseFromFileEx :: MonadIO m => Parser a -> FilePath -> m (Result a)
|
||||
parseFromFileEx p path = do
|
||||
txt <- liftIO (T.readFile path)
|
||||
return $ either (Failure . text . parseErrorPretty' txt) Success
|
||||
$ parse p path txt
|
||||
|
||||
parseFromText :: Parser a -> Text -> Result a
|
||||
parseFromText p txt =
|
||||
either (Failure . text . parseErrorPretty' txt) Success $
|
||||
parse p "<string>" txt
|
|
@ -1,137 +0,0 @@
|
|||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE DeriveDataTypeable #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
{-# OPTIONS_GHC -Wno-missing-signatures #-}
|
||||
|
||||
module Nix.Parser.Operators where
|
||||
|
||||
import Control.DeepSeq
|
||||
import Data.Data (Data(..))
|
||||
import Data.Foldable (concat)
|
||||
import qualified Data.Map as Map
|
||||
import Data.Text (Text)
|
||||
import Data.Typeable (Typeable)
|
||||
import GHC.Generics hiding (Prefix)
|
||||
import Nix.Expr
|
||||
import Nix.Parser.Library
|
||||
import Text.Megaparsec.Expr
|
||||
|
||||
data NSpecialOp = NHasAttrOp | NSelectOp
|
||||
deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)
|
||||
|
||||
data NAssoc = NAssocNone | NAssocLeft | NAssocRight
|
||||
deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)
|
||||
|
||||
data NOperatorDef
|
||||
= NUnaryDef Text NUnaryOp
|
||||
| NBinaryDef Text NBinaryOp NAssoc
|
||||
| NSpecialDef Text NSpecialOp NAssoc
|
||||
deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)
|
||||
|
||||
annotateLocation :: Parser a -> Parser (Ann SrcSpan a)
|
||||
annotateLocation p = do
|
||||
begin <- getPosition
|
||||
res <- p
|
||||
end <- getPosition
|
||||
pure $ Ann (SrcSpan begin end) res
|
||||
|
||||
annotateLocation1 :: Parser (NExprF NExprLoc) -> Parser NExprLoc
|
||||
annotateLocation1 = fmap annToAnnF . annotateLocation
|
||||
|
||||
manyUnaryOp f = foldr1 (.) <$> some f
|
||||
|
||||
operator "-" = lexeme . try $ string "-" <* notFollowedBy (char '>')
|
||||
operator "/" = lexeme . try $ string "/" <* notFollowedBy (char '/')
|
||||
operator "<" = lexeme . try $ string "<" <* notFollowedBy (char '=')
|
||||
operator ">" = lexeme . try $ string ">" <* notFollowedBy (char '=')
|
||||
operator n = symbol n
|
||||
|
||||
opWithLoc :: Text -> o -> (Ann SrcSpan o -> a) -> Parser a
|
||||
opWithLoc name op f = do
|
||||
Ann ann _ <- annotateLocation $ {- dbg (unpack name) $ -} operator name
|
||||
return $ f (Ann ann op)
|
||||
|
||||
binaryN name op = (NBinaryDef name op NAssocNone,
|
||||
InfixN (opWithLoc name op nBinary))
|
||||
binaryL name op = (NBinaryDef name op NAssocLeft,
|
||||
InfixL (opWithLoc name op nBinary))
|
||||
binaryR name op = (NBinaryDef name op NAssocRight,
|
||||
InfixR (opWithLoc name op nBinary))
|
||||
prefix name op = (NUnaryDef name op,
|
||||
Prefix (manyUnaryOp (opWithLoc name op nUnary)))
|
||||
postfix name op = (NUnaryDef name op,
|
||||
Postfix (opWithLoc name op nUnary))
|
||||
|
||||
nixOperators
|
||||
:: Parser (Ann SrcSpan (NAttrPath NExprLoc))
|
||||
-> [[(NOperatorDef, Operator Parser NExprLoc)]]
|
||||
nixOperators selector =
|
||||
[ -- This is not parsed here, even though technically it's part of the
|
||||
-- expression table. The problem is that in some cases, such as list
|
||||
-- membership, it's also a term. And since terms are effectively the
|
||||
-- highest precedence entities parsed by the expression parser, it ends up
|
||||
-- working out that we parse them as a kind of "meta-term".
|
||||
|
||||
-- {- 1 -} [ (NSpecialDef "." NSelectOp NAssocLeft,
|
||||
-- Postfix $ do
|
||||
-- sel <- seldot *> selector
|
||||
-- mor <- optional (reserved "or" *> term)
|
||||
-- return $ \x -> nSelectLoc x sel mor) ]
|
||||
|
||||
{- 2 -} [ (NBinaryDef " " NApp NAssocLeft,
|
||||
-- Thanks to Brent Yorgey for showing me this trick!
|
||||
InfixL $ nApp <$ symbol "") ]
|
||||
, {- 3 -} [ prefix "-" NNeg ]
|
||||
, {- 4 -} [ (NSpecialDef "?" NHasAttrOp NAssocLeft,
|
||||
Postfix $ symbol "?" *> (flip nHasAttr <$> selector)) ]
|
||||
, {- 5 -} [ binaryR "++" NConcat ]
|
||||
, {- 6 -} [ binaryL "*" NMult
|
||||
, binaryL "/" NDiv ]
|
||||
, {- 7 -} [ binaryL "+" NPlus
|
||||
, binaryL "-" NMinus ]
|
||||
, {- 8 -} [ prefix "!" NNot ]
|
||||
, {- 9 -} [ binaryR "//" NUpdate ]
|
||||
, {- 10 -} [ binaryL "<" NLt
|
||||
, binaryL ">" NGt
|
||||
, binaryL "<=" NLte
|
||||
, binaryL ">=" NGte ]
|
||||
, {- 11 -} [ binaryN "==" NEq
|
||||
, binaryN "!=" NNEq ]
|
||||
, {- 12 -} [ binaryL "&&" NAnd ]
|
||||
, {- 13 -} [ binaryL "||" NOr ]
|
||||
, {- 14 -} [ binaryN "->" NImpl ]
|
||||
]
|
||||
|
||||
data OperatorInfo = OperatorInfo
|
||||
{ precedence :: Int
|
||||
, associativity :: NAssoc
|
||||
, operatorName :: Text
|
||||
} deriving (Eq, Ord, Generic, Typeable, Data, Show)
|
||||
|
||||
getUnaryOperator :: NUnaryOp -> OperatorInfo
|
||||
getUnaryOperator = (m Map.!) where
|
||||
m = Map.fromList $ concat $ zipWith buildEntry [1..]
|
||||
(nixOperators (error "unused"))
|
||||
buildEntry i = concatMap $ \case
|
||||
(NUnaryDef name op, _) -> [(op, OperatorInfo i NAssocNone name)]
|
||||
_ -> []
|
||||
|
||||
getBinaryOperator :: NBinaryOp -> OperatorInfo
|
||||
getBinaryOperator = (m Map.!) where
|
||||
m = Map.fromList $ concat $ zipWith buildEntry [1..]
|
||||
(nixOperators (error "unused"))
|
||||
buildEntry i = concatMap $ \case
|
||||
(NBinaryDef name op assoc, _) -> [(op, OperatorInfo i assoc name)]
|
||||
_ -> []
|
||||
|
||||
getSpecialOperator :: NSpecialOp -> OperatorInfo
|
||||
getSpecialOperator NSelectOp = OperatorInfo 1 NAssocLeft "."
|
||||
getSpecialOperator o = m Map.! o where
|
||||
m = Map.fromList $ concat $ zipWith buildEntry [1..]
|
||||
(nixOperators (error "unused"))
|
||||
buildEntry i = concatMap $ \case
|
||||
(NSpecialDef name op assoc, _) -> [(op, OperatorInfo i assoc name)]
|
||||
_ -> []
|
|
@ -25,8 +25,7 @@ import Data.Text (pack, unpack, replace, strip)
|
|||
import qualified Data.Text as Text
|
||||
import Nix.Atoms
|
||||
import Nix.Expr
|
||||
import Nix.Parser.Library (reservedNames)
|
||||
import Nix.Parser.Operators
|
||||
import Nix.Parser
|
||||
import Nix.Strings
|
||||
import Nix.Thunk
|
||||
#if ENABLE_TRACING
|
||||
|
@ -124,7 +123,8 @@ prettyParams :: Params NixDoc -> Doc
|
|||
prettyParams (Param n) = text $ unpack n
|
||||
prettyParams (ParamSet s v mname) = prettyParamSet s v <> case mname of
|
||||
Nothing -> empty
|
||||
Just name -> text "@" <> text (unpack name)
|
||||
Just name | Text.null name -> empty
|
||||
| otherwise -> text "@" <> text (unpack name)
|
||||
|
||||
prettyParamSet :: ParamSet NixDoc -> Bool -> Doc
|
||||
prettyParamSet args var =
|
||||
|
|
|
@ -14,7 +14,9 @@ import Data.List.NonEmpty (NonEmpty((:|)))
|
|||
import qualified Data.Set as Set
|
||||
import Data.Void
|
||||
import Nix.Expr.Types.Annotated
|
||||
import Nix.Parser.Library
|
||||
import Text.Megaparsec.Error
|
||||
import Text.Megaparsec.Pos (SourcePos(..))
|
||||
import Text.PrettyPrint.ANSI.Leijen
|
||||
|
||||
class Monad m => MonadFile m where
|
||||
readFile :: FilePath -> m ByteString
|
||||
|
|
|
@ -21,12 +21,12 @@ import Nix.Expr
|
|||
import Nix.Frames
|
||||
import Nix.Normal
|
||||
import Nix.Options
|
||||
import Nix.Parser.Library hiding (colon)
|
||||
import Nix.Pretty
|
||||
import Nix.Render
|
||||
import Nix.Thunk
|
||||
import Nix.Utils
|
||||
import Nix.Value
|
||||
import Text.Megaparsec.Pos
|
||||
import qualified Text.PrettyPrint.ANSI.Leijen as P
|
||||
import Text.PrettyPrint.ANSI.Leijen hiding ((<$>))
|
||||
import qualified Text.Show.Pretty as PS
|
||||
|
|
|
@ -11,7 +11,7 @@ import Control.Monad
|
|||
import Control.Monad.IO.Class
|
||||
import Data.Fix
|
||||
import Data.List (isInfixOf)
|
||||
import Data.Maybe (isJust)
|
||||
import Data.Maybe (isJust, fromMaybe)
|
||||
import Data.String.Interpolate.IsString
|
||||
import Data.Text (unpack)
|
||||
import Data.Time
|
||||
|
@ -25,7 +25,7 @@ import Nix.Value
|
|||
import qualified NixLanguageTests
|
||||
import qualified ParserTests
|
||||
import qualified PrettyTests
|
||||
-- import qualified PrettyParseTests
|
||||
import qualified PrettyParseTests
|
||||
import System.Environment
|
||||
import System.FilePath.Glob
|
||||
import System.Posix.Files
|
||||
|
@ -83,21 +83,20 @@ main :: IO ()
|
|||
main = do
|
||||
nixLanguageTests <- NixLanguageTests.genTests
|
||||
evalComparisonTests <- EvalTests.genEvalCompareTests
|
||||
langTestsEnv <- lookupEnv "LANGUAGE_TESTS"
|
||||
nixpkgsTestsEnv <- lookupEnv "NIXPKGS_TESTS"
|
||||
let runLangTests = isJust langTestsEnv
|
||||
let runNixpkgsTests = isJust nixpkgsTestsEnv
|
||||
prettyTestsEnv <- lookupEnv "PRETTY_TESTS"
|
||||
|
||||
setEnv "NIX_REMOTE" "local?root=/tmp"
|
||||
|
||||
defaultMain $ testGroup "hnix" $
|
||||
[ testCase "hnix.cabal correctly generated" cabalCorrectlyGenerated ] ++
|
||||
[ ParserTests.tests
|
||||
, EvalTests.tests
|
||||
, PrettyTests.tests
|
||||
-- , PrettyParseTests.tests
|
||||
, evalComparisonTests ] ++
|
||||
, PrettyTests.tests ] ++
|
||||
[ PrettyParseTests.tests (read (fromMaybe "0" prettyTestsEnv)) ] ++
|
||||
[ evalComparisonTests ] ++
|
||||
[ testCase "Nix language tests present" ensureLangTestsPresent
|
||||
| runLangTests ] ++
|
||||
[ nixLanguageTests | runLangTests ] ++
|
||||
, nixLanguageTests ] ++
|
||||
[ testCase "Nixpkgs parses without errors" ensureNixpkgsCanParse
|
||||
| runNixpkgsTests ]
|
||||
| isJust nixpkgsTestsEnv ]
|
||||
|
||||
|
|
|
@ -56,7 +56,10 @@ groupBy key = Map.fromListWith (++) . map (key &&& pure)
|
|||
|
||||
genTests :: IO TestTree
|
||||
genTests = do
|
||||
testFiles <- sort . filter ((/= ".xml") . takeExtension)
|
||||
testFiles <- sort
|
||||
-- jww (2018-05-07): Temporarily disable this test until #128 is fixed.
|
||||
. filter ((/= "eval-okay-path") . takeBaseName)
|
||||
. filter ((/= ".xml") . takeExtension)
|
||||
<$> globDir1 (compile "*-*-*.*") "data/nix/tests/lang"
|
||||
let testsByName = groupBy (takeFileName . dropExtensions) testFiles
|
||||
let testsByType = groupBy testType (Map.toList testsByName)
|
||||
|
|
|
@ -1,38 +1,42 @@
|
|||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE NoMonomorphismRestriction #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE MonoLocalBinds #-}
|
||||
{-# LANGUAGE NoMonomorphismRestriction #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
|
||||
{-# OPTIONS -Wno-orphans#-}
|
||||
|
||||
module PrettyParseTests where
|
||||
|
||||
import Test.Tasty.QuickCheck hiding (Success, Failure)
|
||||
import Test.Tasty
|
||||
import Test.QuickCheck.Instances.Text ()
|
||||
import Test.QuickCheck.Instances.Semigroup ()
|
||||
import Control.Monad
|
||||
import Data.Algorithm.Diff
|
||||
import Data.Algorithm.DiffOutput
|
||||
import Data.Char
|
||||
import Data.Fix
|
||||
import qualified Data.List.NonEmpty as NE
|
||||
import Data.Text (Text, pack)
|
||||
import qualified Data.Text as Text
|
||||
import Generic.Random
|
||||
import Nix.Atoms
|
||||
import Nix.Expr
|
||||
import Nix.Parser
|
||||
import Nix.Pretty
|
||||
import Test.QuickCheck.Instances.Semigroup ()
|
||||
import Test.QuickCheck.Instances.Text ()
|
||||
import qualified Test.QuickCheck.Property as P
|
||||
import Test.Tasty
|
||||
import Test.Tasty.QuickCheck hiding (Success, Failure)
|
||||
import Text.Megaparsec (Pos, SourcePos, mkPos)
|
||||
import Text.PrettyPrint.ANSI.Leijen ((</>), text)
|
||||
import qualified Text.PrettyPrint.ANSI.Leijen as P
|
||||
import qualified Text.Show.Pretty as PS
|
||||
|
||||
import Nix.Expr (NExpr, NExprF(..), NString(..), NUnaryOp(..), NBinaryOp(..)
|
||||
, Params(..), NKeyName(..), Antiquoted(..), Binding(..))
|
||||
import Nix.Atoms
|
||||
import Nix.Pretty
|
||||
import Nix.Parser
|
||||
import Generic.Random
|
||||
import Data.Fix
|
||||
import Data.Text (Text, pack, unpack)
|
||||
import Text.Megaparsec (Pos, SourcePos, mkPos)
|
||||
import Control.Monad
|
||||
import Data.Algorithm.Diff
|
||||
import Data.Algorithm.DiffOutput
|
||||
import Data.Char
|
||||
|
||||
-- Instead of using the Generic arbitrary instance (which doesn't exist
|
||||
-- anyway for Text), we use a different generator which just prints
|
||||
-- sensible looking variable names
|
||||
-- Instead of using the Generic arbitrary instance (which doesn't exist anyway
|
||||
-- for Text), we use a different generator which just prints sensible looking
|
||||
-- variable names
|
||||
custom :: GenList '[Text]
|
||||
custom = asciiText :@ Nil
|
||||
|
||||
|
@ -45,11 +49,11 @@ asciiText :: Gen Text
|
|||
asciiText = pack <$> asciiString
|
||||
|
||||
pcustom :: GenList '[Pos]
|
||||
pcustom = (arbitrary) :@ Nil
|
||||
pcustom = arbitrary :@ Nil
|
||||
|
||||
-- | This generator generates selects one of the constructors uniformly
|
||||
-- and also decreases the size of the generator by dividing by the
|
||||
-- branching factor. This ensures sensible termination.
|
||||
-- | This generator generates selects one of the constructors uniformly and
|
||||
-- also decreases the size of the generator by dividing by the branching
|
||||
-- factor. This ensures sensible termination.
|
||||
genArb :: (GArbitrary (Options 'Sized '[Text]) a, GUniformWeight a) => Gen a
|
||||
genArb = genericArbitraryWith (setGenerators custom sizedOpts) uniform
|
||||
|
||||
|
@ -70,13 +74,23 @@ instance Arbitrary f => Arbitrary (Binding f) where
|
|||
arbitrary = genArb
|
||||
|
||||
instance Arbitrary f => Arbitrary (NKeyName f) where
|
||||
arbitrary = genArb
|
||||
arbitrary = oneof [ DynamicKey <$> arbitrary
|
||||
, StaticKey <$> asciiText <*> arbitrary ]
|
||||
|
||||
instance Arbitrary f => Arbitrary (Params f) where
|
||||
arbitrary = genArb
|
||||
arbitrary =
|
||||
oneof [ Param <$> asciiText
|
||||
, ParamSet <$> listOf ((,) <$> asciiText <*> arbitrary) <*> arbitrary
|
||||
<*> oneof [pure Nothing, Just <$> asciiText]
|
||||
]
|
||||
|
||||
instance Arbitrary NAtom where
|
||||
arbitrary = genArb
|
||||
arbitrary =
|
||||
oneof [ NInt <$> arbitrary `suchThat` (>= 0)
|
||||
, NFloat <$> arbitrary `suchThat` (>= 0)
|
||||
, NBool <$> arbitrary
|
||||
, pure NNull
|
||||
, NUri <$> asciiText `suchThat` (\x -> Text.length x > 0) ]
|
||||
|
||||
instance Arbitrary NUnaryOp where
|
||||
arbitrary = genArb
|
||||
|
@ -90,76 +104,143 @@ instance (Arbitrary f) => Arbitrary (Antiquoted Text f) where
|
|||
instance (Arbitrary f) => Arbitrary (Antiquoted (NString f) f) where
|
||||
arbitrary = genArb
|
||||
|
||||
-- This is written by hand so we can use `fairList` rather than
|
||||
-- the normal list Arbitrary instance which makes the generator
|
||||
-- terminate. The distribution is not scientifically chosen.
|
||||
-- This is written by hand so we can use `fairList` rather than the normal
|
||||
-- list Arbitrary instance which makes the generator terminate. The
|
||||
-- distribution is not scientifically chosen.
|
||||
instance Arbitrary f => Arbitrary (NExprF f) where
|
||||
arbitrary =
|
||||
sized $ \n ->
|
||||
if n < 2
|
||||
then oneof [nConstant, nStr, nSym, nLiteralPath, nEnvPath ]
|
||||
then oneof [genConstant, genStr, genSym, genLiteralPath, genEnvPath ]
|
||||
else
|
||||
frequency
|
||||
[ (1, nConstant)
|
||||
, (1, nSym)
|
||||
, (4, resize (n `div` 3) nIf)
|
||||
, (10, nRecSet )
|
||||
, (20, nSet )
|
||||
, (5, nList )
|
||||
, (2, nUnary )
|
||||
, (2, resize (n `div` 3) nBinary )
|
||||
, (3, resize (n `div` 3) nSelect )
|
||||
, (20, resize (n `div` 2) nAbs )
|
||||
, (2, resize (n `div` 2) nHasAttr )
|
||||
, (10, resize (n `div` 2) nLet )
|
||||
, (10, resize (n `div` 2) nWith )
|
||||
, (1, resize (n `div` 2) nAssert)
|
||||
[ ( 1, genConstant)
|
||||
, ( 1, genSym)
|
||||
, ( 4, resize (n `div` 3) genIf)
|
||||
, (10, genRecSet )
|
||||
, (20, genSet )
|
||||
, ( 5, genList )
|
||||
, ( 2, genUnary )
|
||||
, ( 2, resize (n `div` 3) genBinary )
|
||||
, ( 3, resize (n `div` 3) genSelect )
|
||||
, (20, resize (n `div` 2) genAbs )
|
||||
, ( 2, resize (n `div` 2) genHasAttr )
|
||||
, (10, resize (n `div` 2) genLet )
|
||||
, (10, resize (n `div` 2) genWith )
|
||||
, ( 1, resize (n `div` 2) genAssert)
|
||||
]
|
||||
where
|
||||
nConstant = NConstant <$> arbitrary
|
||||
nStr = NStr <$> arbitrary
|
||||
nSym = NSym <$> asciiText
|
||||
nList = NList <$> fairList arbitrary
|
||||
nSet = NSet <$> fairList arbitrary
|
||||
nRecSet = NRecSet <$> fairList arbitrary
|
||||
nLiteralPath = NLiteralPath <$> asciiString
|
||||
nEnvPath = NEnvPath <$> asciiString
|
||||
nUnary = NUnary <$> arbitrary <*> arbitrary
|
||||
nBinary = NBinary <$> arbitrary <*> arbitrary <*> arbitrary
|
||||
nSelect = NSelect <$> arbitrary <*> arbitrary <*> arbitrary
|
||||
nHasAttr = NHasAttr <$> arbitrary <*> arbitrary
|
||||
nAbs = NAbs <$> arbitrary <*> arbitrary
|
||||
nLet = NLet <$> arbitrary <*> arbitrary
|
||||
nIf = NIf <$> arbitrary <*> arbitrary <*> arbitrary
|
||||
nWith = NWith <$> arbitrary <*> arbitrary
|
||||
nAssert = NAssert <$> arbitrary <*> arbitrary
|
||||
genConstant = NConstant <$> arbitrary
|
||||
genStr = NStr <$> arbitrary
|
||||
genSym = NSym <$> asciiText
|
||||
genList = NList <$> fairList arbitrary
|
||||
genSet = NSet <$> fairList arbitrary
|
||||
genRecSet = NRecSet <$> fairList arbitrary
|
||||
genLiteralPath = NLiteralPath . ("./" ++) <$> asciiString
|
||||
genEnvPath = NEnvPath <$> asciiString
|
||||
genUnary = NUnary <$> arbitrary <*> arbitrary
|
||||
genBinary = NBinary <$> arbitrary <*> arbitrary <*> arbitrary
|
||||
genSelect = NSelect <$> arbitrary <*> arbitrary <*> arbitrary
|
||||
genHasAttr = NHasAttr <$> arbitrary <*> arbitrary
|
||||
genAbs = NAbs <$> arbitrary <*> arbitrary
|
||||
genLet = NLet <$> fairList arbitrary <*> arbitrary
|
||||
genIf = NIf <$> arbitrary <*> arbitrary <*> arbitrary
|
||||
genWith = NWith <$> arbitrary <*> arbitrary
|
||||
genAssert = NAssert <$> arbitrary <*> arbitrary
|
||||
|
||||
-- | Useful when there are recursive positions at each element of the list
|
||||
-- as it divides the size by the length of the generated list.
|
||||
-- | Useful when there are recursive positions at each element of the list as
|
||||
-- it divides the size by the length of the generated list.
|
||||
fairList :: Gen a -> Gen [a]
|
||||
fairList g = do
|
||||
s <- getSize
|
||||
k <- choose (0, s)
|
||||
-- Use max here to avoid dividing by zero when there is the empty list
|
||||
resize (s `div` (max 1 k)) $ vectorOf k g
|
||||
resize (s `div` max 1 k) $ vectorOf k g
|
||||
|
||||
-- | Test that pretty . parse . pretty == pretty
|
||||
equivUpToNormalization :: NExpr -> NExpr -> Bool
|
||||
equivUpToNormalization x y = normalize x == normalize y
|
||||
|
||||
normalize :: NExpr -> NExpr
|
||||
normalize = cata $ \case
|
||||
NConstant (NInt n) | n < 0 -> Fix (NUnary NNeg (Fix (NConstant (NInt (negate n)))))
|
||||
NConstant (NFloat n) | n < 0 -> Fix (NUnary NNeg (Fix (NConstant (NFloat (negate n)))))
|
||||
|
||||
NSet binds -> Fix (NSet (map normBinding binds))
|
||||
NRecSet binds -> Fix (NRecSet (map normBinding binds))
|
||||
NLet binds r -> Fix (NLet (map normBinding binds) r)
|
||||
|
||||
NAbs params r -> Fix (NAbs (normParams params) r)
|
||||
|
||||
r -> Fix r
|
||||
|
||||
where
|
||||
normBinding (NamedVar path r) = NamedVar (NE.map normKey path) r
|
||||
normBinding (Inherit mr names) = Inherit mr (map normKey names)
|
||||
|
||||
normKey (DynamicKey quoted) = DynamicKey (normAntiquotedString quoted)
|
||||
normKey (StaticKey name _) = StaticKey name Nothing
|
||||
|
||||
normAntiquotedString :: Antiquoted (NString NExpr) NExpr
|
||||
-> Antiquoted (NString NExpr) NExpr
|
||||
normAntiquotedString (Plain (DoubleQuoted [EscapedNewline])) =
|
||||
EscapedNewline
|
||||
normAntiquotedString (Plain (DoubleQuoted strs)) =
|
||||
let strs' = map normAntiquotedText strs
|
||||
in if strs == strs'
|
||||
then Plain (DoubleQuoted strs)
|
||||
else normAntiquotedString (Plain (DoubleQuoted strs'))
|
||||
normAntiquotedString r = r
|
||||
|
||||
normAntiquotedText :: Antiquoted Text NExpr -> Antiquoted Text NExpr
|
||||
normAntiquotedText (Plain "\n") = EscapedNewline
|
||||
normAntiquotedText (Plain "''\n") = EscapedNewline
|
||||
normAntiquotedText r = r
|
||||
|
||||
normParams (ParamSet binds var (Just "")) = ParamSet binds var Nothing
|
||||
normParams r = r
|
||||
|
||||
-- | Test that parse . pretty == id up to attribute position information.
|
||||
prop_prettyparse :: NExpr -> P.Result
|
||||
prop_prettyparse p =
|
||||
case parse (pretty p) of
|
||||
Failure s -> P.rejected { P.reason = show s ++ show (pretty p) }
|
||||
Success v ->
|
||||
let pp = normalise (unpack (pretty p))
|
||||
pv = normalise (unpack (pretty v))
|
||||
in (P.liftBool (pp == pv)) { P.reason = "Bad parse:" ++ pp ++ pv ++ ppDiff (diff pp pv) ++ show p ++ show v}
|
||||
let prog = show (pretty p)
|
||||
in case parse (pack prog) of
|
||||
Failure s -> P.rejected
|
||||
{ P.reason = show $
|
||||
text "Parse failed:" </> text (show s)
|
||||
P.<$> P.indent 2 (pretty p) }
|
||||
Success v
|
||||
| equivUpToNormalization p v -> P.succeeded
|
||||
| otherwise ->
|
||||
let pp = normalise prog
|
||||
pv = normalise (show (pretty v))
|
||||
in (P.liftBool (pp == pv))
|
||||
{ P.reason = show $
|
||||
text "----------------------------------------"
|
||||
P.<$> text "Expr before:" P.<$> P.indent 2 (text (PS.ppShow p))
|
||||
P.<$> text "----------------------------------------"
|
||||
P.<$> text "Expr after:" P.<$> P.indent 2 (text (PS.ppShow v))
|
||||
P.<$> text "----------------------------------------"
|
||||
P.<$> text "Pretty before:" P.<$> P.indent 2 (text prog)
|
||||
P.<$> text "----------------------------------------"
|
||||
P.<$> text "Pretty after:" P.<$> P.indent 2 (pretty v)
|
||||
P.<$> text "----------------------------------------"
|
||||
P.<$> text "Normalised before:" P.<$> P.indent 2 (text pp)
|
||||
P.<$> text "----------------------------------------"
|
||||
P.<$> text "Normalised after:" P.<$> P.indent 2 (text pv)
|
||||
P.<$> text "========================================"
|
||||
P.<$> text "Normalised diff:"
|
||||
P.<$> text (ppDiff (diff pp pv))
|
||||
P.<$> text "========================================"
|
||||
}
|
||||
where
|
||||
pretty = pack . show . prettyNix
|
||||
parse = parseNixText
|
||||
pretty = prettyNix
|
||||
parse = parseNixText
|
||||
|
||||
normalise = unlines . map (reverse . dropWhile isSpace . reverse) . lines
|
||||
|
||||
diff :: String -> String -> [Diff [String]]
|
||||
diff s1 s2 = getDiff (map (:[]) (lines s1)) (map (:[]) (lines s2))
|
||||
diff :: String -> String -> [Diff [String]]
|
||||
diff s1 s2 = getDiff (map (:[]) (lines s1)) (map (:[]) (lines s2))
|
||||
|
||||
tests :: TestTree
|
||||
tests = testProperty "Pretty Parse Property" prop_prettyparse
|
||||
tests :: Int -> TestTree
|
||||
tests n = testProperty "Pretty/Parse Property" $
|
||||
withMaxSuccess n prop_prettyparse
|
||||
|
|
|
@ -48,7 +48,8 @@ nixEvalString expr = do
|
|||
return res
|
||||
|
||||
nixEvalFile :: FilePath -> IO String
|
||||
nixEvalFile fp = readProcess "nix-instantiate" ["--eval", fp] ""
|
||||
nixEvalFile fp = readProcess "nix-instantiate"
|
||||
["--store", "local?root=/tmp", "--eval", fp] ""
|
||||
|
||||
assertEvalFileMatchesNix :: FilePath -> Assertion
|
||||
assertEvalFileMatchesNix fp = do
|
||||
|
|
12
tests/files/attrs.nix
Normal file
12
tests/files/attrs.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
rec {
|
||||
|
||||
y = 2;
|
||||
z = { w = 4; };
|
||||
v = rec {
|
||||
u = 6;
|
||||
t = [ u z.w s.q ];
|
||||
};
|
||||
s = { r = import ./goodbye.nix; q = 10; };
|
||||
p = import ./hello.nix;
|
||||
|
||||
}
|
6
tests/files/if-then.nix
Normal file
6
tests/files/if-then.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
# [ ({ a = 1; b = 2; } // { c = 1; d = 2; })
|
||||
# ([1 2 3] ++ [4.0 5.0 6.0])
|
||||
# (x: y: x + y)
|
||||
# ]
|
||||
|
||||
({ x, y ? x + 1 }: x + x)
|
Loading…
Reference in a new issue