git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge remote-tracking branch 'refs/remotes/upstream/master' into psci-node-flags
f0d351fMichael Xavier
LICENSE+35−35
@@ -41,43 +41,43 @@ PureScript uses the following Haskell library packages. Their license files foll
41base LICENSE file:
41base LICENSE file:
42
42
43 This library (libraries/base) is derived from code from several
43 This library (libraries/base) is derived from code from several
44− sources:
44+ sources:
45−
45+
46 * Code from the GHC project which is largely (c) The University of
46 * Code from the GHC project which is largely (c) The University of
47 Glasgow, and distributable under a BSD-style license (see below),
47 Glasgow, and distributable under a BSD-style license (see below),
48−
48+
49 * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
49 * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
50 and freely redistributable (but see the full license for
50 and freely redistributable (but see the full license for
51 restrictions).
51 restrictions).
52−
52+
53 * Code from the Haskell Foreign Function Interface specification,
53 * Code from the Haskell Foreign Function Interface specification,
54 which is (c) Manuel M. T. Chakravarty and freely redistributable
54 which is (c) Manuel M. T. Chakravarty and freely redistributable
55 (but see the full license for restrictions).
55 (but see the full license for restrictions).
56−
56+
57 The full text of these licenses is reproduced below. All of the
57 The full text of these licenses is reproduced below. All of the
58 licenses are BSD-style or compatible.
58 licenses are BSD-style or compatible.
59−
59+
60 -----------------------------------------------------------------------------
60 -----------------------------------------------------------------------------
61−
61+
62 The Glasgow Haskell Compiler License
62 The Glasgow Haskell Compiler License
63−
63+
64− Copyright 2004, The University Court of the University of Glasgow.
64+ Copyright 2004, The University Court of the University of Glasgow.
65 All rights reserved.
65 All rights reserved.
66−
66+
67 Redistribution and use in source and binary forms, with or without
67 Redistribution and use in source and binary forms, with or without
68 modification, are permitted provided that the following conditions are met:
68 modification, are permitted provided that the following conditions are met:
69−
69+
70 - Redistributions of source code must retain the above copyright notice,
70 - Redistributions of source code must retain the above copyright notice,
71 this list of conditions and the following disclaimer.
71 this list of conditions and the following disclaimer.
72−
72+
73 - Redistributions in binary form must reproduce the above copyright notice,
73 - Redistributions in binary form must reproduce the above copyright notice,
74 this list of conditions and the following disclaimer in the documentation
74 this list of conditions and the following disclaimer in the documentation
75 and/or other materials provided with the distribution.
75 and/or other materials provided with the distribution.
76−
76+
77 - Neither name of the University nor the names of its contributors may be
77 - Neither name of the University nor the names of its contributors may be
78 used to endorse or promote products derived from this software without
78 used to endorse or promote products derived from this software without
79− specific prior written permission.
79+ specific prior written permission.
80−
80+
81 THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
81 THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
82 GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
82 GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
83 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
83 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
@@ -90,14 +90,14 @@ base LICENSE file:
90 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
90 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
91 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
91 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
92 DAMAGE.
92 DAMAGE.
93−
93+
94 -----------------------------------------------------------------------------
94 -----------------------------------------------------------------------------
95−
95+
96 Code derived from the document "Report on the Programming Language
96 Code derived from the document "Report on the Programming Language
97 Haskell 98", is distributed under the following license:
97 Haskell 98", is distributed under the following license:
98−
98+
99 Copyright (c) 2002 Simon Peyton Jones
99 Copyright (c) 2002 Simon Peyton Jones
100−
100+
101 The authors intend this Report to belong to the entire Haskell
101 The authors intend this Report to belong to the entire Haskell
102 community, and so we grant permission to copy and distribute it for
102 community, and so we grant permission to copy and distribute it for
103 any purpose, provided that it is reproduced in its entirety,
103 any purpose, provided that it is reproduced in its entirety,
@@ -105,15 +105,15 @@ base LICENSE file:
105 copied and distributed for any purpose, provided that the modified
105 copied and distributed for any purpose, provided that the modified
106 version is clearly presented as such, and that it does not claim to
106 version is clearly presented as such, and that it does not claim to
107 be a definition of the Haskell 98 Language.
107 be a definition of the Haskell 98 Language.
108−
108+
109 -----------------------------------------------------------------------------
109 -----------------------------------------------------------------------------
110−
110+
111 Code derived from the document "The Haskell 98 Foreign Function
111 Code derived from the document "The Haskell 98 Foreign Function
112 Interface, An Addendum to the Haskell 98 Report" is distributed under
112 Interface, An Addendum to the Haskell 98 Report" is distributed under
113 the following license:
113 the following license:
114−
114+
115 Copyright (c) 2002 Manuel M. T. Chakravarty
115 Copyright (c) 2002 Manuel M. T. Chakravarty
116−
116+
117 The authors intend this Report to belong to the entire Haskell
117 The authors intend this Report to belong to the entire Haskell
118 community, and so we grant permission to copy and distribute it for
118 community, and so we grant permission to copy and distribute it for
119 any purpose, provided that it is reproduced in its entirety,
119 any purpose, provided that it is reproduced in its entirety,
@@ -121,9 +121,9 @@ base LICENSE file:
121 copied and distributed for any purpose, provided that the modified
121 copied and distributed for any purpose, provided that the modified
122 version is clearly presented as such, and that it does not claim to
122 version is clearly presented as such, and that it does not claim to
123 be a definition of the Haskell 98 Foreign Function Interface.
123 be a definition of the Haskell 98 Foreign Function Interface.
124−
124+
125 -----------------------------------------------------------------------------
125 -----------------------------------------------------------------------------
126−
126+
127containers LICENSE file:
127containers LICENSE file:
128
128
129 The Glasgow Haskell Compiler License
129 The Glasgow Haskell Compiler License
@@ -161,7 +161,7 @@ containers LICENSE file:
161directory LICENSE file:
161directory LICENSE file:
162
162
163 This library (libraries/base) is derived from code from two
163 This library (libraries/base) is derived from code from two
164− sources:
164+ sources:
165
165
166 * Code from the GHC project which is largely (c) The University of
166 * Code from the GHC project which is largely (c) The University of
167 Glasgow, and distributable under a BSD-style license (see below),
167 Glasgow, and distributable under a BSD-style license (see below),
@@ -177,7 +177,7 @@ directory LICENSE file:
177
177
178 The Glasgow Haskell Compiler License
178 The Glasgow Haskell Compiler License
179
179
180− Copyright 2004, The University Court of the University of Glasgow.
180+ Copyright 2004, The University Court of the University of Glasgow.
181 All rights reserved.
181 All rights reserved.
182
182
183 Redistribution and use in source and binary forms, with or without
183 Redistribution and use in source and binary forms, with or without
@@ -185,14 +185,14 @@ directory LICENSE file:
185
185
186 - Redistributions of source code must retain the above copyright notice,
186 - Redistributions of source code must retain the above copyright notice,
187 this list of conditions and the following disclaimer.
187 this list of conditions and the following disclaimer.
188−
188+
189 - Redistributions in binary form must reproduce the above copyright notice,
189 - Redistributions in binary form must reproduce the above copyright notice,
190 this list of conditions and the following disclaimer in the documentation
190 this list of conditions and the following disclaimer in the documentation
191 and/or other materials provided with the distribution.
191 and/or other materials provided with the distribution.
192−
192+
193 - Neither name of the University nor the names of its contributors may be
193 - Neither name of the University nor the names of its contributors may be
194 used to endorse or promote products derived from this software without
194 used to endorse or promote products derived from this software without
195− specific prior written permission.
195+ specific prior written permission.
196
196
197 THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
197 THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
198 GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
198 GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
@@ -451,7 +451,7 @@ pattern-arrows LICENSE file:
451process LICENSE file:
451process LICENSE file:
452
452
453 This library (libraries/process) is derived from code from two
453 This library (libraries/process) is derived from code from two
454− sources:
454+ sources:
455
455
456 * Code from the GHC project which is largely (c) The University of
456 * Code from the GHC project which is largely (c) The University of
457 Glasgow, and distributable under a BSD-style license (see below),
457 Glasgow, and distributable under a BSD-style license (see below),
@@ -467,7 +467,7 @@ process LICENSE file:
467
467
468 The Glasgow Haskell Compiler License
468 The Glasgow Haskell Compiler License
469
469
470− Copyright 2004, The University Court of the University of Glasgow.
470+ Copyright 2004, The University Court of the University of Glasgow.
471 All rights reserved.
471 All rights reserved.
472
472
473 Redistribution and use in source and binary forms, with or without
473 Redistribution and use in source and binary forms, with or without
@@ -475,14 +475,14 @@ process LICENSE file:
475
475
476 - Redistributions of source code must retain the above copyright notice,
476 - Redistributions of source code must retain the above copyright notice,
477 this list of conditions and the following disclaimer.
477 this list of conditions and the following disclaimer.
478−
478+
479 - Redistributions in binary form must reproduce the above copyright notice,
479 - Redistributions in binary form must reproduce the above copyright notice,
480 this list of conditions and the following disclaimer in the documentation
480 this list of conditions and the following disclaimer in the documentation
481 and/or other materials provided with the distribution.
481 and/or other materials provided with the distribution.
482−
482+
483 - Neither name of the University nor the names of its contributors may be
483 - Neither name of the University nor the names of its contributors may be
484 used to endorse or promote products derived from this software without
484 used to endorse or promote products derived from this software without
485− specific prior written permission.
485+ specific prior written permission.
486
486
487 THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
487 THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
488 GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
488 GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
README.md+2
@@ -9,6 +9,8 @@ PureScript is a small strongly, statically typed programming language with expre
9- [Wiki](http://wiki.purescript.org)
9- [Wiki](http://wiki.purescript.org)
10- [#purescript IRC @ FreeNode](http://webchat.freenode.net/?channels=purescript)
10- [#purescript IRC @ FreeNode](http://webchat.freenode.net/?channels=purescript)
11- [Twitter](http://twitter.com/purescript)
11- [Twitter](http://twitter.com/purescript)
12+- [Google Group](https://groups.google.com/forum/#!forum/purescript)
12- [Try PureScript!](http://try.purescript.org/)
13- [Try PureScript!](http://try.purescript.org/)
14+- [Pursuit Search Engine](http://pursuit.purescript.org/)
13- [Release Notes](https://github.com/purescript/purescript/blob/master/RELEASE-0.6.md)
15- [Release Notes](https://github.com/purescript/purescript/blob/master/RELEASE-0.6.md)
14- [Contributing to PureScript](https://github.com/purescript/purescript/blob/master/CONTRIBUTING.md)
16- [Contributing to PureScript](https://github.com/purescript/purescript/blob/master/CONTRIBUTING.md)
RELEASE-0.2.md+13−13
@@ -10,31 +10,31 @@ Many thanks to the [contributors](https://github.com/purescript/purescript/graph
10- RankNTypes
10- RankNTypes
11
11
12 This experimental feature allows polymorphic types (introduced with `forall`) to appear on the left of a function arrow, or as the type of a record field, etc. For example:
12 This experimental feature allows polymorphic types (introduced with `forall`) to appear on the left of a function arrow, or as the type of a record field, etc. For example:
13−
13+
14 rank2 :: (forall a. a -> a) -> Number
14 rank2 :: (forall a. a -> a) -> Number
15 rank2 = \f -> if f true then f 1 else f 2
15 rank2 = \f -> if f true then f 1 else f 2
16−
16+
17- Modules
17- Modules
18- Polymorphic Object Update
18- Polymorphic Object Update
19
19
20 Records now support member update in which the type of the field changes during the update. For example:
20 Records now support member update in which the type of the field changes during the update. For example:
21
21
22 data Wrap a = Wrap a
22 data Wrap a = Wrap a
23−
23+
24 update = \o -> o { prop = Wrap o.prop }
24 update = \o -> o { prop = Wrap o.prop }
25
25
26### Enhancements
26### Enhancements
27
27
28- Naked expressions as statements
28- Naked expressions as statements
29−
29+
30 Naked expressions of type `{}` can now be used as statements.
30 Naked expressions of type `{}` can now be used as statements.
31
31
32- Split code generation into `AST -> JS` and `JS -> String`
32- Split code generation into `AST -> JS` and `JS -> String`
33−
33+
34 JavaScript generation is now split into the generation of a JavaScript AST, and the pretty-printing of that AST. This enables some optimizations, and a better JavaScript pretty-printer.
34 JavaScript generation is now split into the generation of a JavaScript AST, and the pretty-printing of that AST. This enables some optimizations, and a better JavaScript pretty-printer.
35−
35+
36- Syntactic sugar for introducing curried functions
36- Syntactic sugar for introducing curried functions
37−
37+
38 Single-argument functions and multiple-argument functions can now be introduced in the same way:
38 Single-argument functions and multiple-argument functions can now be introduced in the same way:
39
39
40 test = \a (b, c) d -> a + b + c + d
40 test = \a (b, c) d -> a + b + c + d
@@ -42,32 +42,32 @@ Many thanks to the [contributors](https://github.com/purescript/purescript/graph
42- JavaScript optimizations
42- JavaScript optimizations
43
43
44 Some basic dead-variable elimination, inlining and eta-conversion are now performed on the generated JavaScript.
44 Some basic dead-variable elimination, inlining and eta-conversion are now performed on the generated JavaScript.
45−
45+
46- Generate formatted Javascript
46- Generate formatted Javascript
47
47
48 The generated JavaScript is now formatted to be more readable. In particular, newlines get generated, and the correct indentation is used.
48 The generated JavaScript is now formatted to be more readable. In particular, newlines get generated, and the correct indentation is used.
49
49
50- More valid infix operators
50- More valid infix operators
51−
51+
52 The colon and period characters are now valid in infix operator names.
52 The colon and period characters are now valid in infix operator names.
53
53
54### Syntax Changes
54### Syntax Changes
55
55
56- Avoid 'do' keyword for blocks
56- Avoid 'do' keyword for blocks
57−
57+
58 `do` will be used later for Haskell-like monad comprehensions, so its previous use in introducing blocks of statements is now invalid. The `do` keyword is still reserved.
58 `do` will be used later for Haskell-like monad comprehensions, so its previous use in introducing blocks of statements is now invalid. The `do` keyword is still reserved.
59
59
60- Member foreign import syntax
60- Member foreign import syntax
61
61
62− A small syntactic addition to the FFI, to support a common use case.
62+ A small syntactic addition to the FFI, to support a common use case.
63
63
64- Make FFI syntax match Haskell
64- Make FFI syntax match Haskell
65−
65+
66 Use `foreign import` instead of `extern`.
66 Use `foreign import` instead of `extern`.
67
67
68- Make record declaration syntax match Haskell
68- Make record declaration syntax match Haskell
69- Simplify array binders
69- Simplify array binders
70−
70+
71 There are now two types of array binders: cons binders `x : xs -> ...` and array binders `[x, y, z] -> ...` instead of the previously confusing `[x:xs]`.
71 There are now two types of array binders: cons binders `x : xs -> ...` and array binders `[x, y, z] -> ...` instead of the previously confusing `[x:xs]`.
72
72
73- Array indexing syntax is ambiguous
73- Array indexing syntax is ambiguous
RELEASE-0.3.md+8−8
@@ -14,40 +14,40 @@ Many thanks to the [contributors](https://github.com/purescript/purescript/graph
14 sum (x:xs) = x + sum xs
14 sum (x:xs) = x + sum xs
15
15
16- Basic support for type classes has been added. Polymorphic types of the form `forall a. (C a) => ...` will not be inferred but can be checked. Type inference still works if all type class instances can be determined. There is not yet support for functionality like GHC's `FlexibleInstances`, `FlexibleContexts` or `MultiParamTypesClasses`. For example:
16- Basic support for type classes has been added. Polymorphic types of the form `forall a. (C a) => ...` will not be inferred but can be checked. Type inference still works if all type class instances can be determined. There is not yet support for functionality like GHC's `FlexibleInstances`, `FlexibleContexts` or `MultiParamTypesClasses`. For example:
17−
17+
18 class Truthy a where
18 class Truthy a where
19 isTrue :: a -> Boolean
19 isTrue :: a -> Boolean
20−
20+
21 instance Truthy Boolean where
21 instance Truthy Boolean where
22 isTrue b = b
22 isTrue b = b
23−
23+
24 instance Truthy String where
24 instance Truthy String where
25 isTrue "" = false
25 isTrue "" = false
26 isTrue _ = true
26 isTrue _ = true
27−
27+
28 ifThenElse :: forall a b. (Truthy a) => a -> b -> b -> b
28 ifThenElse :: forall a b. (Truthy a) => a -> b -> b -> b
29 ifThenElse a tr fa = if isTrue a then tr else fa
29 ifThenElse a tr fa = if isTrue a then tr else fa
30
30
31- There is now support for `do` notation, using the `Monad` type class from the `Prelude` module. For example:
31- There is now support for `do` notation, using the `Monad` type class from the `Prelude` module. For example:
32
32
33 data Maybe = Nothing | Just a
33 data Maybe = Nothing | Just a
34−
34+
35 instance Prelude.Monad Maybe where
35 instance Prelude.Monad Maybe where
36 ret = Just
36 ret = Just
37 (>>=) Nothing _ = Nothing
37 (>>=) Nothing _ = Nothing
38 (>>=) (Just a) f = f a
38 (>>=) (Just a) f = f a
39−
39+
40 test = do
40 test = do
41 x <- Just 1
41 x <- Just 1
42 y <- Just 2
42 y <- Just 2
43 ret $ x + y
43 ret $ x + y
44−
44+
45- There is now a better story for side-effects. The `Eff` module in the `Prelude` defines a monad `Eff e` where e is a row of effect types. The kind system now defines a new kind `!` of effects. Row polymorphism allows different native effects to be interleaved. For example:
45- There is now a better story for side-effects. The `Eff` module in the `Prelude` defines a monad `Eff e` where e is a row of effect types. The kind system now defines a new kind `!` of effects. Row polymorphism allows different native effects to be interleaved. For example:
46
46
47 test = do
47 test = do
48 trace "Testing"
48 trace "Testing"
49 throwError "Error!"
49 throwError "Error!"
50−
50+
51 has inferred type `forall eff. Eff (trace :: Trace | error :: Error String | eff)`.
51 has inferred type `forall eff. Eff (trace :: Trace | error :: Error String | eff)`.
52 See the `/examples/passing/Eff.purs` file for a more in-depth set of examples.
52 See the `/examples/passing/Eff.purs` file for a more in-depth set of examples.
53 Supported native effects currently include `ST`, `Trace`, `Error` and `DOM` (via the `libraries/jquery` module).
53 Supported native effects currently include `ST`, `Trace`, `Error` and `DOM` (via the `libraries/jquery` module).
RELEASE-0.4.md+8−8
@@ -8,17 +8,17 @@ This release saw major contributions from [a number of new contributors](https:/
8- Try out the latest features [here](http://tryps.functorial.com).
8- Try out the latest features [here](http://tryps.functorial.com).
9
9
10## Breaking Changes
10## Breaking Changes
11−
11+
12- Multiple argument functions are no longer available.
12- Multiple argument functions are no longer available.
13- When used in the browser, PureScript modules are now accessed through `window.PS.<ModuleName>`. The `PS` object name can be changed via the `--browser-namespace` compiler argument.
13- When used in the browser, PureScript modules are now accessed through `window.PS.<ModuleName>`. The `PS` object name can be changed via the `--browser-namespace` compiler argument.
14- The `--run-main` argument has been replaced with `--main` which can now accept a module name in which to find the `main` function.
14- The `--run-main` argument has been replaced with `--main` which can now accept a module name in which to find the `main` function.
15−
15+
16### New Features
16### New Features
17−
17+
18- Dead code elimination. The new compiler argument `--module=` can be used to specify one or more modules that should be kept in the generated code along with their dependencies. If no modules are specified, all code is exported.
18- Dead code elimination. The new compiler argument `--module=` can be used to specify one or more modules that should be kept in the generated code along with their dependencies. If no modules are specified, all code is exported.
19−
19+
20### Enhancements
20### Enhancements
21−
21+
22- The `->` and `[]` types are now usable in type class instances.
22- The `->` and `[]` types are now usable in type class instances.
23- The file path is included in syntax error messages.
23- The file path is included in syntax error messages.
24- Most reserved Javascript names (`return`, `const`, etc) are now usable.
24- Most reserved Javascript names (`return`, `const`, etc) are now usable.
@@ -28,9 +28,9 @@ This release saw major contributions from [a number of new contributors](https:/
28- It is no longer necessary to sort modules in order of dependencies manually.
28- It is no longer necessary to sort modules in order of dependencies manually.
29- Case statements matching data constructors no longer generate unnecessary constructor checks at runtime if there is only a single data constructor.
29- Case statements matching data constructors no longer generate unnecessary constructor checks at runtime if there is only a single data constructor.
30- New optimizer rules were added to inline JavaScript's built-in operators.
30- New optimizer rules were added to inline JavaScript's built-in operators.
31−
31+
32### Bug Fixes
32### Bug Fixes
33−
33+
34- Floats parse correctly.
34- Floats parse correctly.
35- Using data constructors in pattern matches now works properly across modules.
35- Using data constructors in pattern matches now works properly across modules.
36- PureScript modules no longer overwrite global objects with the same name.
36- PureScript modules no longer overwrite global objects with the same name.
@@ -43,7 +43,7 @@ This release saw major contributions from [a number of new contributors](https:/
43- A bug which allowed skolem variables to escape their scope was add (thanks to Brian McKenna).
43- A bug which allowed skolem variables to escape their scope was add (thanks to Brian McKenna).
44- Modules containing mutually recursive type synonyms and data declarations now compile correctly.
44- Modules containing mutually recursive type synonyms and data declarations now compile correctly.
45- A number of bugs in the optimizer were addressed.
45- A number of bugs in the optimizer were addressed.
46−
46+
47### Libraries
47### Libraries
48
48
49- The `Prelude` has been greatly expanded. Definitions for built-in JavaScript operators have been moved into the Prelude.
49- The `Prelude` has been greatly expanded. Definitions for built-in JavaScript operators have been moved into the Prelude.
RELEASE-0.5.md+3−3
@@ -54,7 +54,7 @@
54- The escape check was removed, since it was too restrictive (paf31)
54- The escape check was removed, since it was too restrictive (paf31)
55- The binary operator reordering step was greatly simplified (paf31)
55- The binary operator reordering step was greatly simplified (paf31)
56- The Object type constructor can now be referenced explicitly as `Prim.Object` (with kind `# * -> *`) (paf31)
56- The Object type constructor can now be referenced explicitly as `Prim.Object` (with kind `# * -> *`) (paf31)
57−- Optimizations are now enabled by default and can be disabled with the `--no-tco` and `--no-magic-do` flags (garyb)
57+- Optimizations are now enabled by default and can be disabled with the `--no-tco` and `--no-magic-do` flags (garyb)
58- Unary minus and signed numeric literals are now supported again (paf31, garyb)
58- Unary minus and signed numeric literals are now supported again (paf31, garyb)
59- Type errors have been simplified, the full trace can be enabled with `--verbose-errors` or `-v` (paf31)
59- Type errors have been simplified, the full trace can be enabled with `--verbose-errors` or `-v` (paf31)
60- Error messages now display source positions (paf31, garyb)
60- Error messages now display source positions (paf31, garyb)
@@ -63,7 +63,7 @@
63- `(++)` is now an alias for the Semigroup operator `(<>)` (paf31)
63- `(++)` is now an alias for the Semigroup operator `(<>)` (paf31)
64- Error messages for classes with undefined or missing members have been improved (garyb)
64- Error messages for classes with undefined or missing members have been improved (garyb)
65- The SYB dependency was removed, and traversals rewritten by hand, for a large performance increase (paf31)
65- The SYB dependency was removed, and traversals rewritten by hand, for a large performance increase (paf31)
66−
66+
67### Bug Fixes
67### Bug Fixes
68
68
69- The subsumes relation has been fixed for object types (paf31)
69- The subsumes relation has been fixed for object types (paf31)
@@ -94,6 +94,6 @@
94- The `grunt-purescript` plugin has been updated to provide support for new command line options.
94- The `grunt-purescript` plugin has been updated to provide support for new command line options.
95- There is a new `gulp-purescript` plugin available for compiling with Gulp.
95- There is a new `gulp-purescript` plugin available for compiling with Gulp.
96
96
97−### Documentation
97+### Documentation
98
98
99- There is a new `hierarchy` executable which will generate `.dot` diagrams based on the type class hierarchy of a module. The Prelude docs have been updated to include such a type class diagram. (joneshf)
99- There is a new `hierarchy` executable which will generate `.dot` diagrams based on the type class hierarchy of a module. The Prelude docs have been updated to include such a type class diagram. (joneshf)
RELEASE-0.7.md+6−6
@@ -12,7 +12,7 @@ positive _ = false
12but this is not:
12but this is not:
13
13
14```haskell
14```haskell
15−positive n | n > 0
15+positive n | n > 0
16 = true
16 = true
17positive _ = false
17positive _ = false
18```
18```
@@ -32,20 +32,20 @@ positive _ = false
32
32
33### Breaking Changes
33### Breaking Changes
34
34
35−-
35+-
36
36
37### New Features
37### New Features
38
38
39−-
39+-
40
40
41### Enhancements
41### Enhancements
42
42
43−-
43+-
44
44
45### Libraries
45### Libraries
46
46
47−-
47+-
48
48
49### Documentation
49### Documentation
50
50
51−-
51+-
bundle/README+4−4
@@ -1,9 +1,9 @@
1− ____ ____ _ _
1+ ____ ____ _ _
2−| _ \ _ _ _ __ ___/ ___| ___ _ __(_)_ __ | |_
2+| _ \ _ _ _ __ ___/ ___| ___ _ __(_)_ __ | |_
3| |_) | | | | '__/ _ \___ \ / __| '__| | '_ \| __|
3| |_) | | | | '__/ _ \___ \ / __| '__| | '_ \| __|
4−| __/| |_| | | | __/___) | (__| | | | |_) | |_
4+| __/| |_| | | | __/___) | (__| | | | |_) | |_
5|_| \__,_|_| \___|____/ \___|_| |_| .__/ \__|
5|_| \__,_|_| \___|____/ \___|_| |_| .__/ \__|
6− |_|
6+ |_|
7
7
8Installation Instructions
8Installation Instructions
9-------------------------
9-------------------------
bundle/build.sh+1−1
@@ -4,7 +4,7 @@ SCRIPTPATH=$( cd "$(dirname "$0")" ; pwd -P )
4
4
5OS=$1
5OS=$1
6
6
7−if [ -z $OS ]
7+if [ -z $OS ]
8then
8then
9 echo "Usage: build.sh osname"
9 echo "Usage: build.sh osname"
10 exit 1
10 exit 1
bundle/winbuild.sh+3−3
@@ -26,9 +26,9 @@ cp README build/purescript/
26cp ../LICENSE build/purescript/
26cp ../LICENSE build/purescript/
27
27
28# Make the binary bundle
28# Make the binary bundle
29−pushd build
29+pushd build
30tar -zcvf ../win64.tar.gz purescript
30tar -zcvf ../win64.tar.gz purescript
31−popd
31+popd
32
32
33# Calculate the MD5 hash
33# Calculate the MD5 hash
34md5sum win64.tar.gz > win64.md5
34md5sum win64.tar.gz > win64.md5
@@ -36,5 +36,5 @@ md5sum win64.tar.gz > win64.md5
36# Remove the staging directory
36# Remove the staging directory
37rm -rf build/
37rm -rf build/
38
38
39−popd
39+popd
40
40
examples/failing/DuplicateDeclarationsInLet.pursnew file+9
@@ -0,0 +1,9 @@
1+module Main where
2+
3+foo = a
4+ where
5+ a :: Number
6+ a = 1
7+
8+ a :: Number
9+ a = 2
examples/failing/NewtypeMultiArgs.purs+1−1
@@ -1,3 +1,3 @@
1module Main where
1module Main where
2
2
3−newtype Thing = Thing String Boolean
3+newtype Thing = Thing String Boolean
examples/failing/NewtypeMultiCtor.purs+1−1
@@ -1,3 +1,3 @@
1module Main where
1module Main where
2
2
3−newtype Thing = Thing String | Other
3+newtype Thing = Thing String | Other
examples/failing/SkolemEscape2.purs+1−1
@@ -6,4 +6,4 @@ import Control.Monad.ST
6
6
7test _ = do
7test _ = do
8 r <- runST (newSTRef 0)
8 r <- runST (newSTRef 0)
9− return 0
9+ return 0
examples/failing/UnknownType.purs+1−1
@@ -1,4 +1,4 @@
1module Main where
1module Main where
2
2
3test :: Number -> Something
3test :: Number -> Something
4−test = {}
4+test = {}
examples/failing/UnknownValue.pursdeleted−25
@@ -1,25 +0,0 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff
5−import Control.Monad.ST
6−import Debug.Trace
7−
8−test = runSTArray (do
9− a <- newSTArray 2 0
10− pokeSTArray a 0 1
11− pokeSTArray a 1 2
12− return a)
13−
14−fromTo lo hi = runSTArray (do
15− arr <- newSTArray (hi - lo + 1) 0
16− (let
17− go lo hi _ arr | lo > hi = return arr
18− go lo hi i arr = do
19− pokeSTArray arrr i lo
20− go (lo + 1) hi (i + 1) arr
21− in go lo hi 0 arr))
22−
23−main = do
24− let t1 = runPure (fromTo 10 20)
25− trace "Done"
examples/manual/failing/ArgLengthMismatch.purs+1−1
@@ -1,4 +1,4 @@
1module ArgLengthMismatch where
1module ArgLengthMismatch where
2
2
3 f x y = true
3 f x y = true
4− f = false
4+ f = false
examples/manual/failing/ExportExplicit.purs+1−1
@@ -2,4 +2,4 @@
2module M1 (x, y, z) where
2module M1 (x, y, z) where
3
3
4 x = 1
4 x = 1
5− y = 2
5+ y = 2
examples/manual/failing/ExportExplicit1.purs+2−2
@@ -5,9 +5,9 @@ module M1 (X(X)) where
5module Main where
5module Main where
6
6
7 import M1
7 import M1
8−
8+
9 testX = X
9 testX = X
10−
10+
11 -- should fail as Y constructor is not exported from M1
11 -- should fail as Y constructor is not exported from M1
12 testY = Y
12 testY = Y
13
13
examples/manual/failing/ExportExplicit2.purs+1−1
@@ -2,4 +2,4 @@
2module M1 (X(Y)) where
2module M1 (X(Y)) where
3
3
4 data X = X
4 data X = X
5− data Y = Y
5+ data Y = Y
examples/manual/failing/ExportExplicit3.purs+1−1
@@ -6,7 +6,7 @@ module M1 (X(..)) where
6module Main where
6module Main where
7
7
8 import M1
8 import M1
9−
9+
10 -- should fail as Z is not exported from M1
10 -- should fail as Z is not exported from M1
11 testZ = M1.Z
11 testZ = M1.Z
12
12
examples/manual/failing/RedefinedFixity.purs+1−1
@@ -1,6 +1,6 @@
1module RedefinedFixity where
1module RedefinedFixity where
2
2
3 (!?) x y = x + y
3 (!?) x y = x + y
4−
4+
5 infix 2 !?
5 infix 2 !?
6 infix 2 !?
6 infix 2 !?
examples/manual/failing/RequiredHiddenType.purs+2−2
@@ -3,6 +3,6 @@ module Foo (B(..), a, b) where
3
3
4 data A = A
4 data A = A
5 data B = B
5 data B = B
6−
6+
7 a = A
7 a = A
8− b = B
8+ b = B
examples/manual/passing/ExportExplicit.purs+2−2
@@ -3,7 +3,7 @@ module M1 (X(X), Z(..), foo) where
3 data X = X | Y
3 data X = X | Y
4 data Z = Z
4 data Z = Z
5
5
6− foo :: Number
6+ foo :: Number
7 foo = 0
7 foo = 0
8
8
9 bar :: Number
9 bar :: Number
@@ -12,7 +12,7 @@ module M1 (X(X), Z(..), foo) where
12module Main where
12module Main where
13
13
14 import M1
14 import M1
15−
15+
16 testX = X
16 testX = X
17 testZ = Z
17 testZ = Z
18 testFoo = foo
18 testFoo = foo
examples/manual/passing/ExportExplicit2.purs+1−1
@@ -1,6 +1,6 @@
1module M1 (bar) where
1module M1 (bar) where
2
2
3− foo :: Number
3+ foo :: Number
4 foo = 0
4 foo = 0
5
5
6 bar :: Number
6 bar :: Number
examples/manual/passing/Import.purs+1−1
@@ -13,7 +13,7 @@ module M2 where
13 import M1
13 import M1
14
14
15 main = \_ -> foo 42
15 main = \_ -> foo 42
16−
16+
17module Main where
17module Main where
18
18
19main = Debug.Trace.trace "Done"
19main = Debug.Trace.trace "Done"
examples/manual/passing/ImportExplicit.purs+1−1
@@ -7,7 +7,7 @@ module Main where
7
7
8 import M1 (X(..))
8 import M1 (X(..))
9
9
10− testX :: X
10+ testX :: X
11 testX = X
11 testX = X
12 testY = Y
12 testY = Y
13
13
examples/manual/passing/ImportQualified.purs+3−3
@@ -1,5 +1,5 @@
1module M1 where
1module M1 where
2−
2+
3 trace x = x
3 trace x = x
4
4
5module Main where
5module Main where
@@ -8,5 +8,5 @@ module Main where
8 import Control.Monad.Eff
8 import Control.Monad.Eff
9 import M1
9 import M1
10 import qualified Debug.Trace as T
10 import qualified Debug.Trace as T
11−
11+
12− main = T.trace (trace "Done")
12+ main = T.trace (trace "Done")
examples/manual/passing/Module.purs+1−1
@@ -22,7 +22,7 @@ module M2 where
22
22
23 match :: M1.Foo -> String
23 match :: M1.Foo -> String
24 match = \f -> case f of M1.Foo s -> s ++ "foo"
24 match = \f -> case f of M1.Foo s -> s ++ "foo"
25−
25+
26module Main where
26module Main where
27
27
28main = Debug.Trace.trace "Done"
28main = Debug.Trace.trace "Done"
examples/manual/passing/ModuleDeps.purs+1−1
@@ -11,7 +11,7 @@ bar = M3.baz
11module M3 where
11module M3 where
12
12
13baz = 1
13baz = 1
14−
14+
15module Main where
15module Main where
16
16
17main = Debug.Trace.trace "Done"
17main = Debug.Trace.trace "Done"
examples/passing/810.pursnew file+11
@@ -0,0 +1,11 @@
1+module Main where
2+
3+data Maybe a = Nothing | Just a
4+
5+test :: forall a. Maybe a -> Maybe a
6+test m = o.x
7+ where
8+ o = case m of Nothing -> { x : Nothing }
9+ Just a -> { x : Just a }
10+
11+main = Debug.Trace.trace "Done"
examples/passing/BindersInFunctions.purs+7−5
@@ -5,12 +5,14 @@ import Prelude
5tail = \(_:xs) -> xs
5tail = \(_:xs) -> xs
6
6
7foreign import error
7foreign import error
8+ """
8− "function error(msg) {\
9+ function error(msg) {
9− \ throw msg;\
10+ throw msg;
11+ }
10− \}" :: forall a. String -> a
12+ """ :: forall a. String -> a
11
13
12−main =
14+main =
13 let ts = tail [1, 2, 3] in
15 let ts = tail [1, 2, 3] in
14− if ts == [2, 3]
16+ if ts == [2, 3]
15 then Debug.Trace.trace "Done"
17 then Debug.Trace.trace "Done"
16 else error "Incorrect result from 'tails'."
18 else error "Incorrect result from 'tails'."
examples/passing/BindingGroups.purs+2−2
@@ -1,6 +1,6 @@
1module Main where
1module Main where
2−
2+
3−foo = bar
3+foo = bar
4 where bar r = r + 1
4 where bar r = r + 1
5
5
6r = foo 2
6r = foo 2
examples/passing/CheckFunction.pursnew file+5
@@ -0,0 +1,5 @@
1+module Main where
2+
3+test = ((\x -> x+1) >>> (\x -> x*2)) 4
4+
5+main = Debug.Trace.trace "Done"
examples/passing/CheckSynonymBug.purs+6−4
@@ -2,12 +2,14 @@ module Main where
2
2
3 import Prelude
3 import Prelude
4
4
5− type Foo a = [a]
5+ type Foo a = [a]
6
6
7 foreign import length
7 foreign import length
8+ """
8− "function length(a) {\
9+ function length(a) {
9− \ return a.length;\
10+ return a.length;
11+ }
10− \}" :: forall a. [a] -> Number
12+ """ :: forall a. [a] -> Number
11
13
12 foo _ = length ([] :: Foo Number)
14 foo _ = length ([] :: Foo Number)
13
15
examples/passing/Comparisons.purs+8−6
@@ -6,12 +6,14 @@ import Debug.Trace
6foreign import data Assert :: !
6foreign import data Assert :: !
7
7
8foreign import assert
8foreign import assert
9+ """
9− "function assert(x) {\
10+ function assert(x) {
10− \ return function () {\
11+ return function() {
11− \ if (!x) throw new Error('assertion failed');\
12+ if (!x) throw new Error('assertion failed');
12− \ return {};\
13+ return {};
13− \ };\
14+ };
15+ }
14− \};" :: forall e. Boolean -> Eff (assert :: Assert | e) Unit
16+ """ :: forall e. Boolean -> Eff (assert :: Assert | e) Unit
15
17
16main = do
18main = do
17 assert (1 < 2)
19 assert (1 < 2)
examples/passing/Conditional.purs+1−1
@@ -2,7 +2,7 @@ module Main where
2
2
3 import Prelude ()
3 import Prelude ()
4
4
5− fns = \f -> if f true then f else \x -> x
5+ fns = \f -> if f true then f else \x -> x
6
6
7 not = \x -> if x then false else true
7 not = \x -> if x then false else true
8
8
examples/passing/Console.purs+1−1
@@ -9,5 +9,5 @@ replicateM_ 0 _ = return {}
9replicateM_ n act = do
9replicateM_ n act = do
10 act
10 act
11 replicateM_ (n - 1) act
11 replicateM_ (n - 1) act
12−
12+
13main = replicateM_ 10 (trace "Hello World!")
13main = replicateM_ 10 (trace "Hello World!")
examples/passing/DeepArrayBinder.purs+6−4
@@ -6,10 +6,12 @@ match2 :: [Number] -> Number
6match2 (x : y : xs) = x * y + match2 xs
6match2 (x : y : xs) = x * y + match2 xs
7match2 _ = 0
7match2 _ = 0
8
8
9−foreign import explode
9+foreign import explode
10+ """
10− "function explode() {\
11+ function explode() {
11− \ throw new Error('Incorrect result');\
12+ throw new Error('Incorrect result');
13+ }
12− \}" :: forall eff a. Eff eff a
14+ """ :: forall eff a. Eff eff a
13
15
14main = case match2 [1, 2, 3, 4, 5, 6, 7, 8, 9] of
16main = case match2 [1, 2, 3, 4, 5, 6, 7, 8, 9] of
15 100 -> Debug.Trace.trace "Done"
17 100 -> Debug.Trace.trace "Done"
examples/passing/DeepCase.purs+2−2
@@ -4,9 +4,9 @@ import Debug.Trace
4import Control.Monad.Eff
4import Control.Monad.Eff
5import Control.Monad.ST
5import Control.Monad.ST
6
6
7−f x y =
7+f x y =
8 let
8 let
9− g = case y of
9+ g = case y of
10 0 -> x
10 0 -> x
11 x -> 1 + x * x
11 x -> 1 + x * x
12 in g + x + y
12 in g + x + y
examples/passing/Dollar.purs+1−1
@@ -12,5 +12,5 @@ id x = x
12test1 x = id $ id $ id $ id $ x
12test1 x = id $ id $ id $ id $ x
13
13
14test2 x = id id $ id x
14test2 x = id id $ id x
15−
15+
16main = Debug.Trace.trace "Done"
16main = Debug.Trace.trace "Done"
examples/passing/EmptyDataDecls.purs+12−8
@@ -11,19 +11,23 @@ nil :: forall a. ArrayBox Z a
11nil = ArrayBox []
11nil = ArrayBox []
12
12
13foreign import concat
13foreign import concat
14+ """
14− "function concat(l1) {\
15+ function concat(l1) {
15− \ return function (l2) {\
16+ return function(l2) {
16− \ return l1.concat(l2);\
17+ return l1.concat(l2);
17− \ };\
18+ };
19+ }
18− \}" :: forall a. [a] -> [a] -> [a]
20+ """ :: forall a. [a] -> [a] -> [a]
19
21
20cons' :: forall a n. a -> ArrayBox n a -> ArrayBox (S n) a
22cons' :: forall a n. a -> ArrayBox n a -> ArrayBox (S n) a
21cons' x (ArrayBox xs) = ArrayBox $ concat [x] xs
23cons' x (ArrayBox xs) = ArrayBox $ concat [x] xs
22
24
23foreign import error
25foreign import error
26+ """
24− "function error(msg) {\
27+ function error(msg) {
25− \ throw msg;\
28+ throw msg;
29+ }
26− \}" :: forall a. String -> a
30+ """ :: forall a. String -> a
27
31
28main = case cons' 1 $ cons' 2 $ cons' 3 nil of
32main = case cons' 1 $ cons' 2 $ cons' 3 nil of
29 ArrayBox [1, 2, 3] -> Debug.Trace.trace "Done"
33 ArrayBox [1, 2, 3] -> Debug.Trace.trace "Done"
examples/passing/EmptyRow.purs+1−1
@@ -1,6 +1,6 @@
1module Main where
1module Main where
2
2
3−data Foo r = Foo { | r }
3+data Foo r = Foo { | r }
4
4
5test :: Foo ()
5test :: Foo ()
6test = Foo {}
6test = Foo {}
examples/passing/ExtendedInfixOperators.pursnew file+20
@@ -0,0 +1,20 @@
1+module Main where
2+
3+zipWith :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
4+zipWith _ [] _ = []
5+zipWith _ _ [] = []
6+zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
7+
8+test1 = [1, 2, 3] `zipWith (+)` [4, 5, 6]
9+
10+comparing :: forall a b. (Ord b) => (a -> b) -> a -> a -> Ordering
11+comparing f = compare `Data.Function.on` f
12+
13+sum [] = 0
14+sum (x:xs) = x + sum xs
15+
16+test2 = [1, 2, 3] `comparing sum` [4, 5, 6]
17+
18+main = do
19+ Debug.Trace.print test1
20+ Debug.Trace.print test2
examples/passing/ExternRaw.purs+20−7
@@ -1,13 +1,26 @@
1module Main where
1module Main where
2
2
3−foreign import first "function first(xs) { return xs[0]; }" :: forall a. [a] -> a
3+foreign import first
4+ """
5+ function first(xs) {
6+ return xs[0];
7+ }
8+ """ :: forall a. [a] -> a
4
9
5−foreign import loop "function loop() { while (true) {} }" :: forall a. a
10+foreign import loop
11+ """
12+ function loop() {
13+ while (true) {}
14+ }
15+ """ :: forall a. a
6
16
7−foreign import concat "function concat(xs) { \
17+foreign import concat
18+ """
19+ function concat(xs) {
8− \ return function(ys) { \
20+ return function(ys) {
9− \ return xs.concat(ys); \
21+ return xs.concat(ys);
10− \ };\
22+ };
23+ }
11− \}" :: forall a. [a] -> [a] -> [a]
24+ """ :: forall a. [a] -> [a] -> [a]
12
25
13main = Debug.Trace.trace "Done"
26main = Debug.Trace.trace "Done"
examples/passing/FFI.purs+6−4
@@ -1,9 +1,11 @@
1module Main where
1module Main where
2
2
3−foreign import foo
3+foreign import foo
4+ """
4− "function foo(s) {\
5+ function foo(s) {
5− \ return s;\
6+ return s;
7+ }
6− \}" :: String -> String
8+ """ :: String -> String
7
9
8bar :: String -> String
10bar :: String -> String
9bar _ = foo "test"
11bar _ = foo "test"
examples/passing/FinalTagless.purs+1−1
@@ -5,7 +5,7 @@ import Prelude
5class E e where
5class E e where
6 num :: Number -> e Number
6 num :: Number -> e Number
7 add :: e Number -> e Number -> e Number
7 add :: e Number -> e Number -> e Number
8−
8+
9type Expr a = forall e. (E e) => e a
9type Expr a = forall e. (E e) => e a
10
10
11data Id a = Id a
11data Id a = Id a
examples/passing/FunctionScope.purs+6−4
@@ -5,10 +5,12 @@ module Main where
5 mkValue :: Number -> Number
5 mkValue :: Number -> Number
6 mkValue id = id
6 mkValue id = id
7
7
8− foreign import error
8+ foreign import error
9+ """
9− "function error(msg) {\
10+ function error(msg) {
10− \ throw msg;\
11+ throw msg;
12+ }
11− \}" :: forall a. String -> a
13+ """ :: forall a. String -> a
12
14
13 main = do
15 main = do
14 let value = mkValue 1
16 let value = mkValue 1
examples/passing/Functions2.purs+5−3
@@ -6,9 +6,11 @@ module Main where
6 test = \const _ -> const
6 test = \const _ -> const
7
7
8 foreign import error
8 foreign import error
9+ """
9− "function error(msg) {\
10+ function error(msg) {
10− \ throw msg;\
11+ throw msg;
12+ }
11− \}" :: forall a. String -> a
13+ """ :: forall a. String -> a
12
14
13 main = do
15 main = do
14 let value = test "Done" {}
16 let value = test "Done" {}
examples/passing/Guards.purs+2−2
@@ -21,9 +21,9 @@ module Main where
21 | otherwise -> m
21 | otherwise -> m
22
22
23 testIndentation :: Number -> Number -> Number
23 testIndentation :: Number -> Number -> Number
24− testIndentation x y | x > 0
24+ testIndentation x y | x > 0
25 = x + y
25 = x + y
26− | otherwise
26+ | otherwise
27 = y - x
27 = y - x
28
28
29 main = Debug.Trace.trace $ min "Done" "ZZZZ"
29 main = Debug.Trace.trace $ min "Done" "ZZZZ"
examples/passing/HoistError.purs+7−5
@@ -4,11 +4,13 @@ import Control.Monad.Eff
4import Debug.Trace
4import Debug.Trace
5
5
6foreign import f
6foreign import f
7+ """
7− "function f(x) {\
8+ function f(x) {
8− \ return function () {\
9+ return function() {
9− \ if (x !== 0) throw new Error('x is not 0');\
10+ if (x !== 0) throw new Error('x is not 0');
11+ };
10− \ }\
12+ }
11− \}" :: forall e. Number -> Eff e Number
13+ """ :: forall e. Number -> Eff e Number
12
14
13main = do
15main = do
14 let x = 0
16 let x = 0
examples/passing/JSReserved.purs+2−2
@@ -4,9 +4,9 @@ module Main where
4
4
5 yield = 0
5 yield = 0
6 member = 1
6 member = 1
7−
7+
8 public = \return -> return
8 public = \return -> return
9−
9+
10 this catch = catch
10 this catch = catch
11
11
12 main = Debug.Trace.trace "Done"
12 main = Debug.Trace.trace "Done"
examples/passing/KindedType.purs+1−1
@@ -26,6 +26,6 @@ class Clazz (a :: *) where
26 def :: a
26 def :: a
27
27
28instance clazzString :: Clazz String where
28instance clazzString :: Clazz String where
29− def = "test"
29+ def = "test"
30
30
31main = Debug.Trace.trace "Done"
31main = Debug.Trace.trace "Done"
examples/passing/Let.purs+7−7
@@ -4,12 +4,12 @@ import Prelude
4import Control.Monad.Eff
4import Control.Monad.Eff
5import Control.Monad.ST
5import Control.Monad.ST
6
6
7−test1 x = let
7+test1 x = let
8 y :: Number
8 y :: Number
9− y = x + 1
9+ y = x + 1
10 in y
10 in y
11
11
12−test2 x y =
12+test2 x y =
13 let x' = x + 1 in
13 let x' = x + 1 in
14 let y' = y + 1 in
14 let y' = y + 1 in
15 x' + y'
15 x' + y'
@@ -17,10 +17,10 @@ test2 x y =
17test3 = let f x y z = x + y + z in
17test3 = let f x y z = x + y + z in
18 f 1 2 3
18 f 1 2 3
19
19
20−test4 = let f x [y, z] = x y z in
20+test4 = let f x [y, z] = x y z in
21 f (+) [1, 2]
21 f (+) [1, 2]
22
22
23−test5 = let
23+test5 = let
24 f x | x > 0 = g (x / 2) + 1
24 f x | x > 0 = g (x / 2) + 1
25 f x = 0
25 f x = 0
26 g x = f (x - 1) + 1
26 g x = f (x - 1) + 1
@@ -42,12 +42,12 @@ test7 = let
42 in if f true then f 1 else f 2
42 in if f true then f 1 else f 2
43
43
44test8 :: Number -> Number
44test8 :: Number -> Number
45−test8 x = let
45+test8 x = let
46 go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
46 go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
47 go y = go $ (y + x / y) / 2
47 go y = go $ (y + x / y) / 2
48 in go x
48 in go x
49
49
50−test10 _ =
50+test10 _ =
51 let
51 let
52 f x = g x * 3
52 f x = g x * 3
53 g x = f x / 2
53 g x = f x / 2
examples/passing/Monad.purs+2−2
@@ -17,12 +17,12 @@ module Main where
17 maybe = { return : Just
17 maybe = { return : Just
18 , bind : \ma f -> case ma of
18 , bind : \ma f -> case ma of
19 Nothing -> Nothing
19 Nothing -> Nothing
20− Just a -> f a
20+ Just a -> f a
21 }
21 }
22
22
23 test :: forall m. Monad m -> m Number
23 test :: forall m. Monad m -> m Number
24 test = \m -> m.bind (m.return 1) (\n1 ->
24 test = \m -> m.bind (m.return 1) (\n1 ->
25− m.bind (m.return "Test") (\n2 ->
25+ m.bind (m.return "Test") (\n2 ->
26 m.return n1))
26 m.return n1))
27
27
28 test1 = test id
28 test1 = test id
examples/passing/MutRec.purs+1−1
@@ -1,4 +1,4 @@
1−module Main where
1+module Main where
2
2
3 import Prelude
3 import Prelude
4
4
examples/passing/MutRec2.purs+1−1
@@ -1,7 +1,7 @@
1module Main where
1module Main where
2
2
3data A = A B
3data A = A B
4−
4+
5data B = B A
5data B = B A
6
6
7foreign import data S :: *
7foreign import data S :: *
examples/passing/MutRec3.purs+1−1
@@ -1,7 +1,7 @@
1module Main where
1module Main where
2
2
3data A = A B
3data A = A B
4−
4+
5data B = B A
5data B = B A
6
6
7foreign import data S :: *
7foreign import data S :: *
examples/passing/NamedPatterns.purs+1−1
@@ -1,6 +1,6 @@
1module Main where
1module Main where
2
2
3− foo = \x -> case x of
3+ foo = \x -> case x of
4 y@{ foo = "Foo" } -> y
4 y@{ foo = "Foo" } -> y
5 y -> y
5 y -> y
6
6
examples/passing/Newtype.purs+3−3
@@ -12,11 +12,11 @@ newtype Box a = Box a
12
12
13instance showBox :: (Show a) => Show (Box a) where
13instance showBox :: (Show a) => Show (Box a) where
14 show (Box x) = "Box " ++ show x
14 show (Box x) = "Box " ++ show x
15−
15+
16apply f x = f x
16apply f x = f x
17−
17+
18main = do
18main = do
19 print $ Thing "hello"
19 print $ Thing "hello"
20 print $ Box 42
20 print $ Box 42
21 print $ apply Box 9000
21 print $ apply Box 9000
22− trace "Done"
22+ trace "Done"
examples/passing/NewtypeWithRecordUpdate.pursnew file+15
@@ -0,0 +1,15 @@
1+-- https://github.com/purescript/purescript/issues/812
2+
3+module Main where
4+
5+import Debug.Trace
6+
7+newtype NewType a = NewType (Object a)
8+
9+rec1 :: Object (a :: Number, b :: Number, c:: Number)
10+rec1 = { a: 0, b: 0, c: 0 }
11+
12+rec2 :: NewType (a :: Number, b :: Number, c :: Number)
13+rec2 = NewType (rec1 { a = 1 })
14+
15+main = trace "Done"
examples/passing/ObjectGetter.pursnew file+11
@@ -0,0 +1,11 @@
1+module Main where
2+
3+getX = _.x
4+
5+point = { x: 1, y: 0 }
6+
7+main = do
8+ Debug.Trace.print $ getX point
9+ Debug.Trace.trace $ _." 123 string Prop Name " { " 123 string Prop Name ": "OK" }
10+ Debug.Trace.trace $ (_.x >>> _.y) { x: { y: "Nested" } }
11+ Debug.Trace.trace $ _.value { value: "Done!" }
examples/passing/ObjectSynonym.purs+1−1
@@ -10,4 +10,4 @@ type Outer = { inner :: Inner }
10outer :: Outer
10outer :: Outer
11outer = { inner: inner }
11outer = { inner: inner }
12
12
13−main = Debug.Trace.trace "Done"
13+main = Debug.Trace.trace "Done"
examples/passing/ObjectUpdate2.purs+1−1
@@ -7,7 +7,7 @@ foreign import x "var x = {};" :: forall r. X r
7blah :: forall r. X r -> X r
7blah :: forall r. X r -> X r
8blah x = x
8blah x = x
9
9
10−test = blah x
10+test = blah x
11 { baz = "blah"
11 { baz = "blah"
12 }
12 }
13
13
examples/passing/ObjectUpdater.pursnew file+35
@@ -0,0 +1,35 @@
1+module Main where
2+
3+import Control.Monad.Eff
4+import Debug.Trace
5+
6+foreign import eqeqeq
7+ """
8+ function eqeqeq(x) {
9+ return function (y) {
10+ if (x == y) return x;
11+ throw new Error("Unexpected result: " + x + " /== " + y);
12+ };
13+ };
14+ """ :: forall a. a -> a -> a
15+
16+(===) = eqeqeq
17+infixl 4 ===
18+
19+getValue :: forall e. Eff (| e) Boolean
20+getValue = return true
21+
22+main = do
23+ let record = { value: false }
24+ record' <- record { value = _ } <$> getValue
25+ print $ record'.value === true
26+
27+ let point = { x: 1, y: 1 }
28+ x = 10
29+ point' = (point { x = _, y = x }) 100
30+
31+ print $ point'.x === 100
32+ print $ point'.y === 10
33+
34+ let record2 = (_ { x = _ }) { x: 0 } 10
35+ print $ record2.x === 10
examples/passing/ObjectWildcards.pursnew file+31
@@ -0,0 +1,31 @@
1+module Main where
2+
3+import Control.Monad.Eff
4+import Debug.Trace
5+
6+mkRecord = { foo: _, bar: _, baz: "baz" }
7+
8+getValue :: forall e. Eff (| e) Boolean
9+getValue = return true
10+
11+foreign import eqeqeq
12+ """
13+ function eqeqeq(x) {
14+ return function (y) {
15+ if (x == y) return x;
16+ throw new Error("Unexpected result: " + x + " /== " + y);
17+ };
18+ };
19+ """ :: forall a. a -> a -> a
20+
21+(===) = eqeqeq
22+infixl 4 ===
23+
24+main = do
25+ obj <- { value: _ } <$> getValue
26+ print obj.value
27+ let x = 1
28+ point <- { x: _, y: x } <$> return 2
29+ print $ point.x === 2
30+ print $ point.y === 1
31+ trace (mkRecord 1 "Done!").bar
examples/passing/Objects.purs+1−1
@@ -31,5 +31,5 @@ module Main where
31 { "***": n } -> n
31 { "***": n } -> n
32
32
33 test7 {a: snoog , b : blah } = blah
33 test7 {a: snoog , b : blah } = blah
34−
34+
35 main = Debug.Trace.trace "Done"
35 main = Debug.Trace.trace "Done"
examples/passing/OneConstructor.purs+1−1
@@ -2,6 +2,6 @@ module Main where
2
2
3data One a = One a
3data One a = One a
4
4
5−one (One a) = a
5+one' (One a) = a
6
6
7main = Debug.Trace.trace "Done"
7main = Debug.Trace.trace "Done"
examples/passing/OperatorAssociativity.purs+34−7
@@ -1,15 +1,42 @@
1module Main where
1module Main where
2
2
3import Control.Monad.Eff
3import Control.Monad.Eff
4+import Debug.Trace
5+
6+foreign import data Assert :: !
7+
8+foreign import assert
9+ """
10+ function assert(x) {
11+ return function(desc) {
12+ return function() {
13+ if (!x) throw new Error('assertion (' + desc + ') failed');
14+ return {};
15+ };
16+ };
17+ }
18+ """ :: forall e. Boolean -> String -> Eff (assert :: Assert | e) Unit
4
19
5bug :: Number -> Number -> Number
20bug :: Number -> Number -> Number
6bug a b = 0 - (a - b)
21bug a b = 0 - (a - b)
7
22
8−foreign import explode
23+foreign import explode
24+ """
9− "function explode() {\
25+ function explode() {
10− \ throw new Error('Assertion failed!');\
26+ throw new Error('Assertion failed!');
27+ }
11− \}":: forall eff a. Eff eff a
28+ """ :: forall eff a. Eff eff a
29+
30+main = do
31+ assert (bug 0 2 == 2) "bug 0 2 == 2"
32+ assert (0 - (0 - 2) == 2) "0 - (0 - 2) == 2"
33+ assert (0 - (0 + 2) == -2) "0 - (0 + 2) == -2"
34+
35+ assert (6 / (3 * 2) == 1) "6 / (3 * 2) == 1"
36+ assert ((6 / 3) * 2 == 4) "(6 / 3) * 2 == 4"
37+
38+ assert (6 % (2 * 2) == 2) "6 % (2 * 2) == 2"
39+ assert ((6 % 2) * 2 == 0) "(6 % 2) * 2 == 0"
12
40
13−main = case bug 0 2 of
41+ assert (4 % (9 / 3) == 1) "4 % (9 / 3) == 1"
14− 2 -> Debug.Trace.trace "Done!"
42+ assert ((4 % 9) / 2 == 2) "(4 % 9) / 2 == 2"
15− _ -> explode
examples/passing/OperatorSections.pursnew file+21
@@ -0,0 +1,21 @@
1+module Main where
2+
3+foreign import eqeqeq
4+ """
5+ function eqeqeq(x) {
6+ return function (y) {
7+ if (x == y) return x;
8+ throw new Error("Unexpected result: " + x + " /== " + y);
9+ };
10+ };
11+ """ :: forall a. a -> a -> a
12+
13+(===) = eqeqeq
14+infixl 4 ===
15+
16+main = do
17+ Debug.Trace.print $ (/ 2) 4 === 2
18+ Debug.Trace.print $ (2 /) 4 === 0.5
19+ Debug.Trace.print $ (`const` 1) 2 === 2
20+ Debug.Trace.print $ (1 `const`) 2 === 1
21+ Debug.Trace.trace "Done!"
examples/passing/Operators.purs+23−5
@@ -2,7 +2,7 @@ module Main where
2
2
3 import Control.Monad.Eff
3 import Control.Monad.Eff
4 import Debug.Trace
4 import Debug.Trace
5−
5+
6 (?!) :: forall a. a -> a -> a
6 (?!) :: forall a. a -> a -> a
7 (?!) x _ = x
7 (?!) x _ = x
8
8
@@ -29,7 +29,7 @@ module Main where
29
29
30 test6 = ((\x -> x) `k` 2) 3
30 test6 = ((\x -> x) `k` 2) 3
31
31
32− (<+>) :: String -> String -> String
32+ (<+>) :: String -> String -> String
33 (<+>) = \s1 s2 -> s1 ++ s2
33 (<+>) = \s1 s2 -> s1 ++ s2
34
34
35 test7 = "Hello" <+> "World!"
35 test7 = "Hello" <+> "World!"
@@ -39,7 +39,7 @@ module Main where
39
39
40 foo :: String -> String
40 foo :: String -> String
41 foo = \s -> s
41 foo = \s -> s
42−
42+
43 test8 = foo @@ "Hello World"
43 test8 = foo @@ "Hello World"
44
44
45 test9 = Main.foo @@ "Hello World"
45 test9 = Main.foo @@ "Hello World"
@@ -52,7 +52,7 @@ module Main where
52 test11 = [1, 2, 3] ... [4, 5, 6]
52 test11 = [1, 2, 3] ... [4, 5, 6]
53
53
54 test12 (<%>) a b = a <%> b
54 test12 (<%>) a b = a <%> b
55−
55+
56 test13 = \(<%>) a b -> a <%> b
56 test13 = \(<%>) a b -> a <%> b
57
57
58 test14 :: Number -> Number -> Boolean
58 test14 :: Number -> Number -> Boolean
@@ -61,9 +61,23 @@ module Main where
61 test15 :: Number -> Number -> Boolean
61 test15 :: Number -> Number -> Boolean
62 test15 a b = const false $ a `test14` b
62 test15 a b = const false $ a `test14` b
63
63
64− test16 :: Number -> Number -> Number
64+ test16 :: Number -> Number -> Number
65 test16 x y = x .|. y .&. y
65 test16 x y = x .|. y .&. y
66
66
67+ test17 :: Number
68+ test17 = negate (-1)
69+
70+ test18 :: Number
71+ test18 = negate $ negate 1
72+
73+ test19 :: Number
74+ test19 = negate $ negate (-1)
75+
76+ test20 :: Number
77+ test20 = 1 @ 2
78+ where
79+ (@) x y = x + y * y
80+
67 main = do
81 main = do
68 let t1 = test1 1 2 (\x y -> x + y)
82 let t1 = test1 1 2 (\x y -> x + y)
69 let t2 = test2
83 let t2 = test2
@@ -81,4 +95,8 @@ module Main where
81 let t14 = test14 1 2
95 let t14 = test14 1 2
82 let t15 = test15 1 2
96 let t15 = test15 1 2
83 let t16 = test16 1 2
97 let t16 = test16 1 2
98+ let t17 = test17
99+ let t18 = test18
100+ let t19 = test19
101+ let t20 = test20
84 trace "Done"
102 trace "Done"
examples/passing/OptimizerBug.purs+1−1
@@ -5,5 +5,5 @@ import Prelude
5x a = 1 + y a
5x a = 1 + y a
6
6
7y a = x a
7y a = x a
8−
8+
9main = Debug.Trace.trace "Done"
9main = Debug.Trace.trace "Done"
examples/passing/PartialFunction.purs+10−8
@@ -1,14 +1,16 @@
1module Main where
1module Main where
2
2
3foreign import testError
3foreign import testError
4+ """
4− "function testError(f) {\
5+ function testError(f) {
5− \ try {\
6+ try {
6− \ return f();\
7+ return f();
7− \ } catch (e) {\
8+ } catch (e) {
8− \ if (e instanceof Error) return 'success';\
9+ if (e instanceof Error) return 'success';
9− \ throw new Error('Pattern match failure is not Error');\
10+ throw new Error('Pattern match failure is not Error');
10− \ }\
11+ }
12+ }
11− \}" :: (Unit -> Number) -> String
13+ """ :: (Unit -> Number) -> String
12
14
13fn :: Number -> Number
15fn :: Number -> Number
14fn 0 = 0
16fn 0 = 0
examples/passing/Patterns.purs+3−3
@@ -2,7 +2,7 @@ module Main where
2
2
3 import Prelude
3 import Prelude
4
4
5− test = \x -> case x of
5+ test = \x -> case x of
6 { str = "Foo", bool = true } -> true
6 { str = "Foo", bool = true } -> true
7 { str = "Bar", bool = b } -> b
7 { str = "Bar", bool = b } -> b
8 _ -> false
8 _ -> false
@@ -17,12 +17,12 @@ module Main where
17 _ -> 0
17 _ -> 0
18
18
19
19
20− h = \o -> case o of
20+ h = \o -> case o of
21 a@[_,_,_] -> a
21 a@[_,_,_] -> a
22 _ -> []
22 _ -> []
23
23
24 isDesc :: [Number] -> Boolean
24 isDesc :: [Number] -> Boolean
25 isDesc [x, y] | x > y = true
25 isDesc [x, y] | x > y = true
26 isDesc _ = false
26 isDesc _ = false
27−
27+
28 main = Debug.Trace.trace "Done"
28 main = Debug.Trace.trace "Done"
examples/passing/Person.purs+8−6
@@ -4,13 +4,15 @@ module Main where
4
4
5 data Person = Person { name :: String, age :: Number }
5 data Person = Person { name :: String, age :: Number }
6
6
7− foreign import itoa
7+ foreign import itoa
8+ """
8− "function itoa(n) {\
9+ function itoa(n) {
9− \ return n.toString();\
10+ return n.toString();
11+ }
10− \}" :: Number -> String
12+ """ :: Number -> String
11−
13+
12 showPerson :: Person -> String
14 showPerson :: Person -> String
13 showPerson = \p -> case p of
15 showPerson = \p -> case p of
14 Person o -> o.name ++ ", aged " ++ itoa(o.age)
16 Person o -> o.name ++ ", aged " ++ itoa(o.age)
15−
17+
16 main = Debug.Trace.trace "Done"
18 main = Debug.Trace.trace "Done"
examples/passing/Rank2Data.purs+7−7
@@ -12,18 +12,18 @@ module Main where
12 runNat = \nat -> case nat of
12 runNat = \nat -> case nat of
13 Nat f -> f 0 (\n -> n + 1)
13 Nat f -> f 0 (\n -> n + 1)
14
14
15− zero = Nat (\zero _ -> zero)
15+ zero' = Nat (\zero' _ -> zero')
16
16
17 succ = \n -> case n of
17 succ = \n -> case n of
18− Nat f -> Nat (\zero succ -> succ (f zero succ))
18+ Nat f -> Nat (\zero' succ -> succ (f zero' succ))
19
19
20 add = \n m -> case n of
20 add = \n m -> case n of
21 Nat f -> case m of
21 Nat f -> case m of
22− Nat g -> Nat (\zero succ -> g (f zero succ) succ)
22+ Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
23
23
24− one = succ zero
24+ one' = succ zero'
25− two = succ zero
25+ two = succ zero'
26 four = add two two
26 four = add two two
27 fourNumber = runNat four
27 fourNumber = runNat four
28−
28+
29− main = Debug.Trace.trace "Done"
29+ main = Debug.Trace.trace "Done'"
examples/passing/Rank2TypeSynonym.purs+2−2
@@ -3,10 +3,10 @@ module Main where
3import Control.Monad.Eff
3import Control.Monad.Eff
4
4
5type Foo a = forall f. (Monad f) => f a
5type Foo a = forall f. (Monad f) => f a
6−
6+
7foo :: forall a. a -> Foo a
7foo :: forall a. a -> Foo a
8foo x = pure x
8foo x = pure x
9−
9+
10bar :: Foo Number
10bar :: Foo Number
11bar = foo 3
11bar = foo 3
12
12
examples/passing/Rank2Types.purs+1−1
@@ -7,5 +7,5 @@ module Main where
7
7
8 forever :: forall m a b. (forall a b. m a -> (a -> m b) -> m b) -> m a -> m b
8 forever :: forall m a b. (forall a b. m a -> (a -> m b) -> m b) -> m a -> m b
9 forever = \bind action -> bind action $ \_ -> forever bind action
9 forever = \bind action -> bind action $ \_ -> forever bind action
10−
10+
11 main = Debug.Trace.trace "Done"
11 main = Debug.Trace.trace "Done"
examples/passing/Recursion.purs+1−1
@@ -6,5 +6,5 @@ module Main where
6 0 -> 1
6 0 -> 1
7 1 -> 1
7 1 -> 1
8 n -> fib (n - 1) + fib (n - 2)
8 n -> fib (n - 1) + fib (n - 2)
9−
9+
10 main = Debug.Trace.trace "Done"
10 main = Debug.Trace.trace "Done"
examples/passing/RowPolyInstanceContext.pursnew file+20
@@ -0,0 +1,20 @@
1+module Main where
2+
3+class T s m where
4+ state :: (s -> s) -> m Unit
5+
6+data S s a = S (s -> { new :: s, ret :: a })
7+
8+instance st :: T s (S s) where
9+ state f = S $ \s -> { new: f s, ret: unit }
10+
11+test1 :: forall r . S { foo :: String | r } Unit
12+test1 = state $ \o -> o { foo = o.foo ++ "!" }
13+
14+test2 :: forall m r . (T { foo :: String | r } m) => m Unit
15+test2 = state $ \o -> o { foo = o.foo ++ "!" }
16+
17+main = do
18+ let t1 = test1
19+ let t2 = test2
20+ Debug.Trace.trace "Done"
examples/passing/RowSynonyms.pursnew file+46
@@ -0,0 +1,46 @@
1+module Main where
2+
3+import Control.Monad.Eff
4+import Control.Monad.ST
5+
6+type State bindings =
7+ {
8+ bindings :: {addition :: Number | bindings},
9+ other :: String
10+ }
11+
12+type MyBindings = (test :: Number)
13+
14+data Shadow bindings = Shadow String
15+
16+shadows :: Shadow (Object MyBindings)
17+shadows = Shadow "uhh"
18+
19+main :: Eff () Unit
20+main = withIt
21+ shadows
22+ \ bindings -> do
23+ let state =
24+ {
25+ bindings : bindings,
26+ other : "Test"
27+ }
28+ runST do
29+ stRef <- newSTRef state
30+ handleKeyD stRef
31+ return unit
32+
33+
34+withIt :: forall bindings eff a. Shadow (Object bindings) ->
35+ ({addition :: Number | bindings} -> Eff eff a) -> Eff eff a
36+withIt (Shadow str) success = do
37+ b <- withBindings
38+ success (b{addition = 1})
39+
40+foreign import withBindings
41+"""
42+ function withBindings() {}
43+""" :: forall eff bindings. Eff eff bindings
44+
45+handleKeyD :: forall h eff. STRef h (State MyBindings) -> Eff (st :: ST h | eff) Unit
46+handleKeyD state = return unit
examples/passing/ScopedTypeVariables.pursnew file+34
@@ -0,0 +1,34 @@
1+module Main where
2+
3+test1 :: forall a. (a -> a) -> a -> a
4+test1 f x = g (g x)
5+ where
6+ g :: a -> a
7+ g y = f (f y)
8+
9+test2 :: forall a. (a -> a) -> a -> a
10+test2 = h
11+ where
12+ h :: forall b. (b -> b) -> b -> b
13+ h f x = g (g x)
14+ where
15+ g :: b -> b
16+ g y = f (f y)
17+
18+test3 :: Number
19+test3 = ((\b -> b :: b) :: forall b. b -> b) 0
20+
21+test4 :: forall a. (a -> a) -> a -> a
22+test4 = h
23+ where
24+ h :: forall b. (b -> b) -> b -> b
25+ h f x = g (g x)
26+ where
27+ g :: b -> b
28+ g y = j (f (f y))
29+ where
30+ j :: forall b. b -> b
31+ j x = x
32+
33+
34+main = Debug.Trace.trace "Done"
examples/passing/Sequence.purs+2−2
@@ -4,9 +4,9 @@ import Control.Monad.Eff
4
4
5class Sequence t where
5class Sequence t where
6 sequence :: forall m a. (Monad m) => t (m a) -> m (t a)
6 sequence :: forall m a. (Monad m) => t (m a) -> m (t a)
7−
7+
8instance sequenceArray :: Sequence [] where
8instance sequenceArray :: Sequence [] where
9 sequence [] = pure []
9 sequence [] = pure []
10− sequence (x:xs) = (:) <$> x <*> sequence xs
10+ sequence (x:xs) = (:) <$> x <*> sequence xs
11
11
12main = sequence $ [Debug.Trace.trace "Done"]
12main = sequence $ [Debug.Trace.trace "Done"]
examples/passing/ShadowedRename.purs+7−5
@@ -4,11 +4,13 @@ import Control.Monad.Eff
4import Debug.Trace
4import Debug.Trace
5
5
6foreign import f
6foreign import f
7+ """
7− "function f(x) {\
8+ function f(x) {
8− \ return function () {\
9+ return function() {
9− \ if (x !== 2) throw new Error('x is not 2');\
10+ if (x !== 2) throw new Error('x is not 2');
11+ };
10− \ }\
12+ }
11− \}" :: forall e. Number -> Eff e Number
13+ """ :: forall e. Number -> Eff e Number
12
14
13foo foo = let foo_1 = \_ -> foo
15foo foo = let foo_1 = \_ -> foo
14 foo_2 = foo_1 unit + 1
16 foo_2 = foo_1 unit + 1
examples/passing/ShadowedTCO.purs+5−5
@@ -2,14 +2,14 @@ module Main where
2
2
3runNat f = f 0 (\n -> n + 1)
3runNat f = f 0 (\n -> n + 1)
4
4
5−zero z _ = z
5+zero' z _ = z
6
6
7−succ f zero succ = succ (f zero succ)
7+succ f zero' succ = succ (f zero' succ)
8
8
9−add f g zero succ = g (f zero succ) succ
9+add f g zero' succ = g (f zero' succ) succ
10
10
11−one = succ zero
11+one' = succ zero'
12−two = succ one
12+two = succ one'
13four = add two two
13four = add two two
14fourNumber = runNat four
14fourNumber = runNat four
15
15
examples/passing/ShadowedTCOLet.purs+3−3
@@ -1,7 +1,7 @@
1module Main where
1module Main where
2
2
3−f x y z =
3+f x y z =
4− let f 1 2 3 = 1
4+ let f 1 2 3 = 1
5 in f x z y
5 in f x z y
6−
6+
7main = Debug.Trace.trace $ show $ f 1 3 2
7main = Debug.Trace.trace $ show $ f 1 3 2
examples/passing/SignedNumericLiterals.purs+2−2
@@ -6,10 +6,10 @@ module Main where
6 y = -0.5
6 y = -0.5
7 z = 0.5
7 z = 0.5
8 w = 1
8 w = 1
9−
9+
10 f :: Number -> Number
10 f :: Number -> Number
11 f x = -x
11 f x = -x
12
12
13 test1 = 2 - 1
13 test1 = 2 - 1
14−
14+
15 main = Debug.Trace.trace "Done"
15 main = Debug.Trace.trace "Done"
examples/passing/Superclasses3.purs+1−1
@@ -33,7 +33,7 @@ instance applicativeMTrace :: Applicative MTrace where
33instance bindMTrace :: Bind MTrace where
33instance bindMTrace :: Bind MTrace where
34 (>>=) m f = MTrace (runMTrace m >>= (runMTrace <<< f))
34 (>>=) m f = MTrace (runMTrace m >>= (runMTrace <<< f))
35
35
36−instance monadMTrace :: Monad MTrace
36+instance monadMTrace :: Monad MTrace
37
37
38instance writerMTrace :: MonadWriter String MTrace where
38instance writerMTrace :: MonadWriter String MTrace where
39 tell s = MTrace (trace s)
39 tell s = MTrace (trace s)
examples/passing/TailCall.purs+2−2
@@ -9,7 +9,7 @@ test n (x:xs) = test (n + x) xs
9loop :: forall a. Number -> a
9loop :: forall a. Number -> a
10loop x = loop (x + 1)
10loop x = loop (x + 1)
11
11
12−notATailCall = \x ->
12+notATailCall = \x ->
13 (\notATailCall -> notATailCall x) (\x -> x)
13 (\notATailCall -> notATailCall x) (\x -> x)
14−
14+
15main = Debug.Trace.print (test 0 [1, 2, 3])
15main = Debug.Trace.print (test 0 [1, 2, 3])
examples/passing/TopLevelCase.purs+1−1
@@ -14,5 +14,5 @@ module Main where
14 data A = A
14 data A = A
15
15
16 parseTest A 0 = 0
16 parseTest A 0 = 0
17−
17+
18 main = Debug.Trace.trace "Done"
18 main = Debug.Trace.trace "Done"
examples/passing/TypeClassImport.purs+3−3
@@ -7,9 +7,9 @@ foreign import data C :: *
7foreign import t "var t = null;" :: T
7foreign import t "var t = null;" :: T
8
8
9foreign import inst """
9foreign import inst """
10− var inst = {
10+ var inst = {
11− show: function(t) {
11+ show: function(t) {
12− return 'Done';
12+ return 'Done';
13 }
13 }
14 }""" :: C
14 }""" :: C
15
15
examples/passing/TypeClassMemberOrderChange.purs+1−1
@@ -3,7 +3,7 @@ module Main where
3class Test a where
3class Test a where
4 fn :: a -> a -> a
4 fn :: a -> a -> a
5 val :: a
5 val :: a
6−
6+
7instance testBoolean :: Test Boolean where
7instance testBoolean :: Test Boolean where
8 val = true
8 val = true
9 fn x y = y
9 fn x y = y
examples/passing/TypeDecl.purs+1−1
@@ -8,5 +8,5 @@ module Main where
8 iterate :: forall a. Number -> (a -> a) -> a -> a
8 iterate :: forall a. Number -> (a -> a) -> a -> a
9 iterate 0 f a = a
9 iterate 0 f a = a
10 iterate n f a = iterate (n - 1) f (f a)
10 iterate n f a = iterate (n - 1) f (f a)
11−
11+
12 main = Debug.Trace.trace "Done"
12 main = Debug.Trace.trace "Done"
examples/passing/TypeSynonyms.purs+2−2
@@ -1,6 +1,6 @@
1module Main where
1module Main where
2
2
3− type Lens a b =
3+ type Lens a b =
4 { get :: a -> b
4 { get :: a -> b
5 , set :: a -> b -> a
5 , set :: a -> b -> a
6 }
6 }
@@ -14,7 +14,7 @@ module Main where
14 type Pair a b = { fst :: a, snd :: b }
14 type Pair a b = { fst :: a, snd :: b }
15
15
16 fst :: forall a b. Lens (Pair a b) a
16 fst :: forall a b. Lens (Pair a b) a
17− fst =
17+ fst =
18 { get: \p -> p.fst
18 { get: \p -> p.fst
19 , set: \p a -> { fst: a, snd: p.snd }
19 , set: \p a -> { fst: a, snd: p.snd }
20 }
20 }
examples/passing/TypeWildcardsRecordExtension.purs+1−1
@@ -1,5 +1,5 @@
1module Main where
1module Main where
2−
2+
3foo :: forall a. {b :: Number | a} -> {b :: Number | _}
3foo :: forall a. {b :: Number | a} -> {b :: Number | _}
4foo f = f
4foo f = f
5
5
examples/passing/Where.purs+6−6
@@ -7,24 +7,24 @@ import Control.Monad.ST
7test1 x = y
7test1 x = y
8 where
8 where
9 y :: Number
9 y :: Number
10− y = x + 1
10+ y = x + 1
11
11
12test2 x y = x' + y'
12test2 x y = x' + y'
13 where
13 where
14 x' = x + 1
14 x' = x + 1
15 y' = y + 1
15 y' = y + 1
16−
16+
17
17
18test3 = f 1 2 3
18test3 = f 1 2 3
19 where f x y z = x + y + z
19 where f x y z = x + y + z
20−
20+
21
21
22test4 = f (+) [1, 2]
22test4 = f (+) [1, 2]
23 where f x [y, z] = x y z
23 where f x [y, z] = x y z
24−
24+
25
25
26test5 = g 10
26test5 = g 10
27− where
27+ where
28 f x | x > 0 = g (x / 2) + 1
28 f x | x > 0 = g (x / 2) + 1
29 f x = 0
29 f x = 0
30 g x = f (x - 1) + 1
30 g x = f (x - 1) + 1
@@ -35,7 +35,7 @@ test6 = if f true then f 1 else f 2
35
35
36test7 :: Number -> Number
36test7 :: Number -> Number
37test7 x = go x
37test7 x = go x
38− where
38+ where
39 go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
39 go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
40 go y = go $ (y + x / y) / 2
40 go y = go $ (y + x / y) / 2
41
41
examples/passing/s.purs+1−1
@@ -1,5 +1,5 @@
1module Main where
1module Main where
2
2
3 s = \x y z -> x z (y z)
3 s = \x y z -> x z (y z)
4−
4+
5 main = Debug.Trace.trace "Done"
5 main = Debug.Trace.trace "Done"
hierarchy/Main.hs+6−7
@@ -25,13 +25,12 @@ import Options.Applicative
25import System.Directory (createDirectoryIfMissing)
25import System.Directory (createDirectoryIfMissing)
26import System.FilePath ((</>))
26import System.FilePath ((</>))
27import System.Exit (exitFailure, exitSuccess)
27import System.Exit (exitFailure, exitSuccess)
28−import System.IO (stderr)
28+import System.IO (hPutStr, stderr)
29
29
30import Text.Parsec as Par (ParseError)
30import Text.Parsec as Par (ParseError)
31
31
32import qualified Language.PureScript as P
32import qualified Language.PureScript as P
33import qualified Paths_purescript as Paths
33import qualified Paths_purescript as Paths
34−import qualified System.IO.UTF8 as U
35
34
36
35
37data HierarchyOptions = HierarchyOptions
36data HierarchyOptions = HierarchyOptions
@@ -56,14 +55,14 @@ runModuleName (P.ModuleName pns) = intercalate "_" (P.runProperName `map` pns)
56
55
57readInput :: FilePath -> IO (Either Par.ParseError [P.Module])
56readInput :: FilePath -> IO (Either Par.ParseError [P.Module])
58readInput filename = do
57readInput filename = do
59− content <- U.readFile filename
58+ content <- readFile filename
60 return $ fmap (map snd) $ P.parseModulesFromFiles id [(filename, content)]
59 return $ fmap (map snd) $ P.parseModulesFromFiles id [(filename, content)]
61
60
62compile :: HierarchyOptions -> IO ()
61compile :: HierarchyOptions -> IO ()
63compile (HierarchyOptions input mOutput) = do
62compile (HierarchyOptions input mOutput) = do
64 modules <- readInput input
63 modules <- readInput input
65 case modules of
64 case modules of
66− Left err -> U.hPutStr stderr (show err) >> exitFailure
65+ Left err -> hPutStr stderr (show err) >> exitFailure
67 Right ms -> do
66 Right ms -> do
68 for_ ms $ \(P.Module moduleName decls _) ->
67 for_ ms $ \(P.Module moduleName decls _) ->
69 let name = runModuleName moduleName
68 let name = runModuleName moduleName
@@ -76,15 +75,15 @@ compile (HierarchyOptions input mOutput) = do
76 in unless (null supers) $ case mOutput of
75 in unless (null supers) $ case mOutput of
77 Just output -> do
76 Just output -> do
78 createDirectoryIfMissing True output
77 createDirectoryIfMissing True output
79− U.writeFile (output </> name) hier
78+ writeFile (output </> name) hier
80− Nothing -> U.putStrLn hier
79+ Nothing -> putStrLn hier
81 exitSuccess
80 exitSuccess
82
81
83superClasses :: P.Declaration -> [SuperMap]
82superClasses :: P.Declaration -> [SuperMap]
84superClasses (P.TypeClassDeclaration sub _ supers@(_:_) _) =
83superClasses (P.TypeClassDeclaration sub _ supers@(_:_) _) =
85 fmap (\(P.Qualified _ super, _) -> SuperMap (Right (super, sub))) supers
84 fmap (\(P.Qualified _ super, _) -> SuperMap (Right (super, sub))) supers
86superClasses (P.TypeClassDeclaration sub _ _ _) = [SuperMap (Left sub)]
85superClasses (P.TypeClassDeclaration sub _ _ _) = [SuperMap (Left sub)]
87−superClasses (P.PositionedDeclaration _ decl) = superClasses decl
86+superClasses (P.PositionedDeclaration _ _ decl) = superClasses decl
88superClasses _ = []
87superClasses _ = []
89
88
90inputFile :: Parser FilePath
89inputFile :: Parser FilePath
prelude/README.md+343−33
@@ -4,28 +4,40 @@
4
4
5### Types
5### Types
6
6
7− data Ordering where
8− LT :: Ordering
9− GT :: Ordering
10− EQ :: Ordering
7+#### `Ordering`
11
8
9+ data Ordering
10+ = LT
11+ | GT
12+ | EQ
13+
14+#### `Unit`
15+
12− newtype Unit where
16+ newtype Unit
13− Unit :: { } -> Unit
17+ = Unit { }
14
18
15
19
16### Type Classes
20### Type Classes
17
21
18![Prelude](images/Prelude.png)
22![Prelude](images/Prelude.png)
19
23
24+#### `Applicative`
25+
20 class (Apply f) <= Applicative f where
26 class (Apply f) <= Applicative f where
21 pure :: forall a. a -> f a
27 pure :: forall a. a -> f a
22
28
29+#### `Apply`
30+
23 class (Functor f) <= Apply f where
31 class (Functor f) <= Apply f where
24 (<*>) :: forall a b. f (a -> b) -> f a -> f b
32 (<*>) :: forall a b. f (a -> b) -> f a -> f b
25
33
34+#### `Bind`
35+
26 class (Apply m) <= Bind m where
36 class (Apply m) <= Bind m where
27 (>>=) :: forall a b. m a -> (a -> m b) -> m b
37 (>>=) :: forall a b. m a -> (a -> m b) -> m b
28
38
39+#### `Bits`
40+
29 class Bits b where
41 class Bits b where
30 (.&.) :: b -> b -> b
42 (.&.) :: b -> b -> b
31 (.|.) :: b -> b -> b
43 (.|.) :: b -> b -> b
@@ -35,153 +47,349 @@
35 zshr :: b -> Number -> b
47 zshr :: b -> Number -> b
36 complement :: b -> b
48 complement :: b -> b
37
49
50+#### `BoolLike`
51+
38 class BoolLike b where
52 class BoolLike b where
39 (&&) :: b -> b -> b
53 (&&) :: b -> b -> b
40 (||) :: b -> b -> b
54 (||) :: b -> b -> b
41 not :: b -> b
55 not :: b -> b
42
56
57+#### `Category`
58+
43 class (Semigroupoid a) <= Category a where
59 class (Semigroupoid a) <= Category a where
44 id :: forall t. a t t
60 id :: forall t. a t t
45
61
62+#### `DivisionRing`
63+
64+Ring where every nonzero element has a multiplicative inverse (possibly
65+a non-commutative field) so that ```a `mod` b = zero```
66+
67+ class (Ring a, ModuloSemiring a) <= DivisionRing a where
68+
69+#### `Eq`
70+
46 class Eq a where
71 class Eq a where
47 (==) :: a -> a -> Boolean
72 (==) :: a -> a -> Boolean
48 (/=) :: a -> a -> Boolean
73 (/=) :: a -> a -> Boolean
49
74
75+#### `Functor`
76+
50 class Functor f where
77 class Functor f where
51 (<$>) :: forall a b. (a -> b) -> f a -> f b
78 (<$>) :: forall a b. (a -> b) -> f a -> f b
52
79
53− class (Applicative m, Bind m) <= Monad m where
80+#### `ModuloSemiring`
54
81
55− class Num a where
82+Semiring with modulo operation and division where
56− (+) :: a -> a -> a
83+```a / b * b + (a `mod` b) = a```
57− (-) :: a -> a -> a
84+
58− (*) :: a -> a -> a
85+ class (Semiring a) <= ModuloSemiring a where
59 (/) :: a -> a -> a
86 (/) :: a -> a -> a
60− (%) :: a -> a -> a
87+ mod :: a -> a -> a
61− negate :: a -> a
88+
89+#### `Monad`
90+
91+ class (Applicative m, Bind m) <= Monad m where
92+
93+#### `Num`
94+
95+A commutative field
96+
97+ class (DivisionRing a) <= Num a where
98+
99+#### `Ord`
62
100
63 class (Eq a) <= Ord a where
101 class (Eq a) <= Ord a where
64 compare :: a -> a -> Ordering
102 compare :: a -> a -> Ordering
65
103
104+#### `Ring`
105+
106+Addition, multiplication, and subtraction
107+
108+ class (Semiring a) <= Ring a where
109+ (-) :: a -> a -> a
110+
111+#### `Semigroup`
112+
66 class Semigroup a where
113 class Semigroup a where
67 (<>) :: a -> a -> a
114 (<>) :: a -> a -> a
68
115
116+#### `Semigroupoid`
117+
69 class Semigroupoid a where
118 class Semigroupoid a where
70 (<<<) :: forall b c d. a c d -> a b c -> a b d
119 (<<<) :: forall b c d. a c d -> a b c -> a b d
71
120
121+#### `Semiring`
122+
123+Addition and multiplication
124+
125+ class Semiring a where
126+ (+) :: a -> a -> a
127+ zero :: a
128+ (*) :: a -> a -> a
129+ one :: a
130+
131+#### `Show`
132+
72 class Show a where
133 class Show a where
73 show :: a -> String
134 show :: a -> String
74
135
75
136
76### Type Class Instances
137### Type Class Instances
77
138
139+#### `applicativeArr`
140+
78 instance applicativeArr :: Applicative (Prim.Function r)
141 instance applicativeArr :: Applicative (Prim.Function r)
79
142
143+#### `applyArr`
144+
80 instance applyArr :: Apply (Prim.Function r)
145 instance applyArr :: Apply (Prim.Function r)
81
146
147+#### `bindArr`
148+
82 instance bindArr :: Bind (Prim.Function r)
149 instance bindArr :: Bind (Prim.Function r)
83
150
151+#### `bitsNumber`
152+
84 instance bitsNumber :: Bits Number
153 instance bitsNumber :: Bits Number
85
154
155+#### `boolLikeBoolean`
156+
86 instance boolLikeBoolean :: BoolLike Boolean
157 instance boolLikeBoolean :: BoolLike Boolean
87
158
159+#### `categoryArr`
160+
88 instance categoryArr :: Category Prim.Function
161 instance categoryArr :: Category Prim.Function
89
162
163+#### `divisionRingNumber`
164+
165+ instance divisionRingNumber :: DivisionRing Number
166+
167+#### `eqArray`
168+
90 instance eqArray :: (Eq a) => Eq [a]
169 instance eqArray :: (Eq a) => Eq [a]
91
170
171+#### `eqBoolean`
172+
92 instance eqBoolean :: Eq Boolean
173 instance eqBoolean :: Eq Boolean
93
174
175+#### `eqNumber`
176+
94 instance eqNumber :: Eq Number
177 instance eqNumber :: Eq Number
95
178
179+#### `eqOrdering`
180+
96 instance eqOrdering :: Eq Ordering
181 instance eqOrdering :: Eq Ordering
97
182
183+#### `eqString`
184+
98 instance eqString :: Eq String
185 instance eqString :: Eq String
99
186
187+#### `eqUnit`
188+
100 instance eqUnit :: Eq Unit
189 instance eqUnit :: Eq Unit
101
190
191+#### `functorArr`
192+
102 instance functorArr :: Functor (Prim.Function r)
193 instance functorArr :: Functor (Prim.Function r)
103
194
195+#### `moduloSemiringNumber`
196+
197+ instance moduloSemiringNumber :: ModuloSemiring Number
198+
199+#### `monadArr`
200+
104 instance monadArr :: Monad (Prim.Function r)
201 instance monadArr :: Monad (Prim.Function r)
105
202
203+#### `numNumber`
204+
106 instance numNumber :: Num Number
205 instance numNumber :: Num Number
107
206
207+#### `ordArray`
208+
108 instance ordArray :: (Ord a) => Ord [a]
209 instance ordArray :: (Ord a) => Ord [a]
109
210
211+#### `ordBoolean`
212+
110 instance ordBoolean :: Ord Boolean
213 instance ordBoolean :: Ord Boolean
111
214
215+#### `ordNumber`
216+
112 instance ordNumber :: Ord Number
217 instance ordNumber :: Ord Number
113
218
219+#### `ordString`
220+
114 instance ordString :: Ord String
221 instance ordString :: Ord String
115
222
223+#### `ordUnit`
224+
116 instance ordUnit :: Ord Unit
225 instance ordUnit :: Ord Unit
117
226
227+#### `ringNumber`
228+
229+ instance ringNumber :: Ring Number
230+
231+#### `semigroupArr`
232+
118 instance semigroupArr :: (Semigroup s') => Semigroup (s -> s')
233 instance semigroupArr :: (Semigroup s') => Semigroup (s -> s')
119
234
235+#### `semigroupString`
236+
120 instance semigroupString :: Semigroup String
237 instance semigroupString :: Semigroup String
121
238
239+#### `semigroupUnit`
240+
122 instance semigroupUnit :: Semigroup Unit
241 instance semigroupUnit :: Semigroup Unit
123
242
243+#### `semigroupoidArr`
244+
124 instance semigroupoidArr :: Semigroupoid Prim.Function
245 instance semigroupoidArr :: Semigroupoid Prim.Function
125
246
247+#### `semiringNumber`
248+
249+ instance semiringNumber :: Semiring Number
250+
251+#### `showArray`
252+
126 instance showArray :: (Show a) => Show [a]
253 instance showArray :: (Show a) => Show [a]
127
254
255+#### `showBoolean`
256+
128 instance showBoolean :: Show Boolean
257 instance showBoolean :: Show Boolean
129
258
259+#### `showNumber`
260+
130 instance showNumber :: Show Number
261 instance showNumber :: Show Number
131
262
263+#### `showOrdering`
264+
132 instance showOrdering :: Show Ordering
265 instance showOrdering :: Show Ordering
133
266
267+#### `showString`
268+
134 instance showString :: Show String
269 instance showString :: Show String
135
270
271+#### `showUnit`
272+
136 instance showUnit :: Show Unit
273 instance showUnit :: Show Unit
137
274
138
275
139### Values
276### Values
140
277
278+#### `(#)`
279+
141 (#) :: forall a b. a -> (a -> b) -> b
280 (#) :: forall a b. a -> (a -> b) -> b
142
281
282+#### `($)`
283+
143 ($) :: forall a b. (a -> b) -> a -> b
284 ($) :: forall a b. (a -> b) -> a -> b
144
285
286+#### `(++)`
287+
145 (++) :: forall s. (Semigroup s) => s -> s -> s
288 (++) :: forall s. (Semigroup s) => s -> s -> s
146
289
290+#### `(:)`
291+
147 (:) :: forall a. a -> [a] -> [a]
292 (:) :: forall a. a -> [a] -> [a]
148
293
294+#### `(<#>)`
295+
149 (<#>) :: forall f a b. (Functor f) => f a -> (a -> b) -> f b
296 (<#>) :: forall f a b. (Functor f) => f a -> (a -> b) -> f b
150
297
298+#### `(<)`
299+
151 (<) :: forall a. (Ord a) => a -> a -> Boolean
300 (<) :: forall a. (Ord a) => a -> a -> Boolean
152
301
302+#### `(<=)`
303+
153 (<=) :: forall a. (Ord a) => a -> a -> Boolean
304 (<=) :: forall a. (Ord a) => a -> a -> Boolean
154
305
306+#### `(>)`
307+
155 (>) :: forall a. (Ord a) => a -> a -> Boolean
308 (>) :: forall a. (Ord a) => a -> a -> Boolean
156
309
310+#### `(>=)`
311+
157 (>=) :: forall a. (Ord a) => a -> a -> Boolean
312 (>=) :: forall a. (Ord a) => a -> a -> Boolean
158
313
314+#### `(>>>)`
315+
159 (>>>) :: forall a b c d. (Semigroupoid a) => a b c -> a c d -> a b d
316 (>>>) :: forall a b c d. (Semigroupoid a) => a b c -> a c d -> a b d
160
317
318+#### `ap`
319+
161 ap :: forall m a b. (Monad m) => m (a -> b) -> m a -> m b
320 ap :: forall m a b. (Monad m) => m (a -> b) -> m a -> m b
162
321
322+#### `asTypeOf`
323+
324+This function returns its first argument, and can be used to assert type equalities.
325+This can be useful when types are otherwise ambiguous.
326+
327+E.g.
328+
329+ main = print $ [] `asTypeOf` [0]
330+
331+If instead, we had written `main = print []`, the type of the argument `[]` would have
332+been ambiguous, resulting in a compile-time error.
333+
163 asTypeOf :: forall a. a -> a -> a
334 asTypeOf :: forall a. a -> a -> a
164
335
336+#### `cons`
337+
165 cons :: forall a. a -> [a] -> [a]
338 cons :: forall a. a -> [a] -> [a]
166
339
340+#### `const`
341+
342+Returns its first argument and ignores its second.
343+
167 const :: forall a b. a -> b -> a
344 const :: forall a b. a -> b -> a
168
345
346+#### `flip`
347+
348+Flips the order of the arguments to a function of two arguments.
349+
169 flip :: forall a b c. (a -> b -> c) -> b -> a -> c
350 flip :: forall a b c. (a -> b -> c) -> b -> a -> c
170
351
352+#### `liftA1`
353+
171 liftA1 :: forall f a b. (Applicative f) => (a -> b) -> f a -> f b
354 liftA1 :: forall f a b. (Applicative f) => (a -> b) -> f a -> f b
172
355
356+#### `liftM1`
357+
173 liftM1 :: forall m a b. (Monad m) => (a -> b) -> m a -> m b
358 liftM1 :: forall m a b. (Monad m) => (a -> b) -> m a -> m b
174
359
360+#### `negate`
361+
362+ negate :: forall a. (Ring a) => a -> a
363+
364+#### `otherwise`
365+
366+An alias for `true`, which can be useful in guard clauses:
367+
368+E.g.
369+
370+ max x y | x >= y = x
371+ | otherwise = y
372+
175 otherwise :: Boolean
373 otherwise :: Boolean
176
374
375+#### `refEq`
376+
177 refEq :: forall a. a -> a -> Boolean
377 refEq :: forall a. a -> a -> Boolean
178
378
379+#### `refIneq`
380+
179 refIneq :: forall a. a -> a -> Boolean
381 refIneq :: forall a. a -> a -> Boolean
180
382
383+#### `return`
384+
181 return :: forall m a. (Monad m) => a -> m a
385 return :: forall m a. (Monad m) => a -> m a
182
386
387+#### `unit`
388+
183 unit :: Unit
389 unit :: Unit
184
390
391+#### `void`
392+
185 void :: forall f a. (Functor f) => f a -> f Unit
393 void :: forall f a. (Functor f) => f a -> f Unit
186
394
187
395
@@ -189,102 +397,152 @@
189
397
190### Types
398### Types
191
399
400+#### `Fn0`
401+
192 data Fn0 :: * -> *
402 data Fn0 :: * -> *
193
403
404+#### `Fn1`
405+
194 data Fn1 :: * -> * -> *
406 data Fn1 :: * -> * -> *
195
407
408+#### `Fn10`
409+
196 data Fn10 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *
410 data Fn10 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *
197
411
412+#### `Fn2`
413+
198 data Fn2 :: * -> * -> * -> *
414 data Fn2 :: * -> * -> * -> *
199
415
416+#### `Fn3`
417+
200 data Fn3 :: * -> * -> * -> * -> *
418 data Fn3 :: * -> * -> * -> * -> *
201
419
420+#### `Fn4`
421+
202 data Fn4 :: * -> * -> * -> * -> * -> *
422 data Fn4 :: * -> * -> * -> * -> * -> *
203
423
424+#### `Fn5`
425+
204 data Fn5 :: * -> * -> * -> * -> * -> * -> *
426 data Fn5 :: * -> * -> * -> * -> * -> * -> *
205
427
428+#### `Fn6`
429+
206 data Fn6 :: * -> * -> * -> * -> * -> * -> * -> *
430 data Fn6 :: * -> * -> * -> * -> * -> * -> * -> *
207
431
432+#### `Fn7`
433+
208 data Fn7 :: * -> * -> * -> * -> * -> * -> * -> * -> *
434 data Fn7 :: * -> * -> * -> * -> * -> * -> * -> * -> *
209
435
436+#### `Fn8`
437+
210 data Fn8 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> *
438 data Fn8 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> *
211
439
440+#### `Fn9`
441+
212 data Fn9 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *
442 data Fn9 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *
213
443
214
444
215### Values
445### Values
216
446
447+#### `mkFn0`
448+
217 mkFn0 :: forall a. (Unit -> a) -> Fn0 a
449 mkFn0 :: forall a. (Unit -> a) -> Fn0 a
218
450
451+#### `mkFn1`
452+
219 mkFn1 :: forall a b. (a -> b) -> Fn1 a b
453 mkFn1 :: forall a b. (a -> b) -> Fn1 a b
220
454
455+#### `mkFn10`
456+
221 mkFn10 :: forall a b c d e f g h i j k. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> Fn10 a b c d e f g h i j k
457 mkFn10 :: forall a b c d e f g h i j k. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> Fn10 a b c d e f g h i j k
222
458
459+#### `mkFn2`
460+
223 mkFn2 :: forall a b c. (a -> b -> c) -> Fn2 a b c
461 mkFn2 :: forall a b c. (a -> b -> c) -> Fn2 a b c
224
462
463+#### `mkFn3`
464+
225 mkFn3 :: forall a b c d. (a -> b -> c -> d) -> Fn3 a b c d
465 mkFn3 :: forall a b c d. (a -> b -> c -> d) -> Fn3 a b c d
226
466
467+#### `mkFn4`
468+
227 mkFn4 :: forall a b c d e. (a -> b -> c -> d -> e) -> Fn4 a b c d e
469 mkFn4 :: forall a b c d e. (a -> b -> c -> d -> e) -> Fn4 a b c d e
228
470
471+#### `mkFn5`
472+
229 mkFn5 :: forall a b c d e f. (a -> b -> c -> d -> e -> f) -> Fn5 a b c d e f
473 mkFn5 :: forall a b c d e f. (a -> b -> c -> d -> e -> f) -> Fn5 a b c d e f
230
474
475+#### `mkFn6`
476+
231 mkFn6 :: forall a b c d e f g. (a -> b -> c -> d -> e -> f -> g) -> Fn6 a b c d e f g
477 mkFn6 :: forall a b c d e f g. (a -> b -> c -> d -> e -> f -> g) -> Fn6 a b c d e f g
232
478
479+#### `mkFn7`
480+
233 mkFn7 :: forall a b c d e f g h. (a -> b -> c -> d -> e -> f -> g -> h) -> Fn7 a b c d e f g h
481 mkFn7 :: forall a b c d e f g h. (a -> b -> c -> d -> e -> f -> g -> h) -> Fn7 a b c d e f g h
234
482
483+#### `mkFn8`
484+
235 mkFn8 :: forall a b c d e f g h i. (a -> b -> c -> d -> e -> f -> g -> h -> i) -> Fn8 a b c d e f g h i
485 mkFn8 :: forall a b c d e f g h i. (a -> b -> c -> d -> e -> f -> g -> h -> i) -> Fn8 a b c d e f g h i
236
486
487+#### `mkFn9`
488+
237 mkFn9 :: forall a b c d e f g h i j. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> Fn9 a b c d e f g h i j
489 mkFn9 :: forall a b c d e f g h i j. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> Fn9 a b c d e f g h i j
238
490
491+#### `on`
492+
239 on :: forall a b c. (b -> b -> c) -> (a -> b) -> a -> a -> c
493 on :: forall a b c. (b -> b -> c) -> (a -> b) -> a -> a -> c
240
494
241− runFn0 :: forall a. Fn0 a -> a
495+#### `runFn0`
242
496
243− runFn1 :: forall a b. Fn1 a b -> a -> b
497+ runFn0 :: forall a. Fn0 a -> a
244
498
245− runFn10 :: forall a b c d e f g h i j k. Fn10 a b c d e f g h i j k -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k
499+#### `runFn1`
246
500
247− runFn2 :: forall a b c. Fn2 a b c -> a -> b -> c
501+ runFn1 :: forall a b. Fn1 a b -> a -> b
248
502
249− runFn3 :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d
503+#### `runFn10`
250
504
251− runFn4 :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e
505+ runFn10 :: forall a b c d e f g h i j k. Fn10 a b c d e f g h i j k -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k
252
506
253− runFn5 :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f
507+#### `runFn2`
254
508
255− runFn6 :: forall a b c d e f g. Fn6 a b c d e f g -> a -> b -> c -> d -> e -> f -> g
509+ runFn2 :: forall a b c. Fn2 a b c -> a -> b -> c
256
510
257− runFn7 :: forall a b c d e f g h. Fn7 a b c d e f g h -> a -> b -> c -> d -> e -> f -> g -> h
511+#### `runFn3`
258
512
259− runFn8 :: forall a b c d e f g h i. Fn8 a b c d e f g h i -> a -> b -> c -> d -> e -> f -> g -> h -> i
513+ runFn3 :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d
260
514
261− runFn9 :: forall a b c d e f g h i j. Fn9 a b c d e f g h i j -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j
515+#### `runFn4`
262
516
517+ runFn4 :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e
263
518
264−## Module Data.Eq
519+#### `runFn5`
265
520
266−### Types
521+ runFn5 :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f
267
522
268− newtype Ref a where
523+#### `runFn6`
269− Ref :: a -> Ref a
270
524
525+ runFn6 :: forall a b c d e f g. Fn6 a b c d e f g -> a -> b -> c -> d -> e -> f -> g
271
526
272−### Type Class Instances
527+#### `runFn7`
273
528
274− instance eqRef :: Eq (Ref a)
529+ runFn7 :: forall a b c d e f g h. Fn7 a b c d e f g h -> a -> b -> c -> d -> e -> f -> g -> h
275
530
276− instance functorRef :: Functor Ref
531+#### `runFn8`
277
532
533+ runFn8 :: forall a b c d e f g h i. Fn8 a b c d e f g h i -> a -> b -> c -> d -> e -> f -> g -> h -> i
278
534
279−### Values
535+#### `runFn9`
280
536
281− liftRef :: forall a b. (a -> a -> b) -> Ref a -> Ref a -> b
537+ runFn9 :: forall a b c d e f g h i j. Fn9 a b c d e f g h i j -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j
282
538
283
539
284## Module Prelude.Unsafe
540## Module Prelude.Unsafe
285
541
286### Values
542### Values
287
543
544+#### `unsafeIndex`
545+
288 unsafeIndex :: forall a. [a] -> Number -> a
546 unsafeIndex :: forall a. [a] -> Number -> a
289
547
290
548
@@ -292,38 +550,66 @@
292
550
293### Types
551### Types
294
552
553+#### `Eff`
554+
295 data Eff :: # ! -> * -> *
555 data Eff :: # ! -> * -> *
296
556
557+#### `Pure`
558+
297 type Pure a = forall e. Eff e a
559 type Pure a = forall e. Eff e a
298
560
299
561
300### Type Class Instances
562### Type Class Instances
301
563
564+#### `applicativeEff`
565+
302 instance applicativeEff :: Applicative (Eff e)
566 instance applicativeEff :: Applicative (Eff e)
303
567
568+#### `applyEff`
569+
304 instance applyEff :: Apply (Eff e)
570 instance applyEff :: Apply (Eff e)
305
571
572+#### `bindEff`
573+
306 instance bindEff :: Bind (Eff e)
574 instance bindEff :: Bind (Eff e)
307
575
576+#### `functorEff`
577+
308 instance functorEff :: Functor (Eff e)
578 instance functorEff :: Functor (Eff e)
309
579
580+#### `monadEff`
581+
310 instance monadEff :: Monad (Eff e)
582 instance monadEff :: Monad (Eff e)
311
583
312
584
313### Values
585### Values
314
586
587+#### `bindE`
588+
315 bindE :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
589 bindE :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
316
590
591+#### `forE`
592+
317 forE :: forall e. Number -> Number -> (Number -> Eff e Unit) -> Eff e Unit
593 forE :: forall e. Number -> Number -> (Number -> Eff e Unit) -> Eff e Unit
318
594
595+#### `foreachE`
596+
319 foreachE :: forall e a. [a] -> (a -> Eff e Unit) -> Eff e Unit
597 foreachE :: forall e a. [a] -> (a -> Eff e Unit) -> Eff e Unit
320
598
599+#### `returnE`
600+
321 returnE :: forall e a. a -> Eff e a
601 returnE :: forall e a. a -> Eff e a
322
602
603+#### `runPure`
604+
323 runPure :: forall a. Pure a -> a
605 runPure :: forall a. Pure a -> a
324
606
607+#### `untilE`
608+
325 untilE :: forall e. Eff e Boolean -> Eff e Unit
609 untilE :: forall e. Eff e Boolean -> Eff e Unit
326
610
611+#### `whileE`
612+
327 whileE :: forall e a. Eff e Boolean -> Eff e a -> Eff e Unit
613 whileE :: forall e a. Eff e Boolean -> Eff e a -> Eff e Unit
328
614
329
615
@@ -331,6 +617,8 @@
331
617
332### Values
618### Values
333
619
620+#### `unsafeInterleaveEff`
621+
334 unsafeInterleaveEff :: forall eff1 eff2 a. Eff eff1 a -> Eff eff2 a
622 unsafeInterleaveEff :: forall eff1 eff2 a. Eff eff1 a -> Eff eff2 a
335
623
336
624
@@ -338,13 +626,19 @@
338
626
339### Types
627### Types
340
628
629+#### `Trace`
630+
341 data Trace :: !
631 data Trace :: !
342
632
343
633
344### Values
634### Values
345
635
636+#### `print`
637+
346 print :: forall a r. (Show a) => a -> Eff (trace :: Trace | r) Unit
638 print :: forall a r. (Show a) => a -> Eff (trace :: Trace | r) Unit
347
639
640+#### `trace`
641+
348 trace :: forall r. String -> Eff (trace :: Trace | r) Unit
642 trace :: forall r. String -> Eff (trace :: Trace | r) Unit
349
643
350
644
@@ -352,23 +646,39 @@
352
646
353### Types
647### Types
354
648
649+#### `ST`
650+
355 data ST :: * -> !
651 data ST :: * -> !
356
652
653+#### `STRef`
654+
357 data STRef :: * -> * -> *
655 data STRef :: * -> * -> *
358
656
359
657
360### Values
658### Values
361
659
660+#### `modifySTRef`
661+
362 modifySTRef :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) a
662 modifySTRef :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) a
363
663
664+#### `newSTRef`
665+
364 newSTRef :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
666 newSTRef :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
365
667
668+#### `pureST`
669+
366 pureST :: forall a. (forall h r. Eff (st :: ST h | r) a) -> a
670 pureST :: forall a. (forall h r. Eff (st :: ST h | r) a) -> a
367
671
672+#### `readSTRef`
673+
368 readSTRef :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
674 readSTRef :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
369
675
676+#### `runST`
677+
370 runST :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
678 runST :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
371
679
680+#### `writeSTRef`
681+
372 writeSTRef :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) a
682 writeSTRef :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) a
373
683
374
684
prelude/images/Prelude.png

Binary file not shown.

prelude/prelude.purs+655−470
@@ -13,8 +13,13 @@ module Prelude
13 , Applicative, pure, liftA1
13 , Applicative, pure, liftA1
14 , Bind, (>>=)
14 , Bind, (>>=)
15 , Monad, return, liftM1, ap
15 , Monad, return, liftM1, ap
16− , Num, (+), (-), (*), (/), (%)
16+ , Semiring, (+), zero, (*), one
17+ , ModuloSemiring, (/), mod
18+ , Ring, (-)
19+ , (%)
17 , negate
20 , negate
21+ , DivisionRing
22+ , Num
18 , Eq, (==), (/=), refEq, refIneq
23 , Eq, (==), (/=), refEq, refIneq
19 , Ord, Ordering(..), compare, (<), (>), (<=), (>=)
24 , Ord, Ordering(..), compare, (<), (>), (<=), (>=)
20 , Bits, (.&.), (.|.), (.^.), shl, shr, zshr, complement
25 , Bits, (.&.), (.|.), (.^.), shl, shr, zshr, complement
@@ -24,15 +29,32 @@ module Prelude
24 , Unit(..), unit
29 , Unit(..), unit
25 ) where
30 ) where
26
31
32+ -- | An alias for `true`, which can be useful in guard clauses:
33+ -- |
34+ -- | E.g.
35+ -- |
36+ -- | max x y | x >= y = x
37+ -- | | otherwise = y
27 otherwise :: Boolean
38 otherwise :: Boolean
28 otherwise = true
39 otherwise = true
29
40
41+ -- | Flips the order of the arguments to a function of two arguments.
30 flip :: forall a b c. (a -> b -> c) -> b -> a -> c
42 flip :: forall a b c. (a -> b -> c) -> b -> a -> c
31 flip f b a = f a b
43 flip f b a = f a b
32
44
45+ -- | Returns its first argument and ignores its second.
33 const :: forall a b. a -> b -> a
46 const :: forall a b. a -> b -> a
34 const a _ = a
47 const a _ = a
35
48
49+ -- | This function returns its first argument, and can be used to assert type equalities.
50+ -- | This can be useful when types are otherwise ambiguous.
51+ -- |
52+ -- | E.g.
53+ -- |
54+ -- | main = print $ [] `asTypeOf` [0]
55+ -- |
56+ -- | If instead, we had written `main = print []`, the type of the argument `[]` would have
57+ -- | been ambiguous, resulting in a compile-time error.
36 asTypeOf :: forall a. a -> a -> a
58 asTypeOf :: forall a. a -> a -> a
37 asTypeOf x _ = x
59 asTypeOf x _ = x
38
60
@@ -69,19 +91,23 @@ module Prelude
69 (:) = cons
91 (:) = cons
70
92
71 foreign import cons
93 foreign import cons
94+ """
72− "function cons(e) {\
95+ function cons(e) {
73− \ return function(l) {\
96+ return function(l) {
74− \ return [e].concat(l);\
97+ return [e].concat(l);
75− \ };\
98+ };
99+ }
76− \}" :: forall a. a -> [a] -> [a]
100+ """ :: forall a. a -> [a] -> [a]
77
101
78 class Show a where
102 class Show a where
79 show :: a -> String
103 show :: a -> String
80
104
81 foreign import showStringImpl
105 foreign import showStringImpl
106+ """
82− "function showStringImpl(s) {\
107+ function showStringImpl(s) {
83− \ return JSON.stringify(s);\
108+ return JSON.stringify(s);
109+ }
84− \}" :: String -> String
110+ """ :: String -> String
85
111
86 instance showUnit :: Show Unit where
112 instance showUnit :: Show Unit where
87 show (Unit {}) = "Unit {}"
113 show (Unit {}) = "Unit {}"
@@ -93,23 +119,28 @@ module Prelude
93 show true = "true"
119 show true = "true"
94 show false = "false"
120 show false = "false"
95
121
96− foreign import showNumberImpl "function showNumberImpl(n) {\
122+ foreign import showNumberImpl
123+ """
124+ function showNumberImpl(n) {
97− \ return n.toString();\
125+ return n.toString();
126+ }
98− \}" :: Number -> String
127+ """ :: Number -> String
99
128
100 instance showNumber :: Show Number where
129 instance showNumber :: Show Number where
101 show = showNumberImpl
130 show = showNumberImpl
102
131
103 foreign import showArrayImpl
132 foreign import showArrayImpl
133+ """
104− "function showArrayImpl(f) {\
134+ function showArrayImpl(f) {
105− \ return function(xs) {\
135+ return function(xs) {
106− \ var ss = [];\
136+ var ss = [];
107− \ for (var i = 0, l = xs.length; i < l; i++) {\
137+ for (var i = 0, l = xs.length; i < l; i++) {
108− \ ss[i] = f(xs[i]);\
138+ ss[i] = f(xs[i]);
109− \ }\
139+ }
110− \ return '[' + ss.join(',') + ']';\
140+ return '[' + ss.join(',') + ']';
111− \ };\
141+ };
142+ }
112− \}" :: forall a. (a -> String) -> [a] -> String
143+ """ :: forall a. (a -> String) -> [a] -> String
113
144
114 instance showArray :: (Show a) => Show [a] where
145 instance showArray :: (Show a) => Show [a] where
115 show = showArrayImpl show
146 show = showArrayImpl show
@@ -179,55 +210,96 @@ module Prelude
179 infixl 6 -
210 infixl 6 -
180 infixl 6 +
211 infixl 6 +
181
212
213+ -- | Addition and multiplication
182− class Num a where
214+ class Semiring a where
183− (+) :: a -> a -> a
215+ (+) :: a -> a -> a
216+ zero :: a
184− (-) :: a -> a -> a
217+ (*) :: a -> a -> a
185− (*) :: a -> a -> a
218+ one :: a
219+
220+ -- | Semiring with modulo operation and division where
221+ -- | ```a / b * b + (a `mod` b) = a```
222+ class (Semiring a) <= ModuloSemiring a where
186 (/) :: a -> a -> a
223 (/) :: a -> a -> a
224+ mod :: a -> a -> a
225+
226+ -- | Addition, multiplication, and subtraction
227+ class (Semiring a) <= Ring a where
187− (%) :: a -> a -> a
228+ (-) :: a -> a -> a
229+
188− negate :: a -> a
230+ negate :: forall a. (Ring a) => a -> a
189−
231+ negate a = zero - a
232+
233+ -- | Ring where every nonzero element has a multiplicative inverse (possibly
234+ -- | a non-commutative field) so that ```a `mod` b = zero```
235+ class (Ring a, ModuloSemiring a) <= DivisionRing a
236+
237+ -- | A commutative field
238+ class (DivisionRing a) <= Num a
239+
190− foreign import numAdd "function numAdd(n1) {\
240+ foreign import numAdd
241+ """
242+ function numAdd(n1) {
191− \ return function(n2) {\
243+ return function(n2) {
192− \ return n1 + n2;\
244+ return n1 + n2;
193− \ };\
245+ };
246+ }
194− \}" :: Number -> Number -> Number
247+ """ :: Number -> Number -> Number
195−
248+
196− foreign import numSub "function numSub(n1) {\
249+ foreign import numSub
250+ """
251+ function numSub(n1) {
197− \ return function(n2) {\
252+ return function(n2) {
198− \ return n1 - n2;\
253+ return n1 - n2;
199− \ };\
254+ };
255+ }
200− \}" :: Number -> Number -> Number
256+ """ :: Number -> Number -> Number
201−
257+
202− foreign import numMul "function numMul(n1) {\
258+ foreign import numMul
259+ """
260+ function numMul(n1) {
203− \ return function(n2) {\
261+ return function(n2) {
204− \ return n1 * n2;\
262+ return n1 * n2;
205− \ };\
263+ };
264+ }
206− \}" :: Number -> Number -> Number
265+ """ :: Number -> Number -> Number
207−
266+
208− foreign import numDiv "function numDiv(n1) {\
267+ foreign import numDiv
268+ """
269+ function numDiv(n1) {
209− \ return function(n2) {\
270+ return function(n2) {
210− \ return n1 / n2;\
271+ return n1 / n2;
211− \ };\
272+ };
273+ }
212− \}" :: Number -> Number -> Number
274+ """ :: Number -> Number -> Number
213−
275+
214− foreign import numMod "function numMod(n1) {\
276+ foreign import numMod
277+ """
278+ function numMod(n1) {
215− \ return function(n2) {\
279+ return function(n2) {
216− \ return n1 % n2;\
280+ return n1 % n2;
217− \ };\
281+ };
282+ }
218− \}" :: Number -> Number -> Number
283+ """ :: Number -> Number -> Number
219−
284+
220− foreign import numNegate "function numNegate(n) {\
285+ (%) = numMod
221− \ return -n;\
286+
222− \}" :: Number -> Number
223−
224− instance numNumber :: Num Number where
287+ instance semiringNumber :: Semiring Number where
225 (+) = numAdd
288 (+) = numAdd
226− (-) = numSub
289+ zero = 0
227 (*) = numMul
290 (*) = numMul
291+ one = 1
292+
293+ instance ringNumber :: Ring Number where
294+ (-) = numSub
295+
296+ instance moduloSemiringNumber :: ModuloSemiring Number where
228 (/) = numDiv
297 (/) = numDiv
229− (%) = numMod
298+ mod _ _ = 0
230− negate = numNegate
299+
300+ instance divisionRingNumber :: DivisionRing Number
301+
302+ instance numNumber :: Num Number
231
303
232 newtype Unit = Unit {}
304 newtype Unit = Unit {}
233
305
@@ -242,18 +314,22 @@ module Prelude
242 (/=) :: a -> a -> Boolean
314 (/=) :: a -> a -> Boolean
243
315
244 foreign import refEq
316 foreign import refEq
317+ """
245− "function refEq(r1) {\
318+ function refEq(r1) {
246− \ return function(r2) {\
319+ return function(r2) {
247− \ return r1 === r2;\
320+ return r1 === r2;
248− \ };\
321+ };
322+ }
249− \}" :: forall a. a -> a -> Boolean
323+ """ :: forall a. a -> a -> Boolean
250
324
251 foreign import refIneq
325 foreign import refIneq
326+ """
252− "function refIneq(r1) {\
327+ function refIneq(r1) {
253− \ return function(r2) {\
328+ return function(r2) {
254− \ return r1 !== r2;\
329+ return r1 !== r2;
255− \ };\
330+ };
331+ }
256− \}" :: forall a. a -> a -> Boolean
332+ """ :: forall a. a -> a -> Boolean
257
333
258 instance eqUnit :: Eq Unit where
334 instance eqUnit :: Eq Unit where
259 (==) (Unit {}) (Unit {}) = true
335 (==) (Unit {}) (Unit {}) = true
@@ -272,17 +348,19 @@ module Prelude
272 (/=) = refIneq
348 (/=) = refIneq
273
349
274 foreign import eqArrayImpl
350 foreign import eqArrayImpl
351+ """
275− "function eqArrayImpl(f) {\
352+ function eqArrayImpl(f) {
276− \ return function(xs) {\
353+ return function(xs) {
277− \ return function(ys) {\
354+ return function(ys) {
278− \ if (xs.length !== ys.length) return false;\
355+ if (xs.length !== ys.length) return false;
279− \ for (var i = 0; i < xs.length; i++) {\
356+ for (var i = 0; i < xs.length; i++) {
280− \ if (!f(xs[i])(ys[i])) return false;\
357+ if (!f(xs[i])(ys[i])) return false;
281− \ }\
358+ }
282− \ return true;\
359+ return true;
283− \ };\
360+ };
284− \ };\
361+ };
362+ }
285− \}" :: forall a. (a -> a -> Boolean) -> [a] -> [a] -> Boolean
363+ """ :: forall a. (a -> a -> Boolean) -> [a] -> [a] -> Boolean
286
364
287 instance eqArray :: (Eq a) => Eq [a] where
365 instance eqArray :: (Eq a) => Eq [a] where
288 (==) xs ys = eqArrayImpl (==) xs ys
366 (==) xs ys = eqArrayImpl (==) xs ys
@@ -334,17 +412,19 @@ module Prelude
334 _ -> true
412 _ -> true
335
413
336 foreign import unsafeCompareImpl
414 foreign import unsafeCompareImpl
415+ """
337− "function unsafeCompareImpl(lt) {\
416+ function unsafeCompareImpl(lt) {
338− \ return function(eq) {\
417+ return function(eq) {
339− \ return function(gt) {\
418+ return function(gt) {
340− \ return function(x) {\
419+ return function(x) {
341− \ return function(y) {\
420+ return function(y) {
342− \ return x < y ? lt : x > y ? gt : eq;\
421+ return x < y ? lt : x > y ? gt : eq;
343− \ };\
422+ };
344− \ };\
423+ };
345− \ };\
424+ };
346− \ };\
425+ };
426+ }
347− \}" :: forall a. Ordering -> Ordering -> Ordering -> a -> a -> Ordering
427+ """ :: forall a. Ordering -> Ordering -> Ordering -> a -> a -> Ordering
348
428
349 unsafeCompare :: forall a. a -> a -> Ordering
429 unsafeCompare :: forall a. a -> a -> Ordering
350 unsafeCompare = unsafeCompareImpl LT EQ GT
430 unsafeCompare = unsafeCompareImpl LT EQ GT
@@ -385,45 +465,66 @@ module Prelude
385 zshr :: b -> Number -> b
465 zshr :: b -> Number -> b
386 complement :: b -> b
466 complement :: b -> b
387
467
388− foreign import numShl "function numShl(n1) {\
468+ foreign import numShl
469+ """
470+ function numShl(n1) {
389− \ return function(n2) {\
471+ return function(n2) {
390− \ return n1 << n2;\
472+ return n1 << n2;
391− \ };\
473+ };
474+ }
392− \}" :: Number -> Number -> Number
475+ """ :: Number -> Number -> Number
393−
476+
394− foreign import numShr "function numShr(n1) {\
477+ foreign import numShr
478+ """
479+ function numShr(n1) {
395− \ return function(n2) {\
480+ return function(n2) {
396− \ return n1 >> n2;\
481+ return n1 >> n2;
397− \ };\
482+ };
483+ }
398− \}" :: Number -> Number -> Number
484+ """ :: Number -> Number -> Number
399−
485+
400− foreign import numZshr "function numZshr(n1) {\
486+ foreign import numZshr
487+ """
488+ function numZshr(n1) {
401− \ return function(n2) {\
489+ return function(n2) {
402− \ return n1 >>> n2;\
490+ return n1 >>> n2;
403− \ };\
491+ };
492+ }
404− \}" :: Number -> Number -> Number
493+ """ :: Number -> Number -> Number
405−
494+
406− foreign import numAnd "function numAnd(n1) {\
495+ foreign import numAnd
496+ """
497+ function numAnd(n1) {
407− \ return function(n2) {\
498+ return function(n2) {
408− \ return n1 & n2;\
499+ return n1 & n2;
409− \ };\
500+ };
501+ }
410− \}" :: Number -> Number -> Number
502+ """ :: Number -> Number -> Number
411−
503+
412− foreign import numOr "function numOr(n1) {\
504+ foreign import numOr
505+ """
506+ function numOr(n1) {
413− \ return function(n2) {\
507+ return function(n2) {
414− \ return n1 | n2;\
508+ return n1 | n2;
415− \ };\
509+ };
510+ }
416− \}" :: Number -> Number -> Number
511+ """ :: Number -> Number -> Number
417−
512+
418− foreign import numXor "function numXor(n1) {\
513+ foreign import numXor
514+ """
515+ function numXor(n1) {
419− \ return function(n2) {\
516+ return function(n2) {
420− \ return n1 ^ n2;\
517+ return n1 ^ n2;
421− \ };\
518+ };
519+ }
422− \}" :: Number -> Number -> Number
520+ """ :: Number -> Number -> Number
423−
521+
424− foreign import numComplement "function numComplement(n) {\
522+ foreign import numComplement
523+ """
524+ function numComplement(n) {
425− \ return ~n;\
525+ return ~n;
526+ }
426− \}" :: Number -> Number
527+ """ :: Number -> Number
427
528
428 instance bitsNumber :: Bits Number where
529 instance bitsNumber :: Bits Number where
429 (.&.) = numAnd
530 (.&.) = numAnd
@@ -442,21 +543,30 @@ module Prelude
442 (||) :: b -> b -> b
543 (||) :: b -> b -> b
443 not :: b -> b
544 not :: b -> b
444
545
445− foreign import boolAnd "function boolAnd(b1) {\
546+ foreign import boolAnd
547+ """
548+ function boolAnd(b1) {
446− \ return function(b2) {\
549+ return function(b2) {
447− \ return b1 && b2;\
550+ return b1 && b2;
448− \ };\
551+ };
552+ }
449− \}" :: Boolean -> Boolean -> Boolean
553+ """ :: Boolean -> Boolean -> Boolean
450−
554+
451− foreign import boolOr "function boolOr(b1) {\
555+ foreign import boolOr
556+ """
557+ function boolOr(b1) {
452− \ return function(b2) {\
558+ return function(b2) {
453− \ return b1 || b2;\
559+ return b1 || b2;
454− \ };\
560+ };
561+ }
455− \}" :: Boolean -> Boolean -> Boolean
562+ """ :: Boolean -> Boolean -> Boolean
456−
563+
457− foreign import boolNot "function boolNot(b) {\
564+ foreign import boolNot
565+ """
566+ function boolNot(b) {
458− \ return !b;\
567+ return !b;
568+ }
459− \}" :: Boolean -> Boolean
569+ """ :: Boolean -> Boolean
460
570
461 instance boolLikeBoolean :: BoolLike Boolean where
571 instance boolLikeBoolean :: BoolLike Boolean where
462 (&&) = boolAnd
572 (&&) = boolAnd
@@ -469,11 +579,13 @@ module Prelude
469 (<>) :: a -> a -> a
579 (<>) :: a -> a -> a
470
580
471 foreign import concatString
581 foreign import concatString
582+ """
472− "function concatString(s1) {\
583+ function concatString(s1) {
473− \ return function(s2) {\
584+ return function(s2) {
474− \ return s1 + s2;\
585+ return s1 + s2;
475− \ };\
586+ };
587+ }
476− \}" :: String -> String -> String
588+ """ :: String -> String -> String
477
589
478 instance semigroupUnit :: Semigroup Unit where
590 instance semigroupUnit :: Semigroup Unit where
479 (<>) (Unit {}) (Unit {}) = Unit {}
591 (<>) (Unit {}) (Unit {}) = Unit {}
@@ -507,293 +619,334 @@ module Data.Function where
507 foreign import data Fn10 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *
619 foreign import data Fn10 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *
508
620
509 foreign import mkFn0
621 foreign import mkFn0
622+ """
510− "function mkFn0(fn) {\
623+ function mkFn0(fn) {
511− \ return function() {\
624+ return function() {
512− \ return fn({});\
625+ return fn({});
513− \ };\
626+ };
627+ }
514− \}" :: forall a. (Unit -> a) -> Fn0 a
628+ """ :: forall a. (Unit -> a) -> Fn0 a
515
629
516 foreign import mkFn1
630 foreign import mkFn1
631+ """
517− "function mkFn1(fn) {\
632+ function mkFn1(fn) {
518− \ return function(a) {\
633+ return function(a) {
519− \ return fn(a);\
634+ return fn(a);
520− \ };\
635+ };
636+ }
521− \}" :: forall a b. (a -> b) -> Fn1 a b
637+ """ :: forall a b. (a -> b) -> Fn1 a b
522
638
523 foreign import mkFn2
639 foreign import mkFn2
640+ """
524− "function mkFn2(fn) {\
641+ function mkFn2(fn) {
525− \ return function(a, b) {\
642+ return function(a, b) {
526− \ return fn(a)(b);\
643+ return fn(a)(b);
527− \ };\
644+ };
645+ }
528− \}" :: forall a b c. (a -> b -> c) -> Fn2 a b c
646+ """ :: forall a b c. (a -> b -> c) -> Fn2 a b c
529
647
530 foreign import mkFn3
648 foreign import mkFn3
649+ """
531− "function mkFn3(fn) {\
650+ function mkFn3(fn) {
532− \ return function(a, b, c) {\
651+ return function(a, b, c) {
533− \ return fn(a)(b)(c);\
652+ return fn(a)(b)(c);
534− \ };\
653+ };
654+ }
535− \}" :: forall a b c d. (a -> b -> c -> d) -> Fn3 a b c d
655+ """ :: forall a b c d. (a -> b -> c -> d) -> Fn3 a b c d
536
656
537 foreign import mkFn4
657 foreign import mkFn4
658+ """
538− "function mkFn4(fn) {\
659+ function mkFn4(fn) {
539− \ return function(a, b, c, d) {\
660+ return function(a, b, c, d) {
540− \ return fn(a)(b)(c)(d);\
661+ return fn(a)(b)(c)(d);
541− \ };\
662+ };
663+ }
542− \}" :: forall a b c d e. (a -> b -> c -> d -> e) -> Fn4 a b c d e
664+ """ :: forall a b c d e. (a -> b -> c -> d -> e) -> Fn4 a b c d e
543
665
544 foreign import mkFn5
666 foreign import mkFn5
667+ """
545− "function mkFn5(fn) {\
668+ function mkFn5(fn) {
546− \ return function(a, b, c, d, e) {\
669+ return function(a, b, c, d, e) {
547− \ return fn(a)(b)(c)(d)(e);\
670+ return fn(a)(b)(c)(d)(e);
548− \ };\
671+ };
672+ }
549− \}" :: forall a b c d e f. (a -> b -> c -> d -> e -> f) -> Fn5 a b c d e f
673+ """ :: forall a b c d e f. (a -> b -> c -> d -> e -> f) -> Fn5 a b c d e f
550
674
551 foreign import mkFn6
675 foreign import mkFn6
676+ """
552− "function mkFn6(fn) {\
677+ function mkFn6(fn) {
553− \ return function(a, b, c, d, e, f) {\
678+ return function(a, b, c, d, e, f) {
554− \ return fn(a)(b)(c)(d)(e)(f);\
679+ return fn(a)(b)(c)(d)(e)(f);
555− \ };\
680+ };
681+ }
556− \}" :: forall a b c d e f g. (a -> b -> c -> d -> e -> f -> g) -> Fn6 a b c d e f g
682+ """ :: forall a b c d e f g. (a -> b -> c -> d -> e -> f -> g) -> Fn6 a b c d e f g
557
683
558 foreign import mkFn7
684 foreign import mkFn7
685+ """
559− "function mkFn7(fn) {\
686+ function mkFn7(fn) {
560− \ return function(a, b, c, d, e, f, g) {\
687+ return function(a, b, c, d, e, f, g) {
561− \ return fn(a)(b)(c)(d)(e)(f)(g);\
688+ return fn(a)(b)(c)(d)(e)(f)(g);
562− \ };\
689+ };
690+ }
563− \}" :: forall a b c d e f g h. (a -> b -> c -> d -> e -> f -> g -> h) -> Fn7 a b c d e f g h
691+ """ :: forall a b c d e f g h. (a -> b -> c -> d -> e -> f -> g -> h) -> Fn7 a b c d e f g h
564
692
565 foreign import mkFn8
693 foreign import mkFn8
694+ """
566− "function mkFn8(fn) {\
695+ function mkFn8(fn) {
567− \ return function(a, b, c, d, e, f, g, h) {\
696+ return function(a, b, c, d, e, f, g, h) {
568− \ return fn(a)(b)(c)(d)(e)(f)(g)(h);\
697+ return fn(a)(b)(c)(d)(e)(f)(g)(h);
569− \ };\
698+ };
699+ }
570− \}" :: forall a b c d e f g h i. (a -> b -> c -> d -> e -> f -> g -> h -> i) -> Fn8 a b c d e f g h i
700+ """ :: forall a b c d e f g h i. (a -> b -> c -> d -> e -> f -> g -> h -> i) -> Fn8 a b c d e f g h i
571
701
572 foreign import mkFn9
702 foreign import mkFn9
703+ """
573− "function mkFn9(fn) {\
704+ function mkFn9(fn) {
574− \ return function(a, b, c, d, e, f, g, h, i) {\
705+ return function(a, b, c, d, e, f, g, h, i) {
575− \ return fn(a)(b)(c)(d)(e)(f)(g)(h)(i);\
706+ return fn(a)(b)(c)(d)(e)(f)(g)(h)(i);
576− \ };\
707+ };
708+ }
577− \}" :: forall a b c d e f g h i j. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> Fn9 a b c d e f g h i j
709+ """ :: forall a b c d e f g h i j. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> Fn9 a b c d e f g h i j
578
710
579 foreign import mkFn10
711 foreign import mkFn10
712+ """
580− "function mkFn10(fn) {\
713+ function mkFn10(fn) {
581− \ return function(a, b, c, d, e, f, g, h, i, j) {\
714+ return function(a, b, c, d, e, f, g, h, i, j) {
582− \ return fn(a)(b)(c)(d)(e)(f)(g)(h)(i)(j);\
715+ return fn(a)(b)(c)(d)(e)(f)(g)(h)(i)(j);
583− \ };\
716+ };
717+ }
584− \}" :: forall a b c d e f g h i j k. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> Fn10 a b c d e f g h i j k
718+ """ :: forall a b c d e f g h i j k. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> Fn10 a b c d e f g h i j k
585
719
586 foreign import runFn0
720 foreign import runFn0
721+ """
587− "function runFn0(fn) {\
722+ function runFn0(fn) {
588− \ return fn();\
723+ return fn();
724+ }
589− \}" :: forall a. Fn0 a -> a
725+ """ :: forall a. Fn0 a -> a
590
726
591 foreign import runFn1
727 foreign import runFn1
728+ """
592− "function runFn1(fn) {\
729+ function runFn1(fn) {
593− \ return function(a) {\
730+ return function(a) {
594− \ return fn(a);\
731+ return fn(a);
595− \ };\
732+ };
733+ }
596− \}" :: forall a b. Fn1 a b -> a -> b
734+ """ :: forall a b. Fn1 a b -> a -> b
597
735
598 foreign import runFn2
736 foreign import runFn2
737+ """
599− "function runFn2(fn) {\
738+ function runFn2(fn) {
600− \ return function(a) {\
739+ return function(a) {
601− \ return function(b) {\
740+ return function(b) {
602− \ return fn(a, b);\
741+ return fn(a, b);
603− \ };\
742+ };
604− \ };\
743+ };
744+ }
605− \}" :: forall a b c. Fn2 a b c -> a -> b -> c
745+ """ :: forall a b c. Fn2 a b c -> a -> b -> c
606
746
607 foreign import runFn3
747 foreign import runFn3
748+ """
608− "function runFn3(fn) {\
749+ function runFn3(fn) {
609− \ return function(a) {\
750+ return function(a) {
610− \ return function(b) {\
751+ return function(b) {
611− \ return function(c) {\
752+ return function(c) {
612− \ return fn(a, b, c);\
753+ return fn(a, b, c);
613− \ };\
754+ };
614− \ };\
755+ };
615− \ };\
756+ };
757+ }
616− \}" :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d
758+ """ :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d
617
759
618 foreign import runFn4
760 foreign import runFn4
761+ """
619− "function runFn4(fn) {\
762+ function runFn4(fn) {
620− \ return function(a) {\
763+ return function(a) {
621− \ return function(b) {\
764+ return function(b) {
622− \ return function(c) {\
765+ return function(c) {
623− \ return function(d) {\
766+ return function(d) {
624− \ return fn(a, b, c, d);\
767+ return fn(a, b, c, d);
625− \ };\
768+ };
626− \ };\
769+ };
627− \ };\
770+ };
628− \ };\
771+ };
772+ }
629− \}" :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e
773+ """ :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e
630
774
631 foreign import runFn5
775 foreign import runFn5
776+ """
632− "function runFn5(fn) {\
777+ function runFn5(fn) {
633− \ return function(a) {\
778+ return function(a) {
634− \ return function(b) {\
779+ return function(b) {
635− \ return function(c) {\
780+ return function(c) {
636− \ return function(d) {\
781+ return function(d) {
637− \ return function(e) {\
782+ return function(e) {
638− \ return fn(a, b, c, d, e);\
783+ return fn(a, b, c, d, e);
639− \ };\
784+ };
640− \ };\
785+ };
641− \ };\
786+ };
642− \ };\
787+ };
643− \ };\
788+ };
789+ }
644− \}" :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f
790+ """ :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f
645
791
646 foreign import runFn6
792 foreign import runFn6
793+ """
647− "function runFn6(fn) {\
794+ function runFn6(fn) {
648− \ return function(a) {\
795+ return function(a) {
649− \ return function(b) {\
796+ return function(b) {
650− \ return function(c) {\
797+ return function(c) {
651− \ return function(d) {\
798+ return function(d) {
652− \ return function(e) {\
799+ return function(e) {
653− \ return function(f) {\
800+ return function(f) {
654− \ return fn(a, b, c, d, e, f);\
801+ return fn(a, b, c, d, e, f);
655− \ };\
802+ };
656− \ };\
803+ };
657− \ };\
804+ };
658− \ };\
805+ };
659− \ };\
806+ };
660− \ };\
807+ };
808+ }
661− \}" :: forall a b c d e f g. Fn6 a b c d e f g -> a -> b -> c -> d -> e -> f -> g
809+ """ :: forall a b c d e f g. Fn6 a b c d e f g -> a -> b -> c -> d -> e -> f -> g
662
810
663 foreign import runFn7
811 foreign import runFn7
812+ """
664− "function runFn7(fn) {\
813+ function runFn7(fn) {
665− \ return function(a) {\
814+ return function(a) {
666− \ return function(b) {\
815+ return function(b) {
667− \ return function(c) {\
816+ return function(c) {
668− \ return function(d) {\
817+ return function(d) {
669− \ return function(e) {\
818+ return function(e) {
670− \ return function(f) {\
819+ return function(f) {
671− \ return function(g) {\
820+ return function(g) {
672− \ return fn(a, b, c, d, e, f, g);\
821+ return fn(a, b, c, d, e, f, g);
822+ };
823+ };
673− \ };\
824+ };
674− \ };\
825+ };
675− \ };\
826+ };
676− \ };\
827+ };
677− \ };\
828+ };
678− \ };\
829+ }
679− \ };\
680− \}" :: forall a b c d e f g h. Fn7 a b c d e f g h -> a -> b -> c -> d -> e -> f -> g -> h
830+ """ :: forall a b c d e f g h. Fn7 a b c d e f g h -> a -> b -> c -> d -> e -> f -> g -> h
681
831
682 foreign import runFn8
832 foreign import runFn8
833+ """
683− "function runFn8(fn) {\
834+ function runFn8(fn) {
684− \ return function(a) {\
835+ return function(a) {
685− \ return function(b) {\
836+ return function(b) {
686− \ return function(c) {\
837+ return function(c) {
687− \ return function(d) {\
838+ return function(d) {
688− \ return function(e) {\
839+ return function(e) {
689− \ return function(f) {\
840+ return function(f) {
690− \ return function(g) {\
841+ return function(g) {
691− \ return function(h) {\
842+ return function(h) {
692− \ return fn(a, b, c, d, e, f, g, h);\
843+ return fn(a, b, c, d, e, f, g, h);
844+ };
845+ };
693− \ };\
846+ };
694− \ };\
847+ };
695− \ };\
848+ };
696− \ };\
849+ };
697− \ };\
850+ };
698− \ };\
851+ };
699− \ };\
852+ }
700− \ };\
701− \}" :: forall a b c d e f g h i. Fn8 a b c d e f g h i -> a -> b -> c -> d -> e -> f -> g -> h -> i
853+ """ :: forall a b c d e f g h i. Fn8 a b c d e f g h i -> a -> b -> c -> d -> e -> f -> g -> h -> i
702
854
703 foreign import runFn9
855 foreign import runFn9
856+ """
704− "function runFn9(fn) {\
857+ function runFn9(fn) {
705− \ return function(a) {\
858+ return function(a) {
706− \ return function(b) {\
859+ return function(b) {
707− \ return function(c) {\
860+ return function(c) {
708− \ return function(d) {\
861+ return function(d) {
709− \ return function(e) {\
862+ return function(e) {
710− \ return function(f) {\
863+ return function(f) {
711− \ return function(g) {\
864+ return function(g) {
712− \ return function(h) {\
865+ return function(h) {
713− \ return function(i) {\
866+ return function(i) {
714− \ return fn(a, b, c, d, e, f, g, h, i);\
867+ return fn(a, b, c, d, e, f, g, h, i);
868+ };
869+ };
715− \ };\
870+ };
716− \ };\
871+ };
717− \ };\
872+ };
718− \ };\
873+ };
719− \ };\
874+ };
720− \ };\
875+ };
721− \ };\
876+ };
722− \ };\
877+ }
723− \ };\
724− \}" :: forall a b c d e f g h i j. Fn9 a b c d e f g h i j -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j
878+ """ :: forall a b c d e f g h i j. Fn9 a b c d e f g h i j -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j
725
879
726 foreign import runFn10
880 foreign import runFn10
881+ """
727− "function runFn10(fn) {\
882+ function runFn10(fn) {
728− \ return function(a) {\
883+ return function(a) {
729− \ return function(b) {\
884+ return function(b) {
730− \ return function(c) {\
885+ return function(c) {
731− \ return function(d) {\
886+ return function(d) {
732− \ return function(e) {\
887+ return function(e) {
733− \ return function(f) {\
888+ return function(f) {
734− \ return function(g) {\
889+ return function(g) {
735− \ return function(h) {\
890+ return function(h) {
736− \ return function(i) {\
891+ return function(i) {
737− \ return function(j) {\
892+ return function(j) {
738− \ return fn(a, b, c, d, e, f, g, h, i, j);\
893+ return fn(a, b, c, d, e, f, g, h, i, j);
894+ };
895+ };
739− \ };\
896+ };
740− \ };\
897+ };
741− \ };\
898+ };
742− \ };\
899+ };
743− \ };\
900+ };
744− \ };\
901+ };
745− \ };\
902+ };
746− \ };\
903+ };
747− \ };\
904+ }
748− \ };\
749− \}" :: forall a b c d e f g h i j k. Fn10 a b c d e f g h i j k -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k
905+ """ :: forall a b c d e f g h i j k. Fn10 a b c d e f g h i j k -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k
750−
751−module Data.Eq where
752−
753− newtype Ref a = Ref a
754−
755− liftRef :: forall a b. (a -> a -> b) -> Ref a -> Ref a -> b
756− liftRef f (Ref x) (Ref y) = f x y
757−
758− instance eqRef :: Eq (Ref a) where
759− (==) = liftRef refEq
760− (/=) = liftRef refIneq
761−
762− instance functorRef :: Functor Ref where
763− (<$>) f (Ref x) = Ref (f x)
764
906
765module Prelude.Unsafe where
907module Prelude.Unsafe where
766
908
767 foreign import unsafeIndex
909 foreign import unsafeIndex
910+ """
768− "function unsafeIndex(xs) {\
911+ function unsafeIndex(xs) {
769− \ return function(n) {\
912+ return function(n) {
770− \ return xs[n];\
913+ return xs[n];
771− \ };\
914+ };
915+ }
772− \}" :: forall a. [a] -> Number -> a
916+ """ :: forall a. [a] -> Number -> a
773
917
774module Control.Monad.Eff where
918module Control.Monad.Eff where
775
919
776 foreign import data Eff :: # ! -> * -> *
920 foreign import data Eff :: # ! -> * -> *
777
921
778− foreign import returnE "function returnE(a) {\
922+ foreign import returnE
923+ """
924+ function returnE(a) {
779− \ return function() {\
925+ return function() {
780− \ return a;\
926+ return a;
781− \ };\
927+ };
928+ }
782− \}" :: forall e a. a -> Eff e a
929+ """ :: forall e a. a -> Eff e a
783−
930+
784− foreign import bindE "function bindE(a) {\
931+ foreign import bindE
932+ """
933+ function bindE(a) {
785− \ return function(f) {\
934+ return function(f) {
786− \ return function() {\
935+ return function() {
787− \ return f(a())();\
936+ return f(a())();
788− \ };\
937+ };
789− \ };\
938+ };
939+ }
790− \}" :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
940+ """ :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
791
941
792 type Pure a = forall e. Eff e a
942 type Pure a = forall e. Eff e a
793
943
794− foreign import runPure "function runPure(f) {\
944+ foreign import runPure
945+ """
946+ function runPure(f) {
795− \ return f();\
947+ return f();
948+ }
796− \}" :: forall a. Pure a -> a
949+ """ :: forall a. Pure a -> a
797
950
798 instance functorEff :: Functor (Eff e) where
951 instance functorEff :: Functor (Eff e) where
799 (<$>) = liftA1
952 (<$>) = liftA1
@@ -809,55 +962,69 @@ module Control.Monad.Eff where
809
962
810 instance monadEff :: Monad (Eff e)
963 instance monadEff :: Monad (Eff e)
811
964
812− foreign import untilE "function untilE(f) {\
965+ foreign import untilE
966+ """
967+ function untilE(f) {
813− \ return function() {\
968+ return function() {
814− \ while (!f());\
969+ while (!f());
815− \ return {};\
970+ return {};
816− \ };\
971+ };
972+ }
817− \}" :: forall e. Eff e Boolean -> Eff e Unit
973+ """ :: forall e. Eff e Boolean -> Eff e Unit
818−
974+
819− foreign import whileE "function whileE(f) {\
975+ foreign import whileE
976+ """
977+ function whileE(f) {
820− \ return function(a) {\
978+ return function(a) {
821− \ return function() {\
979+ return function() {
822− \ while (f()) {\
980+ while (f()) {
823− \ a();\
981+ a();
824− \ }\
982+ }
825− \ return {};\
983+ return {};
826− \ };\
984+ };
827− \ };\
985+ };
986+ }
828− \}" :: forall e a. Eff e Boolean -> Eff e a -> Eff e Unit
987+ """ :: forall e a. Eff e Boolean -> Eff e a -> Eff e Unit
829−
988+
830− foreign import forE "function forE(lo) {\
989+ foreign import forE
990+ """
991+ function forE(lo) {
831− \ return function(hi) {\
992+ return function(hi) {
832− \ return function(f) {\
993+ return function(f) {
833− \ return function() {\
994+ return function() {
834− \ for (var i = lo; i < hi; i++) {\
995+ for (var i = lo; i < hi; i++) {
835− \ f(i)();\
996+ f(i)();
836− \ }\
997+ }
837− \ };\
998+ };
838− \ };\
999+ };
839− \ };\
1000+ };
1001+ }
840− \}" :: forall e. Number -> Number -> (Number -> Eff e Unit) -> Eff e Unit
1002+ """ :: forall e. Number -> Number -> (Number -> Eff e Unit) -> Eff e Unit
841−
1003+
842−
1004+
843− foreign import foreachE "function foreachE(as) {\
1005+ foreign import foreachE
1006+ """
1007+ function foreachE(as) {
844− \ return function(f) {\
1008+ return function(f) {
845− \ return function() {\
1009+ return function() {
846− \ for (var i = 0; i < as.length; i++) {\
1010+ for (var i = 0; i < as.length; i++) {
847− \ f(as[i])();\
1011+ f(as[i])();
848− \ }\
1012+ }
849− \ };\
1013+ };
850− \ };\
1014+ };
1015+ }
851− \}" :: forall e a. [a] -> (a -> Eff e Unit) -> Eff e Unit
1016+ """ :: forall e a. [a] -> (a -> Eff e Unit) -> Eff e Unit
852
1017
853module Control.Monad.Eff.Unsafe where
1018module Control.Monad.Eff.Unsafe where
854
1019
855 import Control.Monad.Eff
1020 import Control.Monad.Eff
856
1021
857 foreign import unsafeInterleaveEff
1022 foreign import unsafeInterleaveEff
1023+ """
858− "function unsafeInterleaveEff(f) {\
1024+ function unsafeInterleaveEff(f) {
859− \ return f;\
1025+ return f;
1026+ }
860− \}" :: forall eff1 eff2 a. Eff eff1 a -> Eff eff2 a
1027+ """ :: forall eff1 eff2 a. Eff eff1 a -> Eff eff2 a
861
1028
862module Debug.Trace where
1029module Debug.Trace where
863
1030
@@ -865,12 +1032,15 @@ module Debug.Trace where
865
1032
866 foreign import data Trace :: !
1033 foreign import data Trace :: !
867
1034
868− foreign import trace "function trace(s) {\
1035+ foreign import trace
1036+ """
1037+ function trace(s) {
869− \ return function() {\
1038+ return function() {
870− \ console.log(s);\
1039+ console.log(s);
871− \ return {};\
1040+ return {};
872− \ };\
1041+ };
1042+ }
873− \}" :: forall r. String -> Eff (trace :: Trace | r) Unit
1043+ """ :: forall r. String -> Eff (trace :: Trace | r) Unit
874
1044
875 print :: forall a r. (Show a) => a -> Eff (trace :: Trace | r) Unit
1045 print :: forall a r. (Show a) => a -> Eff (trace :: Trace | r) Unit
876 print o = trace (show o)
1046 print o = trace (show o)
@@ -883,37 +1053,52 @@ module Control.Monad.ST where
883
1053
884 foreign import data STRef :: * -> * -> *
1054 foreign import data STRef :: * -> * -> *
885
1055
886− foreign import newSTRef "function newSTRef(val) {\
1056+ foreign import newSTRef
1057+ """
1058+ function newSTRef(val) {
887− \ return function() {\
1059+ return function() {
888− \ return { value: val };\
1060+ return { value: val };
889− \ };\
1061+ };
1062+ }
890− \}" :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
1063+ """ :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
891−
1064+
892− foreign import readSTRef "function readSTRef(ref) {\
1065+ foreign import readSTRef
1066+ """
1067+ function readSTRef(ref) {
893− \ return function() {\
1068+ return function() {
894− \ return ref.value;\
1069+ return ref.value;
895− \ };\
1070+ };
1071+ }
896− \}" :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
1072+ """ :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
897−
1073+
898− foreign import modifySTRef "function modifySTRef(ref) {\
1074+ foreign import modifySTRef
1075+ """
1076+ function modifySTRef(ref) {
899− \ return function(f) {\
1077+ return function(f) {
900− \ return function() {\
1078+ return function() {
901− \ return ref.value = f(ref.value);\
1079+ return ref.value = f(ref.value);
902− \ };\
1080+ };
903− \ };\
1081+ };
1082+ }
904− \}" :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) a
1083+ """ :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) a
905−
1084+
906− foreign import writeSTRef "function writeSTRef(ref) {\
1085+ foreign import writeSTRef
1086+ """
1087+ function writeSTRef(ref) {
907− \ return function(a) {\
1088+ return function(a) {
908− \ return function() {\
1089+ return function() {
909− \ return ref.value = a;\
1090+ return ref.value = a;
910− \ };\
1091+ };
911− \ };\
1092+ };
1093+ }
912− \}" :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) a
1094+ """ :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) a
913−
1095+
914− foreign import runST "function runST(f) {\
1096+ foreign import runST
1097+ """
1098+ function runST(f) {
915− \ return f;\
1099+ return f;
1100+ }
916− \}" :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
1101+ """ :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
917
1102
918 pureST :: forall a. (forall h r. Eff (st :: ST h | r) a) -> a
1103 pureST :: forall a. (forall h r. Eff (st :: ST h | r) a) -> a
919 pureST st = runPure (runST st)
1104 pureST st = runPure (runST st)
prelude/updateDocs.sh+1−1
@@ -1,5 +1,5 @@
1../dist/build/psc-docs/psc-docs --hierarchy-images prelude.purs > README.md
1../dist/build/psc-docs/psc-docs --hierarchy-images prelude.purs > README.md
2−../dist/build/hierarchy/hierarchy prelude.purs -o prelude
2+../dist/build/psc-hierarchy/psc-hierarchy prelude.purs -o prelude
3
3
4mkdir -p images
4mkdir -p images
5
5
psc-docs/Main.hs+111−105
@@ -18,39 +18,35 @@ import Control.Applicative
18import Control.Monad
18import Control.Monad
19import Control.Monad.Writer
19import Control.Monad.Writer
20import Control.Arrow (first)
20import Control.Arrow (first)
21−import Data.Function (on)
22import Data.List
21import Data.List
23import Data.Maybe (fromMaybe)
22import Data.Maybe (fromMaybe)
24import Data.Version (showVersion)
23import Data.Version (showVersion)
24+import Data.Foldable (traverse_)
25
25
26import Options.Applicative
26import Options.Applicative
27
27
28import qualified Language.PureScript as P
28import qualified Language.PureScript as P
29import qualified Paths_purescript as Paths
29import qualified Paths_purescript as Paths
30−import qualified System.IO.UTF8 as U
31import System.Exit (exitSuccess, exitFailure)
30import System.Exit (exitSuccess, exitFailure)
32−import System.IO (stderr)
31+import System.IO (hPutStrLn, stderr)
33−
34
32
35data PSCDocsOptions = PSCDocsOptions
33data PSCDocsOptions = PSCDocsOptions
36− { pscdIncludeHeir :: Bool
37− , pscdInputFiles :: [FilePath]
34+ { pscdInputFiles :: [FilePath]
38 }
35 }
39
36
40−
41docgen :: PSCDocsOptions -> IO ()
37docgen :: PSCDocsOptions -> IO ()
42−docgen (PSCDocsOptions showHierarchy input) = do
38+docgen (PSCDocsOptions input) = do
43 e <- P.parseModulesFromFiles (fromMaybe "") <$> mapM (fmap (first Just) . parseFile) (nub input)
39 e <- P.parseModulesFromFiles (fromMaybe "") <$> mapM (fmap (first Just) . parseFile) (nub input)
44 case e of
40 case e of
45 Left err -> do
41 Left err -> do
46− U.hPutStr stderr $ show err
42+ hPutStrLn stderr $ show err
47 exitFailure
43 exitFailure
48 Right ms -> do
44 Right ms -> do
49− U.putStrLn . runDocs $ (renderModules showHierarchy) (map snd ms)
45+ putStrLn . runDocs $ renderModules (map snd ms)
50 exitSuccess
46 exitSuccess
51
47
52parseFile :: FilePath -> IO (FilePath, String)
48parseFile :: FilePath -> IO (FilePath, String)
53−parseFile input = (,) input <$> U.readFile input
49+parseFile input = (,) input <$> readFile input
54
50
55type Docs = Writer [String] ()
51type Docs = Writer [String] ()
56
52
@@ -63,98 +59,126 @@ spacer = tell [""]
63headerLevel :: Int -> String -> Docs
59headerLevel :: Int -> String -> Docs
64headerLevel level hdr = tell [replicate level '#' ++ ' ' : hdr]
60headerLevel level hdr = tell [replicate level '#' ++ ' ' : hdr]
65
61
62+withIndent :: Int -> Docs -> Docs
63+withIndent indent = censor (map (replicate indent ' ' ++ ))
64+
66atIndent :: Int -> String -> Docs
65atIndent :: Int -> String -> Docs
67atIndent indent text =
66atIndent indent text =
68 let ls = lines text in
67 let ls = lines text in
69− forM_ ls $ \l -> tell [replicate indent ' ' ++ l]
68+ withIndent indent (tell ls)
69+
70+fenced :: String -> Docs
71+fenced text = fencedBlock (tell $ lines text)
72+
73+fencedBlock :: Docs -> Docs
74+fencedBlock inner = do
75+ tell ["``` purescript"]
76+ inner
77+ tell ["```"]
78+
79+ticks :: String -> String
80+ticks = ("`" ++) . (++ "`")
70
81
71−renderModules :: Bool -> [P.Module] -> Docs
82+renderModules :: [P.Module] -> Docs
72−renderModules showHierarchy ms = do
83+renderModules ms = do
73 headerLevel 1 "Module Documentation"
84 headerLevel 1 "Module Documentation"
74 spacer
85 spacer
75− mapM_ (renderModule showHierarchy) ms
86+ mapM_ renderModule ms
76−
87+
77−renderModule :: Bool -> P.Module -> Docs
88+renderModule :: P.Module -> Docs
78−renderModule showHierarchy mdl@(P.Module moduleName _ exps) =
89+renderModule mdl@(P.Module moduleName _ exps) = do
79− let ds = P.exportedDeclarations mdl
80− hasTypes = any isTypeDeclaration ds
81− hasTypeclasses = any isTypeClassDeclaration ds
82− hasTypeclassInstances = any isTypeInstanceDeclaration ds
83− hasValues = any isValueDeclaration ds
84− in do
85 headerLevel 2 $ "Module " ++ P.runModuleName moduleName
90 headerLevel 2 $ "Module " ++ P.runModuleName moduleName
86 spacer
91 spacer
87− when hasTypes $ do
88− headerLevel 3 "Types"
89− spacer
90− renderTopLevel exps (filter isTypeDeclaration ds)
91− spacer
92− when hasTypeclasses $ do
93− headerLevel 3 "Type Classes"
94− spacer
95− when showHierarchy $ do
96− renderTypeclassImage moduleName
97− spacer
98− renderTopLevel exps (filter isTypeClassDeclaration ds)
92+ renderTopLevel exps (P.exportedDeclarations mdl)
99− spacer
100− when hasTypeclassInstances $ do
101− headerLevel 3 "Type Class Instances"
102− spacer
103− renderTopLevel exps (filter isTypeInstanceDeclaration ds)
104− spacer
105− when hasValues $ do
106− headerLevel 3 "Values"
107− spacer
108− renderTopLevel exps (filter isValueDeclaration ds)
109− spacer
93+ spacer
110
94
111renderTopLevel :: Maybe [P.DeclarationRef] -> [P.Declaration] -> Docs
95renderTopLevel :: Maybe [P.DeclarationRef] -> [P.Declaration] -> Docs
112−renderTopLevel exps decls = forM_ (sortBy (compare `on` getName) decls) $ \decl -> do
96+renderTopLevel exps decls = forM_ decls $ \decl ->
97+ when (canRenderDecl decl) $ do
98+ traverse_ (headerLevel 4) (ticks `fmap` getDeclarationTitle decl)
99+ spacer
113− renderDeclaration 4 exps decl
100+ renderDeclaration exps decl
114− spacer
101+ spacer
115
102
116renderTypeclassImage :: P.ModuleName -> Docs
103renderTypeclassImage :: P.ModuleName -> Docs
117renderTypeclassImage name =
104renderTypeclassImage name =
118 let name' = P.runModuleName name
105 let name' = P.runModuleName name
119 in tell ["![" ++ name' ++ "](images/" ++ name' ++ ".png)"]
106 in tell ["![" ++ name' ++ "](images/" ++ name' ++ ".png)"]
120
107
108+getDeclarationTitle :: P.Declaration -> Maybe String
109+getDeclarationTitle (P.TypeDeclaration name _) = Just (show name)
110+getDeclarationTitle (P.ExternDeclaration _ name _ _) = Just (show name)
111+getDeclarationTitle (P.DataDeclaration _ name _ _) = Just (show name)
112+getDeclarationTitle (P.ExternDataDeclaration name _) = Just (show name)
113+getDeclarationTitle (P.TypeSynonymDeclaration name _ _) = Just (show name)
114+getDeclarationTitle (P.TypeClassDeclaration name _ _ _) = Just (show name)
115+getDeclarationTitle (P.TypeInstanceDeclaration name _ _ _ _) = Just (show name)
116+getDeclarationTitle (P.PositionedDeclaration _ _ d) = getDeclarationTitle d
117+getDeclarationTitle _ = Nothing
118+
121−renderDeclaration :: Int -> Maybe [P.DeclarationRef] -> P.Declaration -> Docs
119+renderDeclaration :: Maybe [P.DeclarationRef] -> P.Declaration -> Docs
122−renderDeclaration n _ (P.TypeDeclaration ident ty) =
120+renderDeclaration _ (P.TypeDeclaration ident ty) =
123− atIndent n $ show ident ++ " :: " ++ prettyPrintType' ty
121+ fenced $ show ident ++ " :: " ++ prettyPrintType' ty
124−renderDeclaration n _ (P.ExternDeclaration _ ident _ ty) =
122+renderDeclaration _ (P.ExternDeclaration _ ident _ ty) =
125− atIndent n $ show ident ++ " :: " ++ prettyPrintType' ty
123+ fenced $ show ident ++ " :: " ++ prettyPrintType' ty
126−renderDeclaration n exps (P.DataDeclaration dtype name args ctors) = do
124+renderDeclaration exps (P.DataDeclaration dtype name args ctors) = do
127 let
125 let
128 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
126 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
129 typeName = prettyPrintType' typeApp
127 typeName = prettyPrintType' typeApp
130 exported = filter (P.isDctorExported name exps . fst) ctors
128 exported = filter (P.isDctorExported name exps . fst) ctors
129+ fencedBlock $ do
131− atIndent n $ show dtype ++ " " ++ typeName ++ (if null exported then "" else " where")
130+ tell [show dtype ++ " " ++ typeName]
132− forM_ exported $ \(ctor, tys) ->
131+ zipWithM_ (\isFirst (ctor, tys) ->
133− let ctorTy = foldr P.function typeApp tys
134− in atIndent (n + 2) $ P.runProperName ctor ++ " :: " ++ prettyPrintType' ctorTy
132+ atIndent 2 $ (if isFirst then "= " else "| ") ++ P.runProperName ctor ++ " " ++ unwords (map P.prettyPrintTypeAtom tys))
133+ (True : repeat False) exported
135−renderDeclaration n _ (P.ExternDataDeclaration name kind) =
134+renderDeclaration _ (P.ExternDataDeclaration name kind) =
136− atIndent n $ "data " ++ P.runProperName name ++ " :: " ++ P.prettyPrintKind kind
135+ fenced $ "data " ++ P.runProperName name ++ " :: " ++ P.prettyPrintKind kind
137−renderDeclaration n _ (P.TypeSynonymDeclaration name args ty) = do
136+renderDeclaration _ (P.TypeSynonymDeclaration name args ty) = do
138 let
137 let
139 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
138 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
140− typeName = prettyPrintType' typeApp
139+ typeName = prettyPrintType' typeApp
141− atIndent n $ "type " ++ typeName ++ " = " ++ prettyPrintType' ty
140+ fenced $ "type " ++ typeName ++ " = " ++ prettyPrintType' ty
142−renderDeclaration n exps (P.TypeClassDeclaration name args implies ds) = do
141+renderDeclaration _ (P.TypeClassDeclaration name args implies ds) = do
143 let impliesText = case implies of
142 let impliesText = case implies of
144 [] -> ""
143 [] -> ""
145 is -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map P.prettyPrintTypeAtom tys')) is) ++ ") <= "
144 is -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map P.prettyPrintTypeAtom tys')) is) ++ ") <= "
146 classApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
145 classApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
147 className = prettyPrintType' classApp
146 className = prettyPrintType' classApp
147+ fencedBlock $ do
148− atIndent n $ "class " ++ impliesText ++ className ++ " where"
148+ tell ["class " ++ impliesText ++ className ++ " where"]
149− mapM_ (renderDeclaration (n + 2) exps) ds
149+ mapM_ renderClassMember ds
150+ where
151+ renderClassMember (P.PositionedDeclaration _ _ d) = renderClassMember d
152+ renderClassMember (P.TypeDeclaration ident ty) = atIndent 2 $ show ident ++ " :: " ++ prettyPrintType' ty
153+ renderClassMember _ = error "Invalid argument to renderClassMember."
150−renderDeclaration n _ (P.TypeInstanceDeclaration name constraints className tys _) = do
154+renderDeclaration _ (P.TypeInstanceDeclaration name constraints className tys _) = do
151 let constraintsText = case constraints of
155 let constraintsText = case constraints of
152 [] -> ""
156 [] -> ""
153 cs -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map P.prettyPrintTypeAtom tys')) cs) ++ ") => "
157 cs -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map P.prettyPrintTypeAtom tys')) cs) ++ ") => "
154− atIndent n $ "instance " ++ show name ++ " :: " ++ constraintsText ++ show className ++ " " ++ unwords (map P.prettyPrintTypeAtom tys)
158+ fenced $ "instance " ++ show name ++ " :: " ++ constraintsText ++ show className ++ " " ++ unwords (map P.prettyPrintTypeAtom tys)
155−renderDeclaration n exps (P.PositionedDeclaration _ d) =
159+renderDeclaration exps (P.PositionedDeclaration _ com d) = do
156− renderDeclaration n exps d
160+ renderDeclaration exps d
157−renderDeclaration _ _ _ = return ()
161+ renderComments com
162+renderDeclaration _ _ = return ()
163+
164+renderComments :: [P.Comment] -> Docs
165+renderComments cs = do
166+ let raw = concatMap toLines cs
167+ when (all hasPipe raw) $ do
168+ spacer
169+ atIndent 0 . unlines . map stripPipes $ raw
170+ where
171+
172+ toLines (P.LineComment s) = [s]
173+ toLines (P.BlockComment s) = lines s
174+
175+ hasPipe s = case dropWhile (== ' ') s of { ('|':_) -> True; _ -> False }
176+
177+ stripPipes = dropPipe . dropWhile (== ' ')
178+
179+ dropPipe ('|':' ':s) = s
180+ dropPipe ('|':s) = s
181+ dropPipe s = s
158
182
159toTypeVar :: (String, Maybe P.Kind) -> P.Type
183toTypeVar :: (String, Maybe P.Kind) -> P.Type
160toTypeVar (s, Nothing) = P.TypeVar s
184toTypeVar (s, Nothing) = P.TypeVar s
@@ -176,45 +200,27 @@ getName (P.ExternDataDeclaration name _) = P.runProperName name
176getName (P.TypeSynonymDeclaration name _ _) = P.runProperName name
200getName (P.TypeSynonymDeclaration name _ _) = P.runProperName name
177getName (P.TypeClassDeclaration name _ _ _) = P.runProperName name
201getName (P.TypeClassDeclaration name _ _ _) = P.runProperName name
178getName (P.TypeInstanceDeclaration name _ _ _ _) = show name
202getName (P.TypeInstanceDeclaration name _ _ _ _) = show name
179−getName (P.PositionedDeclaration _ d) = getName d
203+getName (P.PositionedDeclaration _ _ d) = getName d
180getName _ = error "Invalid argument to getName"
204getName _ = error "Invalid argument to getName"
181
205
182−isValueDeclaration :: P.Declaration -> Bool
206+canRenderDecl :: P.Declaration -> Bool
183−isValueDeclaration P.TypeDeclaration{} = True
207+canRenderDecl P.TypeDeclaration{} = True
184−isValueDeclaration P.ExternDeclaration{} = True
208+canRenderDecl P.ExternDeclaration{} = True
185−isValueDeclaration (P.PositionedDeclaration _ d) = isValueDeclaration d
186−isValueDeclaration _ = False
187−
188−isTypeDeclaration :: P.Declaration -> Bool
189−isTypeDeclaration P.DataDeclaration{} = True
209+canRenderDecl P.DataDeclaration{} = True
190−isTypeDeclaration P.ExternDataDeclaration{} = True
210+canRenderDecl P.ExternDataDeclaration{} = True
191−isTypeDeclaration P.TypeSynonymDeclaration{} = True
211+canRenderDecl P.TypeSynonymDeclaration{} = True
192−isTypeDeclaration (P.PositionedDeclaration _ d) = isTypeDeclaration d
193−isTypeDeclaration _ = False
194−
195−isTypeClassDeclaration :: P.Declaration -> Bool
196−isTypeClassDeclaration P.TypeClassDeclaration{} = True
212+canRenderDecl P.TypeClassDeclaration{} = True
197−isTypeClassDeclaration (P.PositionedDeclaration _ d) = isTypeClassDeclaration d
198−isTypeClassDeclaration _ = False
199−
200−isTypeInstanceDeclaration :: P.Declaration -> Bool
201−isTypeInstanceDeclaration P.TypeInstanceDeclaration{} = True
213+canRenderDecl P.TypeInstanceDeclaration{} = True
202−isTypeInstanceDeclaration (P.PositionedDeclaration _ d) = isTypeInstanceDeclaration d
214+canRenderDecl (P.PositionedDeclaration _ _ d) = canRenderDecl d
203−isTypeInstanceDeclaration _ = False
215+canRenderDecl _ = False
204
216
205inputFile :: Parser FilePath
217inputFile :: Parser FilePath
206inputFile = strArgument $
218inputFile = strArgument $
207 metavar "FILE"
219 metavar "FILE"
208− <> help "The input .ps file(s)"
220+ <> help "The input .purs file(s)"
209−
210−includeHeirarcy :: Parser Bool
211−includeHeirarcy = switch $
212− long "hierarchy-images"
213− <> help "Include markdown for type class hierarchy images in the output."
214
221
215pscDocsOptions :: Parser PSCDocsOptions
222pscDocsOptions :: Parser PSCDocsOptions
216−pscDocsOptions = PSCDocsOptions <$> includeHeirarcy
223+pscDocsOptions = PSCDocsOptions <$> many inputFile
217− <*> many inputFile
218
224
219main :: IO ()
225main :: IO ()
220main = execParser opts >>= docgen
226main = execParser opts >>= docgen
@@ -223,6 +229,6 @@ main = execParser opts >>= docgen
223 infoModList = fullDesc <> headerInfo <> footerInfo
229 infoModList = fullDesc <> headerInfo <> footerInfo
224 headerInfo = header "psc-docs - Generate Markdown documentation from PureScript extern files"
230 headerInfo = header "psc-docs - Generate Markdown documentation from PureScript extern files"
225 footerInfo = footer $ "psc-docs " ++ showVersion Paths.version
231 footerInfo = footer $ "psc-docs " ++ showVersion Paths.version
226−
232+
227 version :: Parser (a -> a)
233 version :: Parser (a -> a)
228 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
234 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
psc-make/Main.hs+37−31
@@ -17,9 +17,11 @@
17module Main where
17module Main where
18
18
19import Control.Applicative
19import Control.Applicative
20−import Control.Monad.Error
20+import Control.Monad.Except
21+import Control.Monad.Reader
21
22
22import Data.Version (showVersion)
23import Data.Version (showVersion)
24+import Data.Traversable (traverse)
23
25
24import Options.Applicative as Opts
26import Options.Applicative as Opts
25
27
@@ -31,7 +33,6 @@ import System.IO.Error (tryIOError)
31
33
32import qualified Language.PureScript as P
34import qualified Language.PureScript as P
33import qualified Paths_purescript as Paths
35import qualified Paths_purescript as Paths
34−import qualified System.IO.UTF8 as U
35
36
36
37
37data PSCMakeOptions = PSCMakeOptions
38data PSCMakeOptions = PSCMakeOptions
@@ -48,45 +49,43 @@ data InputOptions = InputOptions
48
49
49readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
50readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
50readInput InputOptions{..} = do
51readInput InputOptions{..} = do
51− content <- forM ioInputFiles $ \inFile -> (Right inFile, ) <$> U.readFile inFile
52+ content <- forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readFile inFile
52 return (if ioNoPrelude then content else (Left P.RebuildNever, P.prelude) : content)
53 return (if ioNoPrelude then content else (Left P.RebuildNever, P.prelude) : content)
53
54
55+newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (ExceptT String IO) a }
54−newtype Make a = Make { unMake :: ErrorT String IO a } deriving (Functor, Applicative, Monad, MonadIO, MonadError String)
56+ deriving (Functor, Applicative, Monad, MonadIO, MonadError String, MonadReader (P.Options P.Make))
55
57
56−runMake :: Make a -> IO (Either String a)
58+runMake :: P.Options P.Make -> Make a -> IO (Either String a)
57−runMake = runErrorT . unMake
59+runMake opts = runExceptT . flip runReaderT opts . unMake
58
60
59makeIO :: IO a -> Make a
61makeIO :: IO a -> Make a
60−makeIO = Make . ErrorT . fmap (either (Left . show) Right) . tryIOError
62+makeIO = Make . lift . ExceptT . fmap (either (Left . show) Right) . tryIOError
61
63
62instance P.MonadMake Make where
64instance P.MonadMake Make where
63 getTimestamp path = makeIO $ do
65 getTimestamp path = makeIO $ do
64 exists <- doesFileExist path
66 exists <- doesFileExist path
65− case exists of
66− True -> Just <$> getModificationTime path
67+ traverse (const $ getModificationTime path) $ guard exists
67− False -> return Nothing
68 readTextFile path = makeIO $ do
68 readTextFile path = makeIO $ do
69− U.putStrLn $ "Reading " ++ path
69+ putStrLn $ "Reading " ++ path
70− U.readFile path
70+ readFile path
71 writeTextFile path text = makeIO $ do
71 writeTextFile path text = makeIO $ do
72 mkdirp path
72 mkdirp path
73− U.putStrLn $ "Writing " ++ path
73+ putStrLn $ "Writing " ++ path
74− U.writeFile path text
74+ writeFile path text
75− liftError = either throwError return
76− progress = makeIO . U.putStrLn
75+ progress = makeIO . putStrLn
77
76
78compile :: PSCMakeOptions -> IO ()
77compile :: PSCMakeOptions -> IO ()
79compile (PSCMakeOptions input outputDir opts usePrefix) = do
78compile (PSCMakeOptions input outputDir opts usePrefix) = do
80 modules <- P.parseModulesFromFiles (either (const "") id) <$> readInput (InputOptions (P.optionsNoPrelude opts) input)
79 modules <- P.parseModulesFromFiles (either (const "") id) <$> readInput (InputOptions (P.optionsNoPrelude opts) input)
81 case modules of
80 case modules of
82 Left err -> do
81 Left err -> do
83− U.print err
82+ print err
84 exitFailure
83 exitFailure
85 Right ms -> do
84 Right ms -> do
86− e <- runMake $ P.make outputDir opts ms prefix
85+ e <- runMake opts $ P.make outputDir ms prefix
87 case e of
86 case e of
88 Left err -> do
87 Left err -> do
89− U.putStrLn err
88+ putStrLn err
90 exitFailure
89 exitFailure
91 Right _ -> do
90 Right _ -> do
92 exitSuccess
91 exitSuccess
@@ -101,7 +100,7 @@ mkdirp = createDirectoryIfMissing True . takeDirectory
101inputFile :: Parser FilePath
100inputFile :: Parser FilePath
102inputFile = strArgument $
101inputFile = strArgument $
103 metavar "FILE"
102 metavar "FILE"
104− <> help "The input .ps file(s)"
103+ <> help "The input .purs file(s)"
105
104
106outputDirectory :: Parser FilePath
105outputDirectory :: Parser FilePath
107outputDirectory = strOption $
106outputDirectory = strOption $
@@ -112,12 +111,12 @@ outputDirectory = strOption $
112 <> help "The output directory"
111 <> help "The output directory"
113
112
114noTco :: Parser Bool
113noTco :: Parser Bool
115−noTco = switch $
114+noTco = switch $
116 long "no-tco"
115 long "no-tco"
117 <> help "Disable tail call optimizations"
116 <> help "Disable tail call optimizations"
118
117
119noPrelude :: Parser Bool
118noPrelude :: Parser Bool
120−noPrelude = switch $
119+noPrelude = switch $
121 long "no-prelude"
120 long "no-prelude"
122 <> help "Omit the Prelude"
121 <> help "Omit the Prelude"
123
122
@@ -128,35 +127,42 @@ noMagicDo = switch $
128
127
129noOpts :: Parser Bool
128noOpts :: Parser Bool
130noOpts = switch $
129noOpts = switch $
131− long "verbose-errors"
130+ long "no-opts"
132 <> help "Skip the optimization phase."
131 <> help "Skip the optimization phase."
133
132
133+comments :: Parser Bool
134+comments = switch $
135+ short 'c'
136+ <> long "comments"
137+ <> help "Include comments in the generated code."
138+
134verboseErrors :: Parser Bool
139verboseErrors :: Parser Bool
135verboseErrors = switch $
140verboseErrors = switch $
136 short 'v'
141 short 'v'
137− <> long "no-opts"
142+ <> long "verbose-errors"
138 <> help "Display verbose error messages"
143 <> help "Display verbose error messages"
139
144
140noPrefix :: Parser Bool
145noPrefix :: Parser Bool
141−noPrefix = switch $
146+noPrefix = switch $
142 short 'p'
147 short 'p'
143 <> long "no-prefix"
148 <> long "no-prefix"
144 <> help "Do not include comment header"
149 <> help "Do not include comment header"
145
150
146
151
147options :: Parser (P.Options P.Make)
152options :: Parser (P.Options P.Make)
148−options = P.Options <$> noPrelude
153+options = P.Options <$> noPrelude
149− <*> noTco
154+ <*> noTco
150 <*> noMagicDo
155 <*> noMagicDo
151 <*> pure Nothing
156 <*> pure Nothing
152 <*> noOpts
157 <*> noOpts
158+ <*> comments
153 <*> verboseErrors
159 <*> verboseErrors
154 <*> pure P.MakeOptions
160 <*> pure P.MakeOptions
155
161
156pscMakeOptions :: Parser PSCMakeOptions
162pscMakeOptions :: Parser PSCMakeOptions
157−pscMakeOptions = PSCMakeOptions <$> many inputFile
163+pscMakeOptions = PSCMakeOptions <$> many inputFile
158− <*> outputDirectory
164+ <*> outputDirectory
159− <*> options
165+ <*> options
160 <*> (not <$> noPrefix)
166 <*> (not <$> noPrefix)
161
167
162main :: IO ()
168main :: IO ()
@@ -166,6 +172,6 @@ main = execParser opts >>= compile
166 infoModList = fullDesc <> headerInfo <> footerInfo
172 infoModList = fullDesc <> headerInfo <> footerInfo
167 headerInfo = header "psc-make - Compiles PureScript to Javascript"
173 headerInfo = header "psc-make - Compiles PureScript to Javascript"
168 footerInfo = footer $ "psc-make " ++ showVersion Paths.version
174 footerInfo = footer $ "psc-make " ++ showVersion Paths.version
169−
175+
170 version :: Parser (a -> a)
176 version :: Parser (a -> a)
171 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
177 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
psc/Main.hs+30−23
@@ -17,7 +17,8 @@
17module Main where
17module Main where
18
18
19import Control.Applicative
19import Control.Applicative
20−import Control.Monad.Error
20+import Control.Monad.Except
21+import Control.Monad.Reader
21
22
22import Data.Maybe (fromMaybe)
23import Data.Maybe (fromMaybe)
23import Data.Version (showVersion)
24import Data.Version (showVersion)
@@ -26,11 +27,10 @@ import Options.Applicative as Opts
26import System.Directory (createDirectoryIfMissing)
27import System.Directory (createDirectoryIfMissing)
27import System.FilePath (takeDirectory)
28import System.FilePath (takeDirectory)
28import System.Exit (exitSuccess, exitFailure)
29import System.Exit (exitSuccess, exitFailure)
29−import System.IO (stderr)
30+import System.IO (hPutStrLn, stderr)
30
31
31import qualified Language.PureScript as P
32import qualified Language.PureScript as P
32import qualified Paths_purescript as Paths
33import qualified Paths_purescript as Paths
33−import qualified System.IO.UTF8 as U
34
34
35
35
36data PSCOptions = PSCOptions
36data PSCOptions = PSCOptions
@@ -51,7 +51,7 @@ data InputOptions = InputOptions
51readInput :: InputOptions -> IO [(Maybe FilePath, String)]
51readInput :: InputOptions -> IO [(Maybe FilePath, String)]
52readInput InputOptions{..}
52readInput InputOptions{..}
53 | ioUseStdIn = return . (Nothing ,) <$> getContents
53 | ioUseStdIn = return . (Nothing ,) <$> getContents
54− | otherwise = do content <- forM ioInputFiles $ \inFile -> (Just inFile, ) <$> U.readFile inFile
54+ | otherwise = do content <- forM ioInputFiles $ \inFile -> (Just inFile, ) <$> readFile inFile
55 return (if ioNoPrelude then content else (Nothing, P.prelude) : content)
55 return (if ioNoPrelude then content else (Nothing, P.prelude) : content)
56
56
57compile :: PSCOptions -> IO ()
57compile :: PSCOptions -> IO ()
@@ -59,19 +59,19 @@ compile (PSCOptions input opts stdin output externs usePrefix) = do
59 modules <- P.parseModulesFromFiles (fromMaybe "") <$> readInput (InputOptions (P.optionsNoPrelude opts) stdin input)
59 modules <- P.parseModulesFromFiles (fromMaybe "") <$> readInput (InputOptions (P.optionsNoPrelude opts) stdin input)
60 case modules of
60 case modules of
61 Left err -> do
61 Left err -> do
62− U.hPutStr stderr $ show err
62+ hPutStrLn stderr $ show err
63 exitFailure
63 exitFailure
64 Right ms -> do
64 Right ms -> do
65− case P.compile opts (map snd ms) prefix of
65+ case P.compile (map snd ms) prefix `runReaderT` opts of
66 Left err -> do
66 Left err -> do
67− U.hPutStrLn stderr err
67+ hPutStrLn stderr err
68 exitFailure
68 exitFailure
69 Right (js, exts, _) -> do
69 Right (js, exts, _) -> do
70 case output of
70 case output of
71− Just path -> mkdirp path >> U.writeFile path js
71+ Just path -> mkdirp path >> writeFile path js
72− Nothing -> U.putStrLn js
72+ Nothing -> putStrLn js
73 case externs of
73 case externs of
74− Just path -> mkdirp path >> U.writeFile path exts
74+ Just path -> mkdirp path >> writeFile path exts
75 Nothing -> return ()
75 Nothing -> return ()
76 exitSuccess
76 exitSuccess
77 where
77 where
@@ -116,28 +116,34 @@ runMain = optional $ noArgs <|> withArgs
116 where
116 where
117 defaultVal = "Main"
117 defaultVal = "Main"
118 noArgs = flag' defaultVal (long "main")
118 noArgs = flag' defaultVal (long "main")
119− withArgs = strOption $
119+ withArgs = strOption $
120 long "main"
120 long "main"
121 <> help (concat [
121 <> help (concat [
122 "Generate code to run the main method in the specified module. ",
122 "Generate code to run the main method in the specified module. ",
123 "(no argument: \"", defaultVal, "\")"
123 "(no argument: \"", defaultVal, "\")"
124 ])
124 ])
125−
125+
126noMagicDo :: Parser Bool
126noMagicDo :: Parser Bool
127noMagicDo = switch $
127noMagicDo = switch $
128 long "no-magic-do"
128 long "no-magic-do"
129 <> help "Disable the optimization that overloads the do keyword to generate efficient code specifically for the Eff monad."
129 <> help "Disable the optimization that overloads the do keyword to generate efficient code specifically for the Eff monad."
130−
130+
131noTco :: Parser Bool
131noTco :: Parser Bool
132−noTco = switch $
132+noTco = switch $
133 long "no-tco"
133 long "no-tco"
134 <> help "Disable tail call optimizations"
134 <> help "Disable tail call optimizations"
135
135
136noPrelude :: Parser Bool
136noPrelude :: Parser Bool
137−noPrelude = switch $
137+noPrelude = switch $
138 long "no-prelude"
138 long "no-prelude"
139 <> help "Omit the Prelude"
139 <> help "Omit the Prelude"
140
140
141+comments :: Parser Bool
142+comments = switch $
143+ short 'c'
144+ <> long "comments"
145+ <> help "Include comments in the generated code."
146+
141useStdIn :: Parser Bool
147useStdIn :: Parser Bool
142useStdIn = switch $
148useStdIn = switch $
143 short 's'
149 short 's'
@@ -147,7 +153,7 @@ useStdIn = switch $
147inputFile :: Parser FilePath
153inputFile :: Parser FilePath
148inputFile = strArgument $
154inputFile = strArgument $
149 metavar "FILE"
155 metavar "FILE"
150− <> help "The input .ps file(s)"
156+ <> help "The input .purs file(s)"
151
157
152outputFile :: Parser (Maybe FilePath)
158outputFile :: Parser (Maybe FilePath)
153outputFile = optional . strOption $
159outputFile = optional . strOption $
@@ -159,25 +165,26 @@ externsFile :: Parser (Maybe FilePath)
159externsFile = optional . strOption $
165externsFile = optional . strOption $
160 short 'e'
166 short 'e'
161 <> long "externs"
167 <> long "externs"
162− <> help "The output .e.ps file"
168+ <> help "The output .e.purs file"
163
169
164noPrefix :: Parser Bool
170noPrefix :: Parser Bool
165−noPrefix = switch $
171+noPrefix = switch $
166 short 'p'
172 short 'p'
167 <> long "no-prefix"
173 <> long "no-prefix"
168 <> help "Do not include comment header"
174 <> help "Do not include comment header"
169
175
170options :: Parser (P.Options P.Compile)
176options :: Parser (P.Options P.Compile)
171−options = P.Options <$> noPrelude
177+options = P.Options <$> noPrelude
172− <*> noTco
178+ <*> noTco
173 <*> noMagicDo
179 <*> noMagicDo
174 <*> runMain
180 <*> runMain
175 <*> noOpts
181 <*> noOpts
176 <*> verboseErrors
182 <*> verboseErrors
183+ <*> comments
177 <*> additionalOptions
184 <*> additionalOptions
178 where
185 where
179− additionalOptions =
186+ additionalOptions =
180− P.CompileOptions <$> browserNamespace
187+ P.CompileOptions <$> browserNamespace
181 <*> many dceModule
188 <*> many dceModule
182 <*> many codeGenModule
189 <*> many codeGenModule
183
190
@@ -196,7 +203,7 @@ main = execParser opts >>= compile
196 infoModList = fullDesc <> headerInfo <> footerInfo
203 infoModList = fullDesc <> headerInfo <> footerInfo
197 headerInfo = header "psc - Compiles PureScript to Javascript"
204 headerInfo = header "psc - Compiles PureScript to Javascript"
198 footerInfo = footer $ "psc " ++ showVersion Paths.version
205 footerInfo = footer $ "psc " ++ showVersion Paths.version
199−
206+
200 version :: Parser (a -> a)
207 version :: Parser (a -> a)
201 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
208 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
202
209
psci/Commands.hs+1−1
@@ -52,7 +52,7 @@ data Command
52 -- |
52 -- |
53 -- Binds a value to a name
53 -- Binds a value to a name
54 --
54 --
55− | Let (Expr -> Expr)
55+ | Let [Declaration]
56 -- |
56 -- |
57 -- Find the type of an expression
57 -- Find the type of an expression
58 --
58 --
psci/Main.hs+138−95
@@ -13,7 +13,11 @@
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16+{-# LANGUAGE DataKinds #-}
17+{-# LANGUAGE DoAndIfThenElse #-}
18+{-# LANGUAGE FlexibleContexts #-}
16−{-# LANGUAGE DataKinds, DoAndIfThenElse, FlexibleContexts, GeneralizedNewtypeDeriving #-}
19+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
20+{-# LANGUAGE RecordWildCards #-}
17
21
18module Main where
22module Main where
19
23
@@ -27,8 +31,8 @@ import qualified Data.Map as M
27
31
28import Control.Applicative
32import Control.Applicative
29import Control.Monad
33import Control.Monad
30−import Control.Monad.Error (ErrorT(..), MonadError)
34+import Control.Monad.Except (ExceptT(..), MonadError, runExceptT)
31−import Control.Monad.Error.Class (MonadError(..))
35+import Control.Monad.Reader (MonadReader, ReaderT, runReaderT)
32import Control.Monad.Trans.Class
36import Control.Monad.Trans.Class
33import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
37import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
34import Control.Monad.Trans.State.Strict
38import Control.Monad.Trans.State.Strict
@@ -42,7 +46,6 @@ import System.Exit
42import System.FilePath (pathSeparator, takeDirectory, (</>), isPathSeparator)
46import System.FilePath (pathSeparator, takeDirectory, (</>), isPathSeparator)
43import System.IO.Error (tryIOError)
47import System.IO.Error (tryIOError)
44import System.Process (readProcessWithExitCode)
48import System.Process (readProcessWithExitCode)
45−import qualified System.IO.UTF8 as U (writeFile, putStrLn, print, readFile)
46
49
47import qualified Text.Parsec as Par (ParseError)
50import qualified Text.Parsec as Par (ParseError)
48
51
@@ -54,11 +57,10 @@ import qualified Paths_purescript as Paths
54import Commands as C
57import Commands as C
55import Parser
58import Parser
56
59
57−
58data PSCiOptions = PSCiOptions
60data PSCiOptions = PSCiOptions
59− { psciSingleLineFlag :: Bool
61+ { psciMultiLineMode :: Bool
60− , psciInputNodeFlags :: [String]
61 , psciInputFile :: [FilePath]
62 , psciInputFile :: [FilePath]
63+ , psciInputNodeFlags :: [String]
62 }
64 }
63
65
64-- |
66-- |
@@ -71,7 +73,7 @@ data PSCiState = PSCiState
71 { psciImportedFilenames :: [FilePath]
73 { psciImportedFilenames :: [FilePath]
72 , psciImportedModuleNames :: [P.ModuleName]
74 , psciImportedModuleNames :: [P.ModuleName]
73 , psciLoadedModules :: [(Either P.RebuildPolicy FilePath, P.Module)]
75 , psciLoadedModules :: [(Either P.RebuildPolicy FilePath, P.Module)]
74− , psciLetBindings :: [P.Expr -> P.Expr]
76+ , psciLetBindings :: [P.Declaration]
75 , psciNodeFlags :: [String]
77 , psciNodeFlags :: [String]
76 }
78 }
77
79
@@ -98,8 +100,8 @@ updateModules modules st = st { psciLoadedModules = psciLoadedModules st ++ modu
98-- |
100-- |
99-- Updates the state to have more let bindings.
101-- Updates the state to have more let bindings.
100--
102--
101−updateLets :: (P.Expr -> P.Expr) -> PSCiState -> PSCiState
103+updateLets :: [P.Declaration] -> PSCiState -> PSCiState
102−updateLets name st = st { psciLetBindings = name : psciLetBindings st }
104+updateLets ds st = st { psciLetBindings = psciLetBindings st ++ ds }
103
105
104-- File helpers
106-- File helpers
105-- |
107-- |
@@ -131,7 +133,7 @@ getHistoryFilename = do
131--
133--
132loadModule :: FilePath -> IO (Either String [P.Module])
134loadModule :: FilePath -> IO (Either String [P.Module])
133loadModule filename = do
135loadModule filename = do
134− content <- U.readFile filename
136+ content <- readFile filename
135 return $ either (Left . show) (Right . map snd) $ P.parseModulesFromFiles id [(filename, content)]
137 return $ either (Left . show) (Right . map snd) $ P.parseModulesFromFiles id [(filename, content)]
136
138
137-- |
139-- |
@@ -140,10 +142,20 @@ loadModule filename = do
140loadAllModules :: [FilePath] -> IO (Either Par.ParseError [(Either P.RebuildPolicy FilePath, P.Module)])
142loadAllModules :: [FilePath] -> IO (Either Par.ParseError [(Either P.RebuildPolicy FilePath, P.Module)])
141loadAllModules files = do
143loadAllModules files = do
142 filesAndContent <- forM files $ \filename -> do
144 filesAndContent <- forM files $ \filename -> do
143− content <- U.readFile filename
145+ content <- readFile filename
144 return (Right filename, content)
146 return (Right filename, content)
145 return $ P.parseModulesFromFiles (either (const "") id) $ (Left P.RebuildNever, P.prelude) : filesAndContent
147 return $ P.parseModulesFromFiles (either (const "") id) $ (Left P.RebuildNever, P.prelude) : filesAndContent
146
148
149+-- |
150+-- Load all modules, updating the application state
151+--
152+loadAllImportedModules :: PSCI ()
153+loadAllImportedModules = do
154+ files <- PSCI . lift $ fmap psciImportedFilenames get
155+ modulesOrFirstError <- psciIO $ loadAllModules files
156+ case modulesOrFirstError of
157+ Left err -> psciIO $ print err
158+ Right modules -> PSCI . lift . modify $ \st -> st { psciLoadedModules = modules }
147
159
148-- |
160-- |
149-- Expands tilde in path.
161-- Expands tilde in path.
@@ -175,8 +187,6 @@ prologueMessage = intercalate "\n"
175 , " |_| "
187 , " |_| "
176 , ""
188 , ""
177 , ":? shows help"
189 , ":? shows help"
178− , ""
179− , "Expressions are terminated using Ctrl+D"
180 ]
190 ]
181
191
182-- |
192-- |
@@ -187,27 +197,28 @@ quitMessage = "See ya!"
187
197
188-- Haskeline completions
198-- Haskeline completions
189
199
190−data CompletionContext = Command String | FilePath | Module | Identifier | Fixed [String] | Multiple [CompletionContext]
200+data CompletionContext = Command String | FilePath String | Module | Identifier
201+ | Type | Fixed [String] | Multiple [CompletionContext]
191 deriving (Show)
202 deriving (Show)
192
203
193-- |
204-- |
194-- Decide what kind of completion we need based on input.
205-- Decide what kind of completion we need based on input.
195−completionContext :: String -> Maybe CompletionContext
206+completionContext :: String -> String -> Maybe CompletionContext
196−completionContext cmd@"" = Just $ Multiple [Command cmd, Identifier]
207+completionContext cmd@"" _ = Just $ Multiple [Command cmd, Identifier]
197−completionContext cmd@(':' : _ )
208+completionContext cmd@(':' : _ ) _
198 | cmd `elem` C.commands || cmd == ":" = Just $ Command cmd
209 | cmd `elem` C.commands || cmd == ":" = Just $ Command cmd
199−completionContext (':' : c : _) = case c of
210+completionContext (':' : c : _) word = case c of
200 'i' -> Just Module
211 'i' -> Just Module
201 'b' -> Just Module
212 'b' -> Just Module
202− 'm' -> Just FilePath
213+ 'm' -> Just $ FilePath word
203 'q' -> Nothing
214 'q' -> Nothing
204 'r' -> Nothing
215 'r' -> Nothing
205 '?' -> Nothing
216 '?' -> Nothing
206 's' -> Just $ Fixed ["import", "loaded"]
217 's' -> Just $ Fixed ["import", "loaded"]
207 't' -> Just Identifier
218 't' -> Just Identifier
208− 'k' -> Just Identifier
219+ 'k' -> Just Type
209 _ -> Nothing
220 _ -> Nothing
210−completionContext _ = Just Identifier
221+completionContext _ _ = Just Identifier
211
222
212-- |
223-- |
213-- Loads module, function, and file completions.
224-- Loads module, function, and file completions.
@@ -217,22 +228,23 @@ completion = completeWordWithPrev Nothing " \t\n\r" findCompletions
217 where
228 where
218 findCompletions :: String -> String -> StateT PSCiState IO [Completion]
229 findCompletions :: String -> String -> StateT PSCiState IO [Completion]
219 findCompletions prev word = do
230 findCompletions prev word = do
220− let ctx = completionContext $ (dropWhile isSpace (reverse prev)) ++ word
231+ let ctx = completionContext ((dropWhile isSpace (reverse prev)) ++ word) word
221 completions <- case ctx of
232 completions <- case ctx of
222 Nothing -> return []
233 Nothing -> return []
223 (Just c) -> (mapMaybe $ either (\cand -> if word `isPrefixOf` cand
234 (Just c) -> (mapMaybe $ either (\cand -> if word `isPrefixOf` cand
224 then Just $ simpleCompletion cand
235 then Just $ simpleCompletion cand
225 else Nothing) Just)
236 else Nothing) Just)
226− <$> getCompletion c word
237+ <$> getCompletion c
227 return $ sortBy sorter completions
238 return $ sortBy sorter completions
228
239
229− getCompletion :: CompletionContext -> String -> StateT PSCiState IO [Either String Completion]
240+ getCompletion :: CompletionContext -> StateT PSCiState IO [Either String Completion]
230− getCompletion (Command s) _ = return $ (map Left) $ nub $ filter (isPrefixOf s) C.commands
241+ getCompletion (Command s) = return $ (map Left) $ nub $ filter (isPrefixOf s) C.commands
231− getCompletion FilePath f = (map Right) <$> listFiles f
242+ getCompletion (FilePath f) = (map Right) <$> listFiles f
232− getCompletion Module _ = (map Left) <$> getModuleNames
243+ getCompletion Module = (map Left) <$> getModuleNames
233− getCompletion Identifier _ = (map Left) <$> getIdentNames
244+ getCompletion Identifier = (map Left) <$> ((++) <$> getIdentNames <*> getDctorNames)
245+ getCompletion Type = (map Left) <$> getTypeNames
234− getCompletion (Fixed list) _ = return $ (map Left) list
246+ getCompletion (Fixed list) = return $ (map Left) list
235− getCompletion (Multiple contexts) f = concat <$> mapM (flip getCompletion $ f) contexts
247+ getCompletion (Multiple contexts) = concat <$> mapM getCompletion contexts
236
248
237 getLoadedModules :: StateT PSCiState IO [P.Module]
249 getLoadedModules :: StateT PSCiState IO [P.Module]
238 getLoadedModules = map snd . psciLoadedModules <$> get
250 getLoadedModules = map snd . psciLoadedModules <$> get
@@ -240,30 +252,60 @@ completion = completeWordWithPrev Nothing " \t\n\r" findCompletions
240 getModuleNames :: StateT PSCiState IO [String]
252 getModuleNames :: StateT PSCiState IO [String]
241 getModuleNames = moduleNames <$> getLoadedModules
253 getModuleNames = moduleNames <$> getLoadedModules
242
254
255+ mapLoadedModulesAndQualify :: (Show a) => (P.Module -> [a]) -> StateT PSCiState IO [String]
256+ mapLoadedModulesAndQualify f = do
257+ ms <- getLoadedModules
258+ q <- sequence [qualifyIfNeeded m (f m) | m <- ms]
259+ return $ concat q
260+
243 getIdentNames :: StateT PSCiState IO [String]
261 getIdentNames :: StateT PSCiState IO [String]
244− getIdentNames = identNames <$> getLoadedModules
262+ getIdentNames = mapLoadedModulesAndQualify identNames
245−
263+
264+ getDctorNames :: StateT PSCiState IO [String]
265+ getDctorNames = mapLoadedModulesAndQualify dctorNames
266+
267+ getTypeNames :: StateT PSCiState IO [String]
268+ getTypeNames = mapLoadedModulesAndQualify typeDecls
269+
270+ qualifyIfNeeded :: (Show a) => P.Module -> [a] -> StateT PSCiState IO [String]
271+ qualifyIfNeeded m decls = do
272+ let name = P.getModuleName m
273+ imported <- psciImportedModuleNames <$> get
274+ let qualified = map (P.Qualified $ Just name) decls
275+ if name `elem` imported then
276+ return $ map show $ qualified ++ (map (P.Qualified Nothing) decls)
277+ else
278+ return $ map show qualified
279+
280+ typeDecls :: P.Module -> [N.ProperName]
281+ typeDecls m = mapMaybe getTypeName $ filter P.isDataDecl (P.exportedDeclarations m)
282+ where getTypeName :: P.Declaration -> Maybe N.ProperName
283+ getTypeName (P.TypeSynonymDeclaration name _ _) = Just name
284+ getTypeName (P.DataDeclaration _ name _ _) = Just name
285+ getTypeName (P.PositionedDeclaration _ _ d) = getTypeName d
286+ getTypeName _ = Nothing
287+
288+ identNames :: P.Module -> [N.Ident]
289+ identNames (P.Module _ ds exports) = nub [ ident | ident <- mapMaybe (getDeclName exports) (D.flattenDecls ds) ]
246− getDeclName :: Maybe [P.DeclarationRef] -> P.Declaration -> Maybe P.Ident
290+ where getDeclName :: Maybe [P.DeclarationRef] -> P.Declaration -> Maybe P.Ident
247− getDeclName exts (P.ValueDeclaration ident _ _ _) | isExported ident exts = Just ident
291+ getDeclName exts decl@(P.ValueDeclaration ident _ _ _) | P.isExported exts decl = Just ident
248− getDeclName exts (P.ExternDeclaration _ ident _ _) | isExported ident exts = Just ident
292+ getDeclName exts decl@(P.ExternDeclaration _ ident _ _) | P.isExported exts decl = Just ident
249− getDeclName exts (P.PositionedDeclaration _ d) = getDeclName exts d
293+ getDeclName exts (P.PositionedDeclaration _ _ d) = getDeclName exts d
250− getDeclName _ _ = Nothing
294+ getDeclName _ _ = Nothing
251−
295+
252− isExported :: N.Ident -> Maybe [P.DeclarationRef] -> Bool
296+ dctorNames :: P.Module -> [N.ProperName]
253− isExported ident = maybe True (any exports)
297+ dctorNames m = nub $ concat $ map (P.exportedDctors m) dnames
254− where
298+ where getDataDeclName :: P.Declaration -> Maybe N.ProperName
255− exports :: P.DeclarationRef -> Bool
299+ getDataDeclName (P.DataDeclaration _ name _ _) = Just name
256− exports (P.ValueRef ident') = ident == ident'
300+ getDataDeclName (P.PositionedDeclaration _ _ d) = getDataDeclName d
257− exports (P.PositionedDeclarationRef _ r) = exports r
301+ getDataDeclName _ = Nothing
258− exports _ = False
302+
259−
303+ dnames :: [N.ProperName]
260− identNames :: [P.Module] -> [String]
304+ dnames = (mapMaybe getDataDeclName onlyDataDecls)
261− identNames ms = nub [ show qual
305+
262− | P.Module moduleName ds exts <- ms
306+ onlyDataDecls :: [P.Declaration]
263− , ident <- mapMaybe (getDeclName exts) ds
307+ onlyDataDecls = (filter P.isDataDecl (P.exportedDeclarations m))
264− , qual <- [ P.Qualified Nothing ident
308+
265− , P.Qualified (Just moduleName) ident]
266− ]
267 moduleNames :: [P.Module] -> [String]
309 moduleNames :: [P.Module] -> [String]
268 moduleNames ms = nub [show moduleName | P.Module moduleName _ _ <- ms]
310 moduleNames ms = nub [show moduleName | P.Module moduleName _ _ <- ms]
269
311
@@ -275,7 +317,7 @@ completion = completeWordWithPrev Nothing " \t\n\r" findCompletions
275-- | Compilation options.
317-- | Compilation options.
276--
318--
277options :: P.Options P.Make
319options :: P.Options P.Make
278−options = P.Options False False False Nothing False False P.MakeOptions
320+options = P.Options False False False Nothing False False False P.MakeOptions
279
321
280-- |
322-- |
281-- PSCI monad
323-- PSCI monad
@@ -283,28 +325,26 @@ options = P.Options False False False Nothing False False P.MakeOptions
283newtype PSCI a = PSCI { runPSCI :: InputT (StateT PSCiState IO) a } deriving (Functor, Applicative, Monad)
325newtype PSCI a = PSCI { runPSCI :: InputT (StateT PSCiState IO) a } deriving (Functor, Applicative, Monad)
284
326
285psciIO :: IO a -> PSCI a
327psciIO :: IO a -> PSCI a
286−psciIO io = PSCI (lift (lift io))
328+psciIO io = PSCI . lift $ lift io
287
329
330+newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (ExceptT String IO) a }
288−newtype Make a = Make { unMake :: ErrorT String IO a } deriving (Functor, Applicative, Monad, MonadError String)
331+ deriving (Functor, Applicative, Monad, MonadError String, MonadReader (P.Options P.Make))
289
332
290runMake :: Make a -> IO (Either String a)
333runMake :: Make a -> IO (Either String a)
291−runMake = runErrorT . unMake
334+runMake = runExceptT . flip runReaderT options . unMake
292
335
293makeIO :: IO a -> Make a
336makeIO :: IO a -> Make a
294−makeIO = Make . ErrorT . fmap (either (Left . show) Right) . tryIOError
337+makeIO = Make . lift . ExceptT . fmap (either (Left . show) Right) . tryIOError
295
338
296instance P.MonadMake Make where
339instance P.MonadMake Make where
297 getTimestamp path = makeIO $ do
340 getTimestamp path = makeIO $ do
298 exists <- doesFileExist path
341 exists <- doesFileExist path
299− if exists
342+ traverse (const $ getModificationTime path) $ guard exists
300− then Just <$> getModificationTime path
301− else return Nothing
302− readTextFile path = makeIO $ U.readFile path
343+ readTextFile path = makeIO $ readFile path
303 writeTextFile path text = makeIO $ do
344 writeTextFile path text = makeIO $ do
304 mkdirp path
345 mkdirp path
305− U.writeFile path text
346+ writeFile path text
306− liftError = either throwError return
307− progress s = unless (s == "Compiling $PSCI") $ makeIO . U.putStrLn $ s
347+ progress s = unless (s == "Compiling $PSCI") $ makeIO . putStrLn $ s
308
348
309mkdirp :: FilePath -> IO ()
349mkdirp :: FilePath -> IO ()
310mkdirp = createDirectoryIfMissing True . takeDirectory
350mkdirp = createDirectoryIfMissing True . takeDirectory
@@ -319,13 +359,13 @@ createTemporaryModule exec PSCiState{psciImportedModuleNames = imports, psciLetB
319 importDecl m = P.ImportDeclaration m P.Unqualified Nothing
359 importDecl m = P.ImportDeclaration m P.Unqualified Nothing
320 traceModule = P.ModuleName [P.ProperName "Debug", P.ProperName "Trace"]
360 traceModule = P.ModuleName [P.ProperName "Debug", P.ProperName "Trace"]
321 trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
361 trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
322− itValue = foldl (\x f -> f x) val lets
323 mainValue = P.App trace (P.Var (P.Qualified Nothing (P.Ident "it")))
362 mainValue = P.App trace (P.Var (P.Qualified Nothing (P.Ident "it")))
324− itDecl = P.ValueDeclaration (P.Ident "it") P.Value [] $ Right itValue
363+ itDecl = P.ValueDeclaration (P.Ident "it") P.Value [] $ Right val
325 mainDecl = P.ValueDeclaration (P.Ident "main") P.Value [] $ Right mainValue
364 mainDecl = P.ValueDeclaration (P.Ident "main") P.Value [] $ Right mainValue
326 decls = if exec then [itDecl, mainDecl] else [itDecl]
365 decls = if exec then [itDecl, mainDecl] else [itDecl]
327 in
366 in
328− P.Module moduleName ((importDecl `map` imports) ++ decls) Nothing
367+ P.Module moduleName ((importDecl `map` imports) ++ lets ++ decls) Nothing
368+
329
369
330-- |
370-- |
331-- Makes a volatile module to hold a non-qualified type synonym for a fully-qualified data type declaration.
371-- Makes a volatile module to hold a non-qualified type synonym for a fully-qualified data type declaration.
@@ -363,8 +403,8 @@ handleDeclaration :: P.Expr -> PSCI ()
363handleDeclaration val = do
403handleDeclaration val = do
364 st <- PSCI $ lift get
404 st <- PSCI $ lift get
365 let m = createTemporaryModule True st val
405 let m = createTemporaryModule True st val
366− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
367 let nodeArgs = psciNodeFlags st ++ [indexFile]
406 let nodeArgs = psciNodeFlags st ++ [indexFile]
407+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
368 case e of
408 case e of
369 Left err -> PSCI $ outputStrLn err
409 Left err -> PSCI $ outputStrLn err
370 Right _ -> do
410 Right _ -> do
@@ -380,12 +420,12 @@ handleDeclaration val = do
380-- Takes a let declaration and updates the environment, then run a make. If the declaration fails,
420-- Takes a let declaration and updates the environment, then run a make. If the declaration fails,
381-- restore the pre-let environment.
421-- restore the pre-let environment.
382--
422--
383−handleLet :: (P.Expr -> P.Expr) -> PSCI ()
423+handleLet :: [P.Declaration] -> PSCI ()
384−handleLet l = do
424+handleLet ds = do
385 st <- PSCI $ lift get
425 st <- PSCI $ lift get
386− let st' = updateLets l st
426+ let st' = updateLets ds st
387 let m = createTemporaryModule False st' (P.ObjectLiteral [])
427 let m = createTemporaryModule False st' (P.ObjectLiteral [])
388− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
428+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
389 case e of
429 case e of
390 Left err -> PSCI $ outputStrLn err
430 Left err -> PSCI $ outputStrLn err
391 Right _ -> PSCI $ lift (put st')
431 Right _ -> PSCI $ lift (put st')
@@ -418,7 +458,7 @@ handleImport :: P.ModuleName -> PSCI ()
418handleImport moduleName = do
458handleImport moduleName = do
419 st <- updateImports moduleName <$> PSCI (lift get)
459 st <- updateImports moduleName <$> PSCI (lift get)
420 let m = createTemporaryModuleForImports st
460 let m = createTemporaryModuleForImports st
421− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
461+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
422 case e of
462 case e of
423 Left err -> PSCI $ outputStrLn err
463 Left err -> PSCI $ outputStrLn err
424 Right _ -> do
464 Right _ -> do
@@ -432,7 +472,7 @@ handleTypeOf :: P.Expr -> PSCI ()
432handleTypeOf val = do
472handleTypeOf val = do
433 st <- PSCI $ lift get
473 st <- PSCI $ lift get
434 let m = createTemporaryModule False st val
474 let m = createTemporaryModule False st val
435− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
475+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
436 case e of
476 case e of
437 Left err -> PSCI $ outputStrLn err
477 Left err -> PSCI $ outputStrLn err
438 Right env' ->
478 Right env' ->
@@ -466,7 +506,7 @@ handleBrowse :: P.ModuleName -> PSCI ()
466handleBrowse moduleName = do
506handleBrowse moduleName = do
467 st <- PSCI $ lift get
507 st <- PSCI $ lift get
468 let loadedModules = psciLoadedModules st
508 let loadedModules = psciLoadedModules st
469− env <- psciIO . runMake $ P.make modulesDir options loadedModules []
509+ env <- psciIO . runMake $ P.make modulesDir loadedModules []
470 case env of
510 case env of
471 Left err -> PSCI $ outputStrLn err
511 Left err -> PSCI $ outputStrLn err
472 Right env' ->
512 Right env' ->
@@ -482,7 +522,7 @@ handleKindOf typ = do
482 st <- PSCI $ lift get
522 st <- PSCI $ lift get
483 let m = createTemporaryModuleForKind st typ
523 let m = createTemporaryModuleForKind st typ
484 mName = P.ModuleName [P.ProperName "$PSCI"]
524 mName = P.ModuleName [P.ProperName "$PSCI"]
485− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
525+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
486 case e of
526 case e of
487 Left err -> PSCI $ outputStrLn err
527 Left err -> PSCI $ outputStrLn err
488 Right env' ->
528 Right env' ->
@@ -533,10 +573,12 @@ handleCommand (LoadFile filePath) = do
533 PSCI . outputStrLn $ "Couldn't locate: " ++ filePath
573 PSCI . outputStrLn $ "Couldn't locate: " ++ filePath
534handleCommand Reset = do
574handleCommand Reset = do
535 files <- psciImportedFilenames <$> PSCI (lift get)
575 files <- psciImportedFilenames <$> PSCI (lift get)
536− modulesOrFirstError <- psciIO $ loadAllModules files
576+ PSCI . lift . modify $ \st -> st
537− case modulesOrFirstError of
577+ { psciImportedFilenames = files
538− Left err -> psciIO $ print err >> exitFailure
578+ , psciImportedModuleNames = defaultImports
539− Right modules -> PSCI . lift $ put (PSCiState files defaultImports modules [] [])
579+ , psciLetBindings = []
580+ }
581+ loadAllImportedModules
540handleCommand (TypeOf val) = handleTypeOf val
582handleCommand (TypeOf val) = handleTypeOf val
541handleCommand (KindOf typ) = handleKindOf typ
583handleCommand (KindOf typ) = handleKindOf typ
542handleCommand (Browse moduleName) = handleBrowse moduleName
584handleCommand (Browse moduleName) = handleBrowse moduleName
@@ -550,9 +592,9 @@ loadUserConfig = do
550 exists <- doesFileExist configFile
592 exists <- doesFileExist configFile
551 if exists
593 if exists
552 then do
594 then do
553− ls <- lines <$> U.readFile configFile
595+ ls <- lines <$> readFile configFile
554 case mapM parseCommand ls of
596 case mapM parseCommand ls of
555− Left err -> U.print err >> exitFailure
597+ Left err -> print err >> exitFailure
556 Right cs -> return $ Just cs
598 Right cs -> return $ Just cs
557 else
599 else
558 return Nothing
600 return Nothing
@@ -561,32 +603,33 @@ loadUserConfig = do
561-- The PSCI main loop.
603-- The PSCI main loop.
562--
604--
563loop :: PSCiOptions -> IO ()
605loop :: PSCiOptions -> IO ()
564−loop (PSCiOptions singleLineMode nflags files) = do
606+loop PSCiOptions{..} = do
565 config <- loadUserConfig
607 config <- loadUserConfig
566− modulesOrFirstError <- loadAllModules files
608+ modulesOrFirstError <- loadAllModules psciInputFile
567 case modulesOrFirstError of
609 case modulesOrFirstError of
568 Left err -> print err >> exitFailure
610 Left err -> print err >> exitFailure
569 Right modules -> do
611 Right modules -> do
570 historyFilename <- getHistoryFilename
612 historyFilename <- getHistoryFilename
571 let settings = defaultSettings { historyFile = Just historyFilename }
613 let settings = defaultSettings { historyFile = Just historyFilename }
572− flip evalStateT (PSCiState files defaultImports modules [] nflags) . runInputT (setComplete completion settings) $ do
614+ flip evalStateT (PSCiState psciInputFile defaultImports modules [] psciInputNodeFlags) . runInputT (setComplete completion settings) $ do
573 outputStrLn prologueMessage
615 outputStrLn prologueMessage
574 traverse_ (mapM_ (runPSCI . handleCommand)) config
616 traverse_ (mapM_ (runPSCI . handleCommand)) config
575 go
617 go
576 where
618 where
577 go :: InputT (StateT PSCiState IO) ()
619 go :: InputT (StateT PSCiState IO) ()
578 go = do
620 go = do
579− c <- getCommand singleLineMode
621+ c <- getCommand (not psciMultiLineMode)
580 case c of
622 case c of
581 Left err -> outputStrLn err >> go
623 Left err -> outputStrLn err >> go
582 Right Nothing -> go
624 Right Nothing -> go
583 Right (Just Quit) -> outputStrLn quitMessage
625 Right (Just Quit) -> outputStrLn quitMessage
584− Right (Just c') -> runPSCI (handleCommand c') >> go
626+ Right (Just c') -> runPSCI (loadAllImportedModules >> handleCommand c') >> go
585
627
586−singleLineFlag :: Parser Bool
628+multiLineMode :: Parser Bool
587−singleLineFlag = switch $
629+multiLineMode = switch $
588− long "single-line-mode"
630+ long "multi-line-mode"
631+ <> short 'm'
589− <> Opts.help "Run in single-line mode"
632+ <> Opts.help "Run in multi-line mode (use ^D to terminate commands)"
590
633
591inputFile :: Parser FilePath
634inputFile :: Parser FilePath
592inputFile = strArgument $
635inputFile = strArgument $
@@ -602,9 +645,9 @@ nodeFlagsFlag = option parser $
602 parser = words <$> str
645 parser = words <$> str
603
646
604psciOptions :: Parser PSCiOptions
647psciOptions :: Parser PSCiOptions
605−psciOptions = PSCiOptions <$> singleLineFlag
648+psciOptions = PSCiOptions <$> multiLineMode
606− <*> nodeFlagsFlag
607 <*> many inputFile
649 <*> many inputFile
650+ <*> nodeFlagsFlag
608
651
609main :: IO ()
652main :: IO ()
610main = execParser opts >>= loop
653main = execParser opts >>= loop
psci/Parser.hs+5−5
@@ -34,8 +34,8 @@ import qualified Language.PureScript.Parser.Common as C (mark, same)
34-- Parses PSCI metacommands or expressions input from the user.
34-- Parses PSCI metacommands or expressions input from the user.
35--
35--
36parseCommand :: String -> Either String Command
36parseCommand :: String -> Either String Command
37−parseCommand cmdString =
37+parseCommand cmdString =
38− case splitCommand cmdString of
38+ case splitCommand cmdString of
39 Just ('?', _) -> return Help
39 Just ('?', _) -> return Help
40 Just ('q', _) -> return Quit
40 Just ('q', _) -> return Quit
41 Just ('r', _) -> return Reset
41 Just ('r', _) -> return Reset
@@ -52,7 +52,7 @@ parseCommand cmdString =
52 parseRest p s = either (Left . show) Right $ do
52 parseRest p s = either (Left . show) Right $ do
53 ts <- P.lex "" s
53 ts <- P.lex "" s
54 P.runTokenParser "" (p <* eof) ts
54 P.runTokenParser "" (p <* eof) ts
55−
55+
56 trimEnd :: String -> String
56 trimEnd :: String -> String
57 trimEnd = reverse . dropWhile isSpace . reverse
57 trimEnd = reverse . dropWhile isSpace . reverse
58
58
@@ -68,7 +68,7 @@ parseCommand cmdString =
68 --
68 --
69 psciExpression :: P.TokenParser Command
69 psciExpression :: P.TokenParser Command
70 psciExpression = Expression <$> P.parseValue
70 psciExpression = Expression <$> P.parseValue
71−
71+
72 -- |
72 -- |
73 -- PSCI version of @let@.
73 -- PSCI version of @let@.
74 -- This is essentially let from do-notation.
74 -- This is essentially let from do-notation.
@@ -76,7 +76,7 @@ parseCommand cmdString =
76 -- we actually want the normal @let@.
76 -- we actually want the normal @let@.
77 --
77 --
78 psciLet :: P.TokenParser Command
78 psciLet :: P.TokenParser Command
79− psciLet = Let <$> (P.Let <$> (P.reserved "let" *> P.indented *> manyDecls))
79+ psciLet = Let <$> (P.reserved "let" *> P.indented *> manyDecls)
80 where
80 where
81 manyDecls :: P.TokenParser [P.Declaration]
81 manyDecls :: P.TokenParser [P.Declaration]
82 manyDecls = C.mark (many1 (C.same *> P.parseDeclaration))
82 manyDecls = C.mark (many1 (C.same *> P.parseDeclaration))
purescript.cabal+20−17
@@ -1,5 +1,5 @@
1name: purescript
1name: purescript
2−version: 0.6.2
2+version: 0.6.8
3cabal-version: >=1.8
3cabal-version: >=1.8
4build-type: Simple
4build-type: Simple
5license: MIT
5license: MIT
@@ -31,10 +31,9 @@ library
31 filepath -any,
31 filepath -any,
32 mtl >= 2.1.0 && < 2.3.0,
32 mtl >= 2.1.0 && < 2.3.0,
33 parsec -any,
33 parsec -any,
34− transformers >= 0.3 && < 0.5,
34+ transformers >= 0.4.0 && < 0.5,
35− utf8-string -any,
35+ utf8-string >= 1 && < 2,
36 pattern-arrows >= 0.0.2 && < 0.1,
36 pattern-arrows >= 0.0.2 && < 0.1,
37− monad-unify >= 0.2.2 && < 0.3,
38 file-embed >= 0.0.7 && < 0.0.8,
37 file-embed >= 0.0.7 && < 0.0.8,
39 time -any
38 time -any
40 exposed-modules: Language.PureScript
39 exposed-modules: Language.PureScript
@@ -66,6 +65,7 @@ library
66 Language.PureScript.CoreFn.Meta
65 Language.PureScript.CoreFn.Meta
67 Language.PureScript.CoreFn.Module
66 Language.PureScript.CoreFn.Module
68 Language.PureScript.CoreFn.Traversals
67 Language.PureScript.CoreFn.Traversals
68+ Language.PureScript.Comments
69 Language.PureScript.DeadCodeElimination
69 Language.PureScript.DeadCodeElimination
70 Language.PureScript.Environment
70 Language.PureScript.Environment
71 Language.PureScript.Errors
71 Language.PureScript.Errors
@@ -92,6 +92,7 @@ library
92 Language.PureScript.Sugar.CaseDeclarations
92 Language.PureScript.Sugar.CaseDeclarations
93 Language.PureScript.Sugar.DoNotation
93 Language.PureScript.Sugar.DoNotation
94 Language.PureScript.Sugar.Names
94 Language.PureScript.Sugar.Names
95+ Language.PureScript.Sugar.ObjectWildcards
95 Language.PureScript.Sugar.Operators
96 Language.PureScript.Sugar.Operators
96 Language.PureScript.Sugar.TypeClasses
97 Language.PureScript.Sugar.TypeClasses
97 Language.PureScript.Sugar.TypeDeclarations
98 Language.PureScript.Sugar.TypeDeclarations
@@ -109,67 +110,69 @@ library
109 Language.PureScript.TypeChecker.Unify
110 Language.PureScript.TypeChecker.Unify
110 Language.PureScript.TypeClassDictionaries
111 Language.PureScript.TypeClassDictionaries
111 Language.PureScript.Types
112 Language.PureScript.Types
113+
114+ Control.Monad.Unify
112 exposed: True
115 exposed: True
113 buildable: True
116 buildable: True
114 hs-source-dirs: src
117 hs-source-dirs: src
115 other-modules: Paths_purescript
118 other-modules: Paths_purescript
116− ghc-options: -Wall -fno-warn-warnings-deprecations -O2
119+ ghc-options: -Wall -O2
117
120
118executable psc
121executable psc
119 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
122 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
120 mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
123 mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
121− transformers -any, utf8-string -any
124+ transformers -any
122 main-is: Main.hs
125 main-is: Main.hs
123 buildable: True
126 buildable: True
124 hs-source-dirs: psc
127 hs-source-dirs: psc
125 other-modules:
128 other-modules:
126− ghc-options: -Wall -fno-warn-warnings-deprecations -O2 -fno-warn-unused-do-bind
129+ ghc-options: -Wall -O2 -fno-warn-unused-do-bind
127
130
128executable psc-make
131executable psc-make
129 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
132 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
130 mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
133 mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
131− transformers -any, utf8-string -any
134+ transformers -any
132 main-is: Main.hs
135 main-is: Main.hs
133 buildable: True
136 buildable: True
134 hs-source-dirs: psc-make
137 hs-source-dirs: psc-make
135 other-modules:
138 other-modules:
136− ghc-options: -Wall -fno-warn-warnings-deprecations -O2 -fno-warn-unused-do-bind
139+ ghc-options: -Wall -O2 -fno-warn-unused-do-bind
137
140
138executable psci
141executable psci
139 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
142 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
140 mtl -any, optparse-applicative >= 0.10.0, parsec -any,
143 mtl -any, optparse-applicative >= 0.10.0, parsec -any,
141 haskeline >= 0.7.0.0, purescript -any, transformers -any,
144 haskeline >= 0.7.0.0, purescript -any, transformers -any,
142− utf8-string -any, process -any
145+ process -any
143
146
144 main-is: Main.hs
147 main-is: Main.hs
145 buildable: True
148 buildable: True
146 hs-source-dirs: psci
149 hs-source-dirs: psci
147 other-modules: Commands
150 other-modules: Commands
148 Parser
151 Parser
149− ghc-options: -Wall -fno-warn-warnings-deprecations -O2
152+ ghc-options: -Wall -O2
150
153
151executable psc-docs
154executable psc-docs
152− build-depends: base >=4 && <5, purescript -any, utf8-string -any,
155+ build-depends: base >=4 && <5, purescript -any,
153 optparse-applicative >= 0.10.0, process -any, mtl -any
156 optparse-applicative >= 0.10.0, process -any, mtl -any
154 main-is: Main.hs
157 main-is: Main.hs
155 buildable: True
158 buildable: True
156 hs-source-dirs: psc-docs
159 hs-source-dirs: psc-docs
157 other-modules:
160 other-modules:
158− ghc-options: -Wall -fno-warn-warnings-deprecations -O2
161+ ghc-options: -Wall -O2
159
162
160−executable hierarchy
163+executable psc-hierarchy
161− build-depends: base >=4 && <5, purescript -any, utf8-string -any, optparse-applicative >= 0.10.0,
164+ build-depends: base >=4 && <5, purescript -any, optparse-applicative >= 0.10.0,
162 process -any, mtl -any, parsec -any, filepath -any, directory -any
165 process -any, mtl -any, parsec -any, filepath -any, directory -any
163 main-is: Main.hs
166 main-is: Main.hs
164 buildable: True
167 buildable: True
165 hs-source-dirs: hierarchy
168 hs-source-dirs: hierarchy
166 other-modules:
169 other-modules:
167− ghc-options: -Wall -fno-warn-warnings-deprecations -O2
170+ ghc-options: -Wall -O2
168
171
169test-suite tests
172test-suite tests
170 build-depends: base >=4 && <5, containers -any, directory -any,
173 build-depends: base >=4 && <5, containers -any, directory -any,
171 filepath -any, mtl -any, parsec -any, purescript -any,
174 filepath -any, mtl -any, parsec -any, purescript -any,
172− transformers -any, utf8-string -any, process -any
175+ transformers -any, process -any
173 type: exitcode-stdio-1.0
176 type: exitcode-stdio-1.0
174 main-is: Main.hs
177 main-is: Main.hs
175 buildable: True
178 buildable: True
src/Control/Monad/Unify.hsnew file+155
@@ -0,0 +1,155 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Control.Monad.Unify
4+-- Copyright : (c) Phil Freeman 2013
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- |
12+--
13+--
14+-----------------------------------------------------------------------------
15+
16+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17+{-# LANGUAGE FlexibleInstances #-}
18+{-# LANGUAGE FlexibleContexts #-}
19+{-# LANGUAGE DeriveDataTypeable #-}
20+{-# LANGUAGE MultiParamTypeClasses #-}
21+{-# LANGUAGE FunctionalDependencies #-}
22+{-# LANGUAGE UndecidableInstances #-}
23+{-# LANGUAGE OverloadedStrings #-}
24+
25+module Control.Monad.Unify where
26+
27+import Data.String (IsString)
28+import Data.Monoid
29+
30+import Control.Applicative
31+import Control.Monad.State
32+import Control.Monad.Error.Class
33+
34+import Data.HashMap.Strict as M
35+
36+-- |
37+-- Untyped unification variables
38+--
39+type Unknown = Int
40+
41+-- |
42+-- A type which can contain unification variables
43+--
44+class Partial t where
45+ unknown :: Unknown -> t
46+ isUnknown :: t -> Maybe Unknown
47+ unknowns :: t -> [Unknown]
48+ ($?) :: Substitution t -> t -> t
49+
50+-- |
51+-- Identifies types which support unification
52+--
53+class (Partial t) => Unifiable m t | t -> m where
54+ (=?=) :: t -> t -> UnifyT t m ()
55+
56+-- |
57+-- A substitution maintains a mapping from unification variables to their values
58+--
59+data Substitution t = Substitution { runSubstitution :: M.HashMap Int t }
60+
61+instance (Partial t) => Monoid (Substitution t) where
62+ mempty = Substitution M.empty
63+ s1 `mappend` s2 = Substitution $
64+ M.map (s2 $?) (runSubstitution s1) `M.union`
65+ M.map (s1 $?) (runSubstitution s2)
66+
67+-- |
68+-- State required for type checking
69+--
70+data UnifyState t = UnifyState {
71+ -- |
72+ -- The next fresh unification variable
73+ --
74+ unifyNextVar :: Int
75+ -- |
76+ -- The current substitution
77+ --
78+ , unifyCurrentSubstitution :: Substitution t
79+ }
80+
81+-- |
82+-- An empty @UnifyState@
83+--
84+defaultUnifyState :: (Partial t) => UnifyState t
85+defaultUnifyState = UnifyState 0 mempty
86+
87+-- |
88+-- The type checking monad, which provides the state of the type checker, and error reporting capabilities
89+--
90+newtype UnifyT t m a = UnifyT { unUnify :: (StateT (UnifyState t) m) a }
91+ deriving (Functor, Monad, Applicative, Alternative, MonadPlus)
92+
93+instance (MonadState s m) => MonadState s (UnifyT t m) where
94+ get = UnifyT . lift $ get
95+ put = UnifyT . lift . put
96+
97+instance (MonadError e m) => MonadError e (UnifyT t m) where
98+ throwError = UnifyT . throwError
99+ catchError e f = UnifyT $ catchError (unUnify e) (unUnify . f)
100+
101+-- |
102+-- Run a computation in the Unify monad, failing with an error, or succeeding with a return value and the new next unification variable
103+--
104+runUnify :: UnifyState t -> UnifyT t m a -> m (a, UnifyState t)
105+runUnify s = flip runStateT s . unUnify
106+
107+-- |
108+-- Substitute a single unification variable
109+--
110+substituteOne :: (Partial t) => Unknown -> t -> Substitution t
111+substituteOne u t = Substitution $ M.singleton u t
112+
113+-- |
114+-- Replace a unification variable with the specified value in the current substitution
115+--
116+(=:=) :: (IsString e, Monad m, MonadError e m, Unifiable m t) => Unknown -> t -> UnifyT t m ()
117+(=:=) u t' = do
118+ st <- UnifyT get
119+ let sub = unifyCurrentSubstitution st
120+ let t = sub $? t'
121+ occursCheck u t
122+ let current = sub $? unknown u
123+ case isUnknown current of
124+ Just u1 | u1 == u -> return ()
125+ _ -> current =?= t
126+ UnifyT $ modify $ \s -> s { unifyCurrentSubstitution = substituteOne u t <> unifyCurrentSubstitution s }
127+
128+-- |
129+-- Perform the occurs check, to make sure a unification variable does not occur inside a value
130+--
131+occursCheck :: (IsString e, Monad m, MonadError e m, Partial t) => Unknown -> t -> UnifyT t m ()
132+occursCheck u t =
133+ case isUnknown t of
134+ Nothing -> when (u `elem` unknowns t) $ UnifyT . lift . throwError $ "Occurs check fails"
135+ _ -> return ()
136+
137+-- |
138+-- Generate a fresh untyped unification variable
139+--
140+fresh' :: (Monad m) => UnifyT t m Unknown
141+fresh' = do
142+ st <- UnifyT get
143+ UnifyT $ modify $ \s -> s { unifyNextVar = succ (unifyNextVar s) }
144+ return $ unifyNextVar st
145+
146+-- |
147+-- Generate a fresh unification variable at a specific type
148+--
149+fresh :: (Monad m, Partial t) => UnifyT t m t
150+fresh = do
151+ u <- fresh'
152+ return $ unknown u
153+
154+
155+
src/Language/PureScript.hs+43−37
@@ -13,7 +13,7 @@
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16−{-# LANGUAGE DataKinds, QuasiQuotes, TemplateHaskell #-}
16+{-# LANGUAGE DataKinds, QuasiQuotes, TemplateHaskell, FlexibleContexts #-}
17
17
18module Language.PureScript (module P, compile, compile', RebuildPolicy(..), MonadMake(..), make, prelude) where
18module Language.PureScript (module P, compile, compile', RebuildPolicy(..), MonadMake(..), make, prelude) where
19
19
@@ -22,17 +22,20 @@ import Data.Function (on)
22import Data.List (sortBy, groupBy, intercalate)
22import Data.List (sortBy, groupBy, intercalate)
23import Data.Maybe (fromMaybe)
23import Data.Maybe (fromMaybe)
24import Data.Time.Clock
24import Data.Time.Clock
25+import qualified Data.Traversable as T (traverse)
25import qualified Data.ByteString.UTF8 as BU
26import qualified Data.ByteString.UTF8 as BU
26import qualified Data.Map as M
27import qualified Data.Map as M
27import qualified Data.Set as S
28import qualified Data.Set as S
28
29
29import Control.Applicative
30import Control.Applicative
30import Control.Arrow ((&&&))
31import Control.Arrow ((&&&))
31−import Control.Monad.Error
32+import Control.Monad.Except
33+import Control.Monad.Reader
32
34
33import System.FilePath ((</>))
35import System.FilePath ((</>))
34
36
35import Language.PureScript.AST as P
37import Language.PureScript.AST as P
38+import Language.PureScript.Comments as P
36import Language.PureScript.CodeGen as P
39import Language.PureScript.CodeGen as P
37import Language.PureScript.DeadCodeElimination as P
40import Language.PureScript.DeadCodeElimination as P
38import Language.PureScript.Environment as P
41import Language.PureScript.Environment as P
@@ -70,42 +73,47 @@ import qualified Language.PureScript.Constants as C
70--
73--
71-- * Pretty-print the generated Javascript
74-- * Pretty-print the generated Javascript
72--
75--
76+compile :: (Functor m, Applicative m, MonadError String m, MonadReader (Options Compile) m)
73−compile :: Options Compile -> [Module] -> [String] -> Either String (String, String, Environment)
77+ => [Module] -> [String] -> m (String, String, Environment)
74compile = compile' initEnvironment
78compile = compile' initEnvironment
75
79
80+compile' :: (Functor m, Applicative m, MonadError String m, MonadReader (Options Compile) m)
76−compile' :: Environment -> Options Compile -> [Module] -> [String] -> Either String (String, String, Environment)
81+ => Environment -> [Module] -> [String] -> m (String, String, Environment)
77−compile' env opts ms prefix = do
82+compile' env ms prefix = do
83+ noPrelude <- asks optionsNoPrelude
84+ additional <- asks optionsAdditional
85+ mainModuleIdent <- asks (fmap moduleNameFromString . optionsMain)
78− (sorted, _) <- sortModules $ map importPrim $ if optionsNoPrelude opts then ms else map importPrelude ms
86+ (sorted, _) <- sortModules $ map importPrim $ if noPrelude then ms else map importPrelude ms
79 (desugared, nextVar) <- stringifyErrorStack True $ runSupplyT 0 $ desugar sorted
87 (desugared, nextVar) <- stringifyErrorStack True $ runSupplyT 0 $ desugar sorted
80− (elaborated, env') <- runCheck' opts env $ forM desugared $ typeCheckModule mainModuleIdent
88+ (elaborated, env') <- runCheck' env $ forM desugared $ typeCheckModule mainModuleIdent
81 regrouped <- stringifyErrorStack True $ createBindingGroupsModule . collapseBindingGroupsModule $ elaborated
89 regrouped <- stringifyErrorStack True $ createBindingGroupsModule . collapseBindingGroupsModule $ elaborated
82 let corefn = map (CoreFn.moduleToCoreFn env') regrouped
90 let corefn = map (CoreFn.moduleToCoreFn env') regrouped
83− let entryPoints = moduleNameFromString `map` entryPointModules (optionsAdditional opts)
91+ let entryPoints = moduleNameFromString `map` entryPointModules additional
84 let elim = if null entryPoints then corefn else eliminateDeadCode entryPoints corefn
92 let elim = if null entryPoints then corefn else eliminateDeadCode entryPoints corefn
85 let renamed = renameInModules elim
93 let renamed = renameInModules elim
86− let codeGenModuleNames = moduleNameFromString `map` codeGenModules (optionsAdditional opts)
94+ let codeGenModuleNames = moduleNameFromString `map` codeGenModules additional
87 let modulesToCodeGen = if null codeGenModuleNames then renamed else filter (\(CoreFn.Module mn _ _ _ _) -> mn `elem` codeGenModuleNames) renamed
95 let modulesToCodeGen = if null codeGenModuleNames then renamed else filter (\(CoreFn.Module mn _ _ _ _) -> mn `elem` codeGenModuleNames) renamed
88− let js = evalSupply nextVar $ concat <$> mapM (moduleToJs opts) modulesToCodeGen
96+ js <- concat <$> (evalSupplyT nextVar $ T.traverse moduleToJs modulesToCodeGen)
89 let exts = intercalate "\n" . map (`moduleToPs` env') $ regrouped
97 let exts = intercalate "\n" . map (`moduleToPs` env') $ regrouped
90− js' <- generateMain env' opts js
98+ js' <- generateMain env' js
91 let pjs = unlines $ map ("// " ++) prefix ++ [prettyPrintJS js']
99 let pjs = unlines $ map ("// " ++) prefix ++ [prettyPrintJS js']
92 return (pjs, exts, env')
100 return (pjs, exts, env')
93− where
94− mainModuleIdent = moduleNameFromString <$> optionsMain opts
95
101
96−generateMain :: Environment -> Options Compile -> [JS] -> Either String [JS]
102+generateMain :: (MonadError String m, MonadReader (Options Compile) m) => Environment -> [JS] -> m [JS]
97−generateMain env opts js =
103+generateMain env js = do
104+ main <- asks optionsMain
105+ additional <- asks optionsAdditional
98− case moduleNameFromString <$> optionsMain opts of
106+ case moduleNameFromString <$> main of
99 Just mmi -> do
107 Just mmi -> do
100 when ((mmi, Ident C.main) `M.notMember` names env) $
108 when ((mmi, Ident C.main) `M.notMember` names env) $
101− Left $ show mmi ++ "." ++ C.main ++ " is undefined"
109+ throwError $ show mmi ++ "." ++ C.main ++ " is undefined"
102− return $ js ++ [JSApp (JSAccessor C.main (JSAccessor (moduleNameToJs mmi) (JSVar (browserNamespace (optionsAdditional opts))))) []]
110+ return $ js ++ [JSApp (JSAccessor C.main (JSAccessor (moduleNameToJs mmi) (JSVar (browserNamespace additional)))) []]
103 _ -> return js
111 _ -> return js
104
112
105-- |
113-- |
106-- A type class which collects the IO actions we need to be able to run in "make" mode
114-- A type class which collects the IO actions we need to be able to run in "make" mode
107--
115--
108−class MonadMake m where
116+class (MonadReader (P.Options P.Make) m, MonadError String m) => MonadMake m where
109 -- |
117 -- |
110 -- Get a file timestamp
118 -- Get a file timestamp
111 --
119 --
@@ -121,11 +129,6 @@ class MonadMake m where
121 --
129 --
122 writeTextFile :: FilePath -> String -> m ()
130 writeTextFile :: FilePath -> String -> m ()
123
131
124− -- |
125− -- Report an error
126− --
127− liftError :: Either String a -> m a
128−
129 -- |
132 -- |
130 -- Respond to a progress update
133 -- Respond to a progress update
131 --
134 --
@@ -151,11 +154,13 @@ traverseEither f (Right y) = Right <$> f y
151-- If timestamps have not changed, the externs file can be used to provide the module's types without
154-- If timestamps have not changed, the externs file can be used to provide the module's types without
152-- having to typecheck the module again.
155-- having to typecheck the module again.
153--
156--
157+make :: (Functor m, Applicative m, Monad m, MonadMake m)
154−make :: (Functor m, Applicative m, Monad m, MonadMake m) => FilePath -> Options Make -> [(Either RebuildPolicy FilePath, Module)] -> [String] -> m Environment
158+ => FilePath -> [(Either RebuildPolicy FilePath, Module)] -> [String] -> m Environment
155−make outputDir opts ms prefix = do
159+make outputDir ms prefix = do
160+ noPrelude <- asks optionsNoPrelude
156 let filePathMap = M.fromList (map (\(fp, Module mn _ _) -> (mn, fp)) ms)
161 let filePathMap = M.fromList (map (\(fp, Module mn _ _) -> (mn, fp)) ms)
157
162
158− (sorted, graph) <- liftError $ sortModules $ map importPrim $ if optionsNoPrelude opts then map snd ms else map (importPrelude . snd) ms
163+ (sorted, graph) <- sortModules $ map importPrim $ if noPrelude then map snd ms else map (importPrelude . snd) ms
159
164
160 toRebuild <- foldM (\s (Module moduleName' _ _) -> do
165 toRebuild <- foldM (\s (Module moduleName' _ _) -> do
161 let filePath = runModuleName moduleName'
166 let filePath = runModuleName moduleName'
@@ -175,15 +180,16 @@ make outputDir opts ms prefix = do
175
180
176 marked <- rebuildIfNecessary (reverseDependencies graph) toRebuild sorted
181 marked <- rebuildIfNecessary (reverseDependencies graph) toRebuild sorted
177
182
178− (desugared, nextVar) <- liftError $ stringifyErrorStack True $ runSupplyT 0 $ zip (map fst marked) <$> desugar (map snd marked)
183+ (desugared, nextVar) <- stringifyErrorStack True $ runSupplyT 0 $ zip (map fst marked) <$> desugar (map snd marked)
179
184
180− evalSupplyT nextVar (go initEnvironment desugared)
185+ evalSupplyT nextVar $ go initEnvironment desugared
181
186
182 where
187 where
188+ go :: (Functor m, Applicative m, Monad m, MonadMake m)
183− go :: (Functor m, Applicative m, Monad m, MonadMake m) => Environment -> [(Bool, Module)] -> SupplyT m Environment
189+ => Environment -> [(Bool, Module)] -> SupplyT m Environment
184 go env [] = return env
190 go env [] = return env
185 go env ((False, m) : ms') = do
191 go env ((False, m) : ms') = do
186− (_, env') <- lift . liftError . runCheck' opts env $ typeCheckModule Nothing m
192+ (_, env') <- lift . runCheck' env $ typeCheckModule Nothing m
187
193
188 go env' ms'
194 go env' ms'
189 go env ((True, m@(Module moduleName' _ exps)) : ms') = do
195 go env ((True, m@(Module moduleName' _ exps)) : ms') = do
@@ -193,15 +199,15 @@ make outputDir opts ms prefix = do
193
199
194 lift . progress $ "Compiling " ++ runModuleName moduleName'
200 lift . progress $ "Compiling " ++ runModuleName moduleName'
195
201
196− (Module _ elaborated _, env') <- lift . liftError . runCheck' opts env $ typeCheckModule Nothing m
202+ (Module _ elaborated _, env') <- lift . runCheck' env $ typeCheckModule Nothing m
197
203
198− regrouped <- lift . liftError . stringifyErrorStack True . createBindingGroups moduleName' . collapseBindingGroups $ elaborated
204+ regrouped <- stringifyErrorStack True . createBindingGroups moduleName' . collapseBindingGroups $ elaborated
199
205
200 let mod' = Module moduleName' regrouped exps
206 let mod' = Module moduleName' regrouped exps
201 let corefn = CoreFn.moduleToCoreFn env' mod'
207 let corefn = CoreFn.moduleToCoreFn env' mod'
202 let [renamed] = renameInModules [corefn]
208 let [renamed] = renameInModules [corefn]
203
209
204− pjs <- prettyPrintJS <$> moduleToJs opts renamed
210+ pjs <- prettyPrintJS <$> moduleToJs renamed
205 let js = unlines $ map ("// " ++) prefix ++ [pjs]
211 let js = unlines $ map ("// " ++) prefix ++ [pjs]
206 let exts = unlines $ map ("-- " ++) prefix ++ [moduleToPs mod' env']
212 let exts = unlines $ map ("-- " ++) prefix ++ [moduleToPs mod' env']
207
213
@@ -219,10 +225,10 @@ make outputDir opts ms prefix = do
219 rebuildIfNecessary graph toRebuild (Module moduleName' _ _ : ms') = do
225 rebuildIfNecessary graph toRebuild (Module moduleName' _ _ : ms') = do
220 let externsFile = outputDir </> runModuleName moduleName' </> "externs.purs"
226 let externsFile = outputDir </> runModuleName moduleName' </> "externs.purs"
221 externs <- readTextFile externsFile
227 externs <- readTextFile externsFile
222− externsModules <- liftError . fmap (map snd) . either (Left . show) Right $ P.parseModulesFromFiles id [(externsFile, externs)]
228+ externsModules <- fmap (map snd) . either (throwError . show) return $ P.parseModulesFromFiles id [(externsFile, externs)]
223 case externsModules of
229 case externsModules of
224 [m'@(Module moduleName'' _ _)] | moduleName'' == moduleName' -> (:) (False, m') <$> rebuildIfNecessary graph toRebuild ms'
230 [m'@(Module moduleName'' _ _)] | moduleName'' == moduleName' -> (:) (False, m') <$> rebuildIfNecessary graph toRebuild ms'
225− _ -> liftError . Left $ "Externs file " ++ externsFile ++ " was invalid"
231+ _ -> throwError $ "Externs file " ++ externsFile ++ " was invalid"
226
232
227reverseDependencies :: ModuleGraph -> M.Map ModuleName [ModuleName]
233reverseDependencies :: ModuleGraph -> M.Map ModuleName [ModuleName]
228reverseDependencies g = combine [ (dep, mn) | (mn, deps) <- g, dep <- deps ]
234reverseDependencies g = combine [ (dep, mn) | (mn, deps) <- g, dep <- deps ]
@@ -239,7 +245,7 @@ addDefaultImport toImport m@(Module mn decls exps) =
239 else Module mn (ImportDeclaration toImport Unqualified Nothing : decls) exps
245 else Module mn (ImportDeclaration toImport Unqualified Nothing : decls) exps
240 where
246 where
241 isExistingImport (ImportDeclaration mn' _ _) | mn' == toImport = True
247 isExistingImport (ImportDeclaration mn' _ _) | mn' == toImport = True
242− isExistingImport (PositionedDeclaration _ d) = isExistingImport d
248+ isExistingImport (PositionedDeclaration _ _ d) = isExistingImport d
243 isExistingImport _ = False
249 isExistingImport _ = False
244
250
245importPrim :: Module -> Module
251importPrim :: Module -> Module
src/Language/PureScript/AST/Binders.hs+3−2
@@ -20,6 +20,7 @@ import qualified Data.Data as D
20
20
21import Language.PureScript.AST.SourcePos
21import Language.PureScript.AST.SourcePos
22import Language.PureScript.Names
22import Language.PureScript.Names
23+import Language.PureScript.Comments
23
24
24-- |
25-- |
25-- Data type for binders
26-- Data type for binders
@@ -68,7 +69,7 @@ data Binder
68 -- |
69 -- |
69 -- A binder with source position information
70 -- A binder with source position information
70 --
71 --
71− | PositionedBinder SourceSpan Binder deriving (Show, D.Data, D.Typeable)
72+ | PositionedBinder SourceSpan [Comment] Binder deriving (Show, D.Data, D.Typeable)
72
73
73-- |
74-- |
74-- Collect all names introduced in binders in an expression
75-- Collect all names introduced in binders in an expression
@@ -82,5 +83,5 @@ binderNames = go []
82 go ns (ArrayBinder bs) = foldl go ns bs
83 go ns (ArrayBinder bs) = foldl go ns bs
83 go ns (ConsBinder b1 b2) = go (go ns b1) b2
84 go ns (ConsBinder b1 b2) = go (go ns b1) b2
84 go ns (NamedBinder name b) = go (name : ns) b
85 go ns (NamedBinder name b) = go (name : ns) b
85− go ns (PositionedBinder _ b) = go ns b
86+ go ns (PositionedBinder _ _ b) = go ns b
86 go ns _ = ns
87 go ns _ = ns
src/Language/PureScript/AST/Declarations.hs+60−21
@@ -25,6 +25,7 @@ import Language.PureScript.Types
25import Language.PureScript.Names
25import Language.PureScript.Names
26import Language.PureScript.Kinds
26import Language.PureScript.Kinds
27import Language.PureScript.TypeClassDictionaries
27import Language.PureScript.TypeClassDictionaries
28+import Language.PureScript.Comments
28import Language.PureScript.CodeGen.JS.AST
29import Language.PureScript.CodeGen.JS.AST
29import Language.PureScript.Environment
30import Language.PureScript.Environment
30
31
@@ -34,27 +35,32 @@ import Language.PureScript.Environment
34--
35--
35data Module = Module ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)
36data Module = Module ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)
36
37
38+-- | Return a module's name.
39+getModuleName :: Module -> ModuleName
40+getModuleName (Module name _ _) = name
41+
37-- |
42-- |
38-- Test if a declaration is exported, given a module's export list.
43-- Test if a declaration is exported, given a module's export list.
39--
44--
40isExported :: Maybe [DeclarationRef] -> Declaration -> Bool
45isExported :: Maybe [DeclarationRef] -> Declaration -> Bool
41isExported Nothing _ = True
46isExported Nothing _ = True
42isExported _ TypeInstanceDeclaration{} = True
47isExported _ TypeInstanceDeclaration{} = True
43−isExported exps (PositionedDeclaration _ d) = isExported exps d
48+isExported exps (PositionedDeclaration _ _ d) = isExported exps d
44isExported (Just exps) decl = any (matches decl) exps
49isExported (Just exps) decl = any (matches decl) exps
45 where
50 where
46 matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
51 matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
52+ matches (ValueDeclaration ident _ _ _) (ValueRef ident') = ident == ident'
47 matches (ExternDeclaration _ ident _ _) (ValueRef ident') = ident == ident'
53 matches (ExternDeclaration _ ident _ _) (ValueRef ident') = ident == ident'
48 matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
54 matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
49 matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
55 matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
50 matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
56 matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
51 matches (TypeClassDeclaration ident _ _ _) (TypeClassRef ident') = ident == ident'
57 matches (TypeClassDeclaration ident _ _ _) (TypeClassRef ident') = ident == ident'
52− matches (PositionedDeclaration _ d) r = d `matches` r
58+ matches (PositionedDeclaration _ _ d) r = d `matches` r
53− matches d (PositionedDeclarationRef _ r) = d `matches` r
59+ matches d (PositionedDeclarationRef _ _ r) = d `matches` r
54 matches _ _ = False
60 matches _ _ = False
55
61
56exportedDeclarations :: Module -> [Declaration]
62exportedDeclarations :: Module -> [Declaration]
57−exportedDeclarations (Module _ decls exps) = filter (isExported exps) decls
63+exportedDeclarations (Module _ decls exps) = filter (isExported exps) (flattenDecls decls)
58
64
59-- |
65-- |
60-- Test if a data constructor for a given type is exported, given a module's export list.
66-- Test if a data constructor for a given type is exported, given a module's export list.
@@ -63,7 +69,7 @@ isDctorExported :: ProperName -> Maybe [DeclarationRef] -> ProperName -> Bool
63isDctorExported _ Nothing _ = True
69isDctorExported _ Nothing _ = True
64isDctorExported ident (Just exps) ctor = test `any` exps
70isDctorExported ident (Just exps) ctor = test `any` exps
65 where
71 where
66− test (PositionedDeclarationRef _ d) = test d
72+ test (PositionedDeclarationRef _ _ d) = test d
67 test (TypeRef ident' Nothing) = ident == ident'
73 test (TypeRef ident' Nothing) = ident == ident'
68 test (TypeRef ident' (Just ctors)) = ident == ident' && ctor `elem` ctors
74 test (TypeRef ident' (Just ctors)) = ident == ident' && ctor `elem` ctors
69 test _ = False
75 test _ = False
@@ -75,8 +81,9 @@ exportedDctors :: Module -> ProperName -> [ProperName]
75exportedDctors (Module _ decls exps) ident =
81exportedDctors (Module _ decls exps) ident =
76 filter (isDctorExported ident exps) dctors
82 filter (isDctorExported ident exps) dctors
77 where
83 where
78− dctors = concatMap getDctors decls
84+ dctors = concatMap getDctors (flattenDecls decls)
79 getDctors (DataDeclaration _ _ _ ctors) = map fst ctors
85 getDctors (DataDeclaration _ _ _ ctors) = map fst ctors
86+ getDctors (PositionedDeclaration _ _ d) = getDctors d
80 getDctors _ = []
87 getDctors _ = []
81
88
82-- |
89-- |
@@ -102,7 +109,7 @@ data DeclarationRef
102 -- |
109 -- |
103 -- A declaration reference with source position information
110 -- A declaration reference with source position information
104 --
111 --
105− | PositionedDeclarationRef SourceSpan DeclarationRef
112+ | PositionedDeclarationRef SourceSpan [Comment] DeclarationRef
106 deriving (Show, D.Data, D.Typeable)
113 deriving (Show, D.Data, D.Typeable)
107
114
108instance Eq DeclarationRef where
115instance Eq DeclarationRef where
@@ -110,8 +117,8 @@ instance Eq DeclarationRef where
110 (ValueRef name) == (ValueRef name') = name == name'
117 (ValueRef name) == (ValueRef name') = name == name'
111 (TypeClassRef name) == (TypeClassRef name') = name == name'
118 (TypeClassRef name) == (TypeClassRef name') = name == name'
112 (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'
119 (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'
113− (PositionedDeclarationRef _ r) == r' = r == r'
120+ (PositionedDeclarationRef _ _ r) == r' = r == r'
114− r == (PositionedDeclarationRef _ r') = r == r'
121+ r == (PositionedDeclarationRef _ _ r') = r == r'
115 _ == _ = False
122 _ == _ = False
116
123
117-- |
124-- |
@@ -192,7 +199,7 @@ data Declaration
192 -- |
199 -- |
193 -- A declaration with source position information
200 -- A declaration with source position information
194 --
201 --
195− | PositionedDeclaration SourceSpan Declaration
202+ | PositionedDeclaration SourceSpan [Comment] Declaration
196 deriving (Show, D.Data, D.Typeable)
203 deriving (Show, D.Data, D.Typeable)
197
204
198-- |
205-- |
@@ -200,7 +207,7 @@ data Declaration
200--
207--
201isValueDecl :: Declaration -> Bool
208isValueDecl :: Declaration -> Bool
202isValueDecl ValueDeclaration{} = True
209isValueDecl ValueDeclaration{} = True
203−isValueDecl (PositionedDeclaration _ d) = isValueDecl d
210+isValueDecl (PositionedDeclaration _ _ d) = isValueDecl d
204isValueDecl _ = False
211isValueDecl _ = False
205
212
206-- |
213-- |
@@ -209,7 +216,7 @@ isValueDecl _ = False
209isDataDecl :: Declaration -> Bool
216isDataDecl :: Declaration -> Bool
210isDataDecl DataDeclaration{} = True
217isDataDecl DataDeclaration{} = True
211isDataDecl TypeSynonymDeclaration{} = True
218isDataDecl TypeSynonymDeclaration{} = True
212−isDataDecl (PositionedDeclaration _ d) = isDataDecl d
219+isDataDecl (PositionedDeclaration _ _ d) = isDataDecl d
213isDataDecl _ = False
220isDataDecl _ = False
214
221
215-- |
222-- |
@@ -217,7 +224,7 @@ isDataDecl _ = False
217--
224--
218isImportDecl :: Declaration -> Bool
225isImportDecl :: Declaration -> Bool
219isImportDecl ImportDeclaration{} = True
226isImportDecl ImportDeclaration{} = True
220−isImportDecl (PositionedDeclaration _ d) = isImportDecl d
227+isImportDecl (PositionedDeclaration _ _ d) = isImportDecl d
221isImportDecl _ = False
228isImportDecl _ = False
222
229
223-- |
230-- |
@@ -225,7 +232,7 @@ isImportDecl _ = False
225--
232--
226isExternDataDecl :: Declaration -> Bool
233isExternDataDecl :: Declaration -> Bool
227isExternDataDecl ExternDataDeclaration{} = True
234isExternDataDecl ExternDataDeclaration{} = True
228−isExternDataDecl (PositionedDeclaration _ d) = isExternDataDecl d
235+isExternDataDecl (PositionedDeclaration _ _ d) = isExternDataDecl d
229isExternDataDecl _ = False
236isExternDataDecl _ = False
230
237
231-- |
238-- |
@@ -233,7 +240,7 @@ isExternDataDecl _ = False
233--
240--
234isExternInstanceDecl :: Declaration -> Bool
241isExternInstanceDecl :: Declaration -> Bool
235isExternInstanceDecl ExternInstanceDeclaration{} = True
242isExternInstanceDecl ExternInstanceDeclaration{} = True
236−isExternInstanceDecl (PositionedDeclaration _ d) = isExternInstanceDecl d
243+isExternInstanceDecl (PositionedDeclaration _ _ d) = isExternInstanceDecl d
237isExternInstanceDecl _ = False
244isExternInstanceDecl _ = False
238
245
239-- |
246-- |
@@ -241,7 +248,7 @@ isExternInstanceDecl _ = False
241--
248--
242isFixityDecl :: Declaration -> Bool
249isFixityDecl :: Declaration -> Bool
243isFixityDecl FixityDeclaration{} = True
250isFixityDecl FixityDeclaration{} = True
244−isFixityDecl (PositionedDeclaration _ d) = isFixityDecl d
251+isFixityDecl (PositionedDeclaration _ _ d) = isFixityDecl d
245isFixityDecl _ = False
252isFixityDecl _ = False
246
253
247-- |
254-- |
@@ -249,7 +256,7 @@ isFixityDecl _ = False
249--
256--
250isExternDecl :: Declaration -> Bool
257isExternDecl :: Declaration -> Bool
251isExternDecl ExternDeclaration{} = True
258isExternDecl ExternDeclaration{} = True
252−isExternDecl (PositionedDeclaration _ d) = isExternDecl d
259+isExternDecl (PositionedDeclaration _ _ d) = isExternDecl d
253isExternDecl _ = False
260isExternDecl _ = False
254
261
255-- |
262-- |
@@ -258,9 +265,17 @@ isExternDecl _ = False
258isTypeClassDeclaration :: Declaration -> Bool
265isTypeClassDeclaration :: Declaration -> Bool
259isTypeClassDeclaration TypeClassDeclaration{} = True
266isTypeClassDeclaration TypeClassDeclaration{} = True
260isTypeClassDeclaration TypeInstanceDeclaration{} = True
267isTypeClassDeclaration TypeInstanceDeclaration{} = True
261−isTypeClassDeclaration (PositionedDeclaration _ d) = isTypeClassDeclaration d
268+isTypeClassDeclaration (PositionedDeclaration _ _ d) = isTypeClassDeclaration d
262isTypeClassDeclaration _ = False
269isTypeClassDeclaration _ = False
263
270
271+-- |
272+-- Recursively flatten data binding groups in the list of declarations
273+flattenDecls :: [Declaration] -> [Declaration]
274+flattenDecls = concatMap flattenOne
275+ where flattenOne :: Declaration -> [Declaration]
276+ flattenOne (DataBindingGroupDeclaration decls) = concatMap flattenOne decls
277+ flattenOne d = [d]
278+
264-- |
279-- |
265-- A guard is just a boolean-valued expression that appears alongside a set of binders
280-- A guard is just a boolean-valued expression that appears alongside a set of binders
266--
281--
@@ -290,13 +305,18 @@ data Expr
290 -- Binary operator application. During the rebracketing phase of desugaring, this data constructor
305 -- Binary operator application. During the rebracketing phase of desugaring, this data constructor
291 -- will be removed.
306 -- will be removed.
292 --
307 --
293− | BinaryNoParens (Qualified Ident) Expr Expr
308+ | BinaryNoParens Expr Expr Expr
294 -- |
309 -- |
295 -- Explicit parentheses. During the rebracketing phase of desugaring, this data constructor
310 -- Explicit parentheses. During the rebracketing phase of desugaring, this data constructor
296 -- will be removed.
311 -- will be removed.
297 --
312 --
298 | Parens Expr
313 | Parens Expr
299 -- |
314 -- |
315+ -- Operator section. This will be removed during desugaring and replaced with a partially applied
316+ -- operator or lambda to flip the arguments.
317+ --
318+ | OperatorSection Expr (Either Expr Expr)
319+ -- |
300 -- An array literal
320 -- An array literal
301 --
321 --
302 | ArrayLiteral [Expr]
322 | ArrayLiteral [Expr]
@@ -305,6 +325,16 @@ data Expr
305 --
325 --
306 | ObjectLiteral [(String, Expr)]
326 | ObjectLiteral [(String, Expr)]
307 -- |
327 -- |
328+ -- An object constructor (object literal with underscores). This will be removed during
329+ -- desugaring and expanded into a lambda that returns an object literal.
330+ --
331+ | ObjectConstructor [(String, Maybe Expr)]
332+ -- |
333+ -- An object property getter (e.g. `_.x`). This will be removed during
334+ -- desugaring and expanded into a lambda that reads a property from an object.
335+ --
336+ | ObjectGetter String
337+ -- |
308 -- An record property accessor expression
338 -- An record property accessor expression
309 --
339 --
310 | Accessor String Expr
340 | Accessor String Expr
@@ -313,6 +343,11 @@ data Expr
313 --
343 --
314 | ObjectUpdate Expr [(String, Expr)]
344 | ObjectUpdate Expr [(String, Expr)]
315 -- |
345 -- |
346+ -- Partial record updater. This will be removed during desugaring and
347+ -- expanded into a lambda that returns an object update.
348+ --
349+ | ObjectUpdater (Maybe Expr) [(String, Maybe Expr)]
350+ -- |
316 -- Function introduction
351 -- Function introduction
317 --
352 --
318 | Abs (Either Ident Binder) Expr
353 | Abs (Either Ident Binder) Expr
@@ -363,13 +398,17 @@ data Expr
363 --
398 --
364 | TypeClassDictionary Bool Constraint [TypeClassDictionaryInScope]
399 | TypeClassDictionary Bool Constraint [TypeClassDictionaryInScope]
365 -- |
400 -- |
401+ -- A typeclass dictionary accessor, the implementation is left unspecified until CoreFn desugaring.
402+ --
403+ | TypeClassDictionaryAccessor (Qualified ProperName) Ident
404+ -- |
366 -- A placeholder for a superclass dictionary to be turned into a TypeClassDictionary during typechecking
405 -- A placeholder for a superclass dictionary to be turned into a TypeClassDictionary during typechecking
367 --
406 --
368 | SuperClassDictionary (Qualified ProperName) [Type]
407 | SuperClassDictionary (Qualified ProperName) [Type]
369 -- |
408 -- |
370 -- A value with source position information
409 -- A value with source position information
371 --
410 --
372− | PositionedValue SourceSpan Expr deriving (Show, D.Data, D.Typeable)
411+ | PositionedValue SourceSpan [Comment] Expr deriving (Show, D.Data, D.Typeable)
373
412
374-- |
413-- |
375-- An alternative in a case statement
414-- An alternative in a case statement
@@ -404,4 +443,4 @@ data DoNotationElement
404 -- |
443 -- |
405 -- A do notation element with source position information
444 -- A do notation element with source position information
406 --
445 --
407− | PositionedDoNotationElement SourceSpan DoNotationElement deriving (Show, D.Data, D.Typeable)
446+ | PositionedDoNotationElement SourceSpan [Comment] DoNotationElement deriving (Show, D.Data, D.Typeable)
src/Language/PureScript/AST/SourcePos.hs+2−2
@@ -48,6 +48,6 @@ data SourceSpan = SourceSpan
48 --
48 --
49 , spanEnd :: SourcePos
49 , spanEnd :: SourcePos
50 } deriving (D.Data, D.Typeable)
50 } deriving (D.Data, D.Typeable)
51−
51+
52instance Show SourceSpan where
52instance Show SourceSpan where
53− show sp = spanName sp ++ " " ++ show (spanStart sp) ++ " - " ++ show (spanEnd sp)
53+ show sp = spanName sp ++ " " ++ show (spanStart sp) ++ " - " ++ show (spanEnd sp)
src/Language/PureScript/AST/Traversals.hs+56−32
@@ -15,10 +15,11 @@
15module Language.PureScript.AST.Traversals where
15module Language.PureScript.AST.Traversals where
16
16
17import Data.Monoid (Monoid(..), mconcat)
17import Data.Monoid (Monoid(..), mconcat)
18+import Data.Maybe (mapMaybe)
18
19
19import Control.Applicative
20import Control.Applicative
20import Control.Monad
21import Control.Monad
21−import Control.Arrow ((***), (+++))
22+import Control.Arrow ((***), (+++), second)
22
23
23import Language.PureScript.AST.Binders
24import Language.PureScript.AST.Binders
24import Language.PureScript.AST.Declarations
25import Language.PureScript.AST.Declarations
@@ -37,18 +38,22 @@ everywhereOnValues f g h = (f', g', h')
37 f' (BindingGroupDeclaration ds) = f (BindingGroupDeclaration (map (\(name, nameKind, val) -> (name, nameKind, g' val)) ds))
38 f' (BindingGroupDeclaration ds) = f (BindingGroupDeclaration (map (\(name, nameKind, val) -> (name, nameKind, g' val)) ds))
38 f' (TypeClassDeclaration name args implies ds) = f (TypeClassDeclaration name args implies (map f' ds))
39 f' (TypeClassDeclaration name args implies ds) = f (TypeClassDeclaration name args implies (map f' ds))
39 f' (TypeInstanceDeclaration name cs className args ds) = f (TypeInstanceDeclaration name cs className args (map f' ds))
40 f' (TypeInstanceDeclaration name cs className args ds) = f (TypeInstanceDeclaration name cs className args (map f' ds))
40− f' (PositionedDeclaration pos d) = f (PositionedDeclaration pos (f' d))
41+ f' (PositionedDeclaration pos com d) = f (PositionedDeclaration pos com (f' d))
41 f' other = f other
42 f' other = f other
42
43
43 g' :: Expr -> Expr
44 g' :: Expr -> Expr
44 g' (UnaryMinus v) = g (UnaryMinus (g' v))
45 g' (UnaryMinus v) = g (UnaryMinus (g' v))
45− g' (BinaryNoParens op v1 v2) = g (BinaryNoParens op (g' v1) (g' v2))
46+ g' (BinaryNoParens op v1 v2) = g (BinaryNoParens (g' op) (g' v1) (g' v2))
46 g' (Parens v) = g (Parens (g' v))
47 g' (Parens v) = g (Parens (g' v))
48+ g' (OperatorSection op (Left v)) = g (OperatorSection (g' op) (Left $ g' v))
49+ g' (OperatorSection op (Right v)) = g (OperatorSection (g' op) (Right $ g' v))
47 g' (ArrayLiteral vs) = g (ArrayLiteral (map g' vs))
50 g' (ArrayLiteral vs) = g (ArrayLiteral (map g' vs))
48 g' (ObjectLiteral vs) = g (ObjectLiteral (map (fmap g') vs))
51 g' (ObjectLiteral vs) = g (ObjectLiteral (map (fmap g') vs))
52+ g' (ObjectConstructor vs) = g (ObjectConstructor (map (second (fmap g')) vs))
49 g' (TypeClassDictionaryConstructorApp name v) = g (TypeClassDictionaryConstructorApp name (g' v))
53 g' (TypeClassDictionaryConstructorApp name v) = g (TypeClassDictionaryConstructorApp name (g' v))
50 g' (Accessor prop v) = g (Accessor prop (g' v))
54 g' (Accessor prop v) = g (Accessor prop (g' v))
51 g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))
55 g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))
56+ g' (ObjectUpdater obj vs) = g (ObjectUpdater (fmap g' obj) (map (second (fmap g')) vs))
52 g' (Abs name v) = g (Abs name (g' v))
57 g' (Abs name v) = g (Abs name (g' v))
53 g' (App v1 v2) = g (App (g' v1) (g' v2))
58 g' (App v1 v2) = g (App (g' v1) (g' v2))
54 g' (IfThenElse v1 v2 v3) = g (IfThenElse (g' v1) (g' v2) (g' v3))
59 g' (IfThenElse v1 v2 v3) = g (IfThenElse (g' v1) (g' v2) (g' v3))
@@ -56,7 +61,7 @@ everywhereOnValues f g h = (f', g', h')
56 g' (TypedValue check v ty) = g (TypedValue check (g' v) ty)
61 g' (TypedValue check v ty) = g (TypedValue check (g' v) ty)
57 g' (Let ds v) = g (Let (map f' ds) (g' v))
62 g' (Let ds v) = g (Let (map f' ds) (g' v))
58 g' (Do es) = g (Do (map handleDoNotationElement es))
63 g' (Do es) = g (Do (map handleDoNotationElement es))
59− g' (PositionedValue pos v) = g (PositionedValue pos (g' v))
64+ g' (PositionedValue pos com v) = g (PositionedValue pos com (g' v))
60 g' other = g other
65 g' other = g other
61
66
62 h' :: Binder -> Binder
67 h' :: Binder -> Binder
@@ -65,7 +70,7 @@ everywhereOnValues f g h = (f', g', h')
65 h' (ArrayBinder bs) = h (ArrayBinder (map h' bs))
70 h' (ArrayBinder bs) = h (ArrayBinder (map h' bs))
66 h' (ConsBinder b1 b2) = h (ConsBinder (h' b1) (h' b2))
71 h' (ConsBinder b1 b2) = h (ConsBinder (h' b1) (h' b2))
67 h' (NamedBinder name b) = h (NamedBinder name (h' b))
72 h' (NamedBinder name b) = h (NamedBinder name (h' b))
68− h' (PositionedBinder pos b) = h (PositionedBinder pos (h' b))
73+ h' (PositionedBinder pos com b) = h (PositionedBinder pos com (h' b))
69 h' other = h other
74 h' other = h other
70
75
71 handleCaseAlternative :: CaseAlternative -> CaseAlternative
76 handleCaseAlternative :: CaseAlternative -> CaseAlternative
@@ -78,8 +83,7 @@ everywhereOnValues f g h = (f', g', h')
78 handleDoNotationElement (DoNotationValue v) = DoNotationValue (g' v)
83 handleDoNotationElement (DoNotationValue v) = DoNotationValue (g' v)
79 handleDoNotationElement (DoNotationBind b v) = DoNotationBind (h' b) (g' v)
84 handleDoNotationElement (DoNotationBind b v) = DoNotationBind (h' b) (g' v)
80 handleDoNotationElement (DoNotationLet ds) = DoNotationLet (map f' ds)
85 handleDoNotationElement (DoNotationLet ds) = DoNotationLet (map f' ds)
81− handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos (handleDoNotationElement e)
86+ handleDoNotationElement (PositionedDoNotationElement pos com e) = PositionedDoNotationElement pos com (handleDoNotationElement e)
82−
83
87
84everywhereOnValuesTopDownM :: (Functor m, Applicative m, Monad m) =>
88everywhereOnValuesTopDownM :: (Functor m, Applicative m, Monad m) =>
85 (Declaration -> m Declaration) ->
89 (Declaration -> m Declaration) ->
@@ -93,17 +97,21 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
93 f' (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> (g val >>= g')) ds
97 f' (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> (g val >>= g')) ds
94 f' (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f' <=< f) ds
98 f' (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f' <=< f) ds
95 f' (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f' <=< f) ds
99 f' (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f' <=< f) ds
96− f' (PositionedDeclaration pos d) = PositionedDeclaration pos <$> (f d >>= f')
100+ f' (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> (f d >>= f')
97 f' other = f other
101 f' other = f other
98
102
99 g' (UnaryMinus v) = UnaryMinus <$> (g v >>= g')
103 g' (UnaryMinus v) = UnaryMinus <$> (g v >>= g')
100− g' (BinaryNoParens op v1 v2) = BinaryNoParens op <$> (g v1 >>= g') <*> (g v2 >>= g')
104+ g' (BinaryNoParens op v1 v2) = BinaryNoParens <$> (g op >>= g') <*> (g v1 >>= g') <*> (g v2 >>= g')
101 g' (Parens v) = Parens <$> (g v >>= g')
105 g' (Parens v) = Parens <$> (g v >>= g')
106+ g' (OperatorSection op (Left v)) = OperatorSection <$> (g op >>= g') <*> (Left <$> (g v >>= g'))
107+ g' (OperatorSection op (Right v)) = OperatorSection <$> (g op >>= g') <*> (Right <$> (g v >>= g'))
102 g' (ArrayLiteral vs) = ArrayLiteral <$> mapM (g' <=< g) vs
108 g' (ArrayLiteral vs) = ArrayLiteral <$> mapM (g' <=< g) vs
103 g' (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g' <=< g)) vs
109 g' (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g' <=< g)) vs
110+ g' (ObjectConstructor vs) = ObjectConstructor <$> mapM (sndM $ maybeM (g' <=< g)) vs
104 g' (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g v >>= g')
111 g' (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g v >>= g')
105 g' (Accessor prop v) = Accessor prop <$> (g v >>= g')
112 g' (Accessor prop v) = Accessor prop <$> (g v >>= g')
106 g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> mapM (sndM (g' <=< g)) vs
113 g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> mapM (sndM (g' <=< g)) vs
114+ g' (ObjectUpdater obj vs) = ObjectUpdater <$> (maybeM g obj >>= maybeM g') <*> mapM (sndM $ maybeM (g' <=< g)) vs
107 g' (Abs name v) = Abs name <$> (g v >>= g')
115 g' (Abs name v) = Abs name <$> (g v >>= g')
108 g' (App v1 v2) = App <$> (g v1 >>= g') <*> (g v2 >>= g')
116 g' (App v1 v2) = App <$> (g v1 >>= g') <*> (g v2 >>= g')
109 g' (IfThenElse v1 v2 v3) = IfThenElse <$> (g v1 >>= g') <*> (g v2 >>= g') <*> (g v3 >>= g')
117 g' (IfThenElse v1 v2 v3) = IfThenElse <$> (g v1 >>= g') <*> (g v2 >>= g') <*> (g v3 >>= g')
@@ -111,7 +119,7 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
111 g' (TypedValue check v ty) = TypedValue check <$> (g v >>= g') <*> pure ty
119 g' (TypedValue check v ty) = TypedValue check <$> (g v >>= g') <*> pure ty
112 g' (Let ds v) = Let <$> mapM (f' <=< f) ds <*> (g v >>= g')
120 g' (Let ds v) = Let <$> mapM (f' <=< f) ds <*> (g v >>= g')
113 g' (Do es) = Do <$> mapM handleDoNotationElement es
121 g' (Do es) = Do <$> mapM handleDoNotationElement es
114− g' (PositionedValue pos v) = PositionedValue pos <$> (g v >>= g')
122+ g' (PositionedValue pos com v) = PositionedValue pos com <$> (g v >>= g')
115 g' other = g other
123 g' other = g other
116
124
117 h' (ConstructorBinder ctor bs) = ConstructorBinder ctor <$> mapM (h' <=< h) bs
125 h' (ConstructorBinder ctor bs) = ConstructorBinder ctor <$> mapM (h' <=< h) bs
@@ -119,7 +127,7 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
119 h' (ArrayBinder bs) = ArrayBinder <$> mapM (h' <=< h) bs
127 h' (ArrayBinder bs) = ArrayBinder <$> mapM (h' <=< h) bs
120 h' (ConsBinder b1 b2) = ConsBinder <$> (h b1 >>= h') <*> (h b2 >>= h')
128 h' (ConsBinder b1 b2) = ConsBinder <$> (h b1 >>= h') <*> (h b2 >>= h')
121 h' (NamedBinder name b) = NamedBinder name <$> (h b >>= h')
129 h' (NamedBinder name b) = NamedBinder name <$> (h b >>= h')
122− h' (PositionedBinder pos b) = PositionedBinder pos <$> (h b >>= h')
130+ h' (PositionedBinder pos com b) = PositionedBinder pos com <$> (h b >>= h')
123 h' other = h other
131 h' other = h other
124
132
125 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM (h' <=< h) bs
133 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM (h' <=< h) bs
@@ -128,7 +136,7 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
128 handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> (g' <=< g) v
136 handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> (g' <=< g) v
129 handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> (h' <=< h) b <*> (g' <=< g) v
137 handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> (h' <=< h) b <*> (g' <=< g) v
130 handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM (f' <=< f) ds
138 handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM (f' <=< f) ds
131− handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos <$> handleDoNotationElement e
139+ handleDoNotationElement (PositionedDoNotationElement pos com e) = PositionedDoNotationElement pos com <$> handleDoNotationElement e
132
140
133everywhereOnValuesM :: (Functor m, Applicative m, Monad m) =>
141everywhereOnValuesM :: (Functor m, Applicative m, Monad m) =>
134 (Declaration -> m Declaration) ->
142 (Declaration -> m Declaration) ->
@@ -142,17 +150,21 @@ everywhereOnValuesM f g h = (f', g', h')
142 f' (BindingGroupDeclaration ds) = (BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> g' val) ds) >>= f
150 f' (BindingGroupDeclaration ds) = (BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> g' val) ds) >>= f
143 f' (TypeClassDeclaration name args implies ds) = (TypeClassDeclaration name args implies <$> mapM f' ds) >>= f
151 f' (TypeClassDeclaration name args implies ds) = (TypeClassDeclaration name args implies <$> mapM f' ds) >>= f
144 f' (TypeInstanceDeclaration name cs className args ds) = (TypeInstanceDeclaration name cs className args <$> mapM f' ds) >>= f
152 f' (TypeInstanceDeclaration name cs className args ds) = (TypeInstanceDeclaration name cs className args <$> mapM f' ds) >>= f
145− f' (PositionedDeclaration pos d) = (PositionedDeclaration pos <$> f' d) >>= f
153+ f' (PositionedDeclaration pos com d) = (PositionedDeclaration pos com <$> f' d) >>= f
146 f' other = f other
154 f' other = f other
147
155
148 g' (UnaryMinus v) = (UnaryMinus <$> g' v) >>= g
156 g' (UnaryMinus v) = (UnaryMinus <$> g' v) >>= g
149− g' (BinaryNoParens op v1 v2) = (BinaryNoParens op <$> g' v1 <*> g' v2) >>= g
157+ g' (BinaryNoParens op v1 v2) = (BinaryNoParens <$> g' op <*> g' v1 <*> g' v2) >>= g
150 g' (Parens v) = (Parens <$> g' v) >>= g
158 g' (Parens v) = (Parens <$> g' v) >>= g
159+ g' (OperatorSection op (Left v)) = (OperatorSection <$> g' op <*> (Left <$> g' v)) >>= g
160+ g' (OperatorSection op (Right v)) = (OperatorSection <$> g' op <*> (Right <$> g' v)) >>= g
151 g' (ArrayLiteral vs) = (ArrayLiteral <$> mapM g' vs) >>= g
161 g' (ArrayLiteral vs) = (ArrayLiteral <$> mapM g' vs) >>= g
152 g' (ObjectLiteral vs) = (ObjectLiteral <$> mapM (sndM g') vs) >>= g
162 g' (ObjectLiteral vs) = (ObjectLiteral <$> mapM (sndM g') vs) >>= g
163+ g' (ObjectConstructor vs) = (ObjectConstructor <$> mapM (sndM $ maybeM g') vs) >>= g
153 g' (TypeClassDictionaryConstructorApp name v) = (TypeClassDictionaryConstructorApp name <$> g' v) >>= g
164 g' (TypeClassDictionaryConstructorApp name v) = (TypeClassDictionaryConstructorApp name <$> g' v) >>= g
154 g' (Accessor prop v) = (Accessor prop <$> g' v) >>= g
165 g' (Accessor prop v) = (Accessor prop <$> g' v) >>= g
155 g' (ObjectUpdate obj vs) = (ObjectUpdate <$> g' obj <*> mapM (sndM g') vs) >>= g
166 g' (ObjectUpdate obj vs) = (ObjectUpdate <$> g' obj <*> mapM (sndM g') vs) >>= g
167+ g' (ObjectUpdater obj vs) = (ObjectUpdater <$> maybeM g' obj <*> mapM (sndM $ maybeM g') vs) >>= g
156 g' (Abs name v) = (Abs name <$> g' v) >>= g
168 g' (Abs name v) = (Abs name <$> g' v) >>= g
157 g' (App v1 v2) = (App <$> g' v1 <*> g' v2) >>= g
169 g' (App v1 v2) = (App <$> g' v1 <*> g' v2) >>= g
158 g' (IfThenElse v1 v2 v3) = (IfThenElse <$> g' v1 <*> g' v2 <*> g' v3) >>= g
170 g' (IfThenElse v1 v2 v3) = (IfThenElse <$> g' v1 <*> g' v2 <*> g' v3) >>= g
@@ -160,7 +172,7 @@ everywhereOnValuesM f g h = (f', g', h')
160 g' (TypedValue check v ty) = (TypedValue check <$> g' v <*> pure ty) >>= g
172 g' (TypedValue check v ty) = (TypedValue check <$> g' v <*> pure ty) >>= g
161 g' (Let ds v) = (Let <$> mapM f' ds <*> g' v) >>= g
173 g' (Let ds v) = (Let <$> mapM f' ds <*> g' v) >>= g
162 g' (Do es) = (Do <$> mapM handleDoNotationElement es) >>= g
174 g' (Do es) = (Do <$> mapM handleDoNotationElement es) >>= g
163− g' (PositionedValue pos v) = (PositionedValue pos <$> g' v) >>= g
175+ g' (PositionedValue pos com v) = (PositionedValue pos com <$> g' v) >>= g
164 g' other = g other
176 g' other = g other
165
177
166 h' (ConstructorBinder ctor bs) = (ConstructorBinder ctor <$> mapM h' bs) >>= h
178 h' (ConstructorBinder ctor bs) = (ConstructorBinder ctor <$> mapM h' bs) >>= h
@@ -168,7 +180,7 @@ everywhereOnValuesM f g h = (f', g', h')
168 h' (ArrayBinder bs) = (ArrayBinder <$> mapM h' bs) >>= h
180 h' (ArrayBinder bs) = (ArrayBinder <$> mapM h' bs) >>= h
169 h' (ConsBinder b1 b2) = (ConsBinder <$> h' b1 <*> h' b2) >>= h
181 h' (ConsBinder b1 b2) = (ConsBinder <$> h' b1 <*> h' b2) >>= h
170 h' (NamedBinder name b) = (NamedBinder name <$> h' b) >>= h
182 h' (NamedBinder name b) = (NamedBinder name <$> h' b) >>= h
171− h' (PositionedBinder pos b) = (PositionedBinder pos <$> h' b) >>= h
183+ h' (PositionedBinder pos com b) = (PositionedBinder pos com <$> h' b) >>= h
172 h' other = h other
184 h' other = h other
173
185
174 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM h' bs
186 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM h' bs
@@ -177,7 +189,7 @@ everywhereOnValuesM f g h = (f', g', h')
177 handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> g' v
189 handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> g' v
178 handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> h' b <*> g' v
190 handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> h' b <*> g' v
179 handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM f' ds
191 handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM f' ds
180− handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos <$> handleDoNotationElement e
192+ handleDoNotationElement (PositionedDoNotationElement pos com e) = PositionedDoNotationElement pos com <$> handleDoNotationElement e
181
193
182everythingOnValues :: (r -> r -> r) ->
194everythingOnValues :: (r -> r -> r) ->
183 (Declaration -> r) ->
195 (Declaration -> r) ->
@@ -194,17 +206,21 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
194 f' d@(BindingGroupDeclaration ds) = foldl (<>) (f d) (map (\(_, _, val) -> g' val) ds)
206 f' d@(BindingGroupDeclaration ds) = foldl (<>) (f d) (map (\(_, _, val) -> g' val) ds)
195 f' d@(TypeClassDeclaration _ _ _ ds) = foldl (<>) (f d) (map f' ds)
207 f' d@(TypeClassDeclaration _ _ _ ds) = foldl (<>) (f d) (map f' ds)
196 f' d@(TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) (f d) (map f' ds)
208 f' d@(TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) (f d) (map f' ds)
197− f' d@(PositionedDeclaration _ d1) = f d <> f' d1
209+ f' d@(PositionedDeclaration _ _ d1) = f d <> f' d1
198 f' d = f d
210 f' d = f d
199
211
200 g' v@(UnaryMinus v1) = g v <> g' v1
212 g' v@(UnaryMinus v1) = g v <> g' v1
201− g' v@(BinaryNoParens _ v1 v2) = g v <> g' v1 <> g' v2
213+ g' v@(BinaryNoParens op v1 v2) = g v <> g op <> g' v1 <> g' v2
202 g' v@(Parens v1) = g v <> g' v1
214 g' v@(Parens v1) = g v <> g' v1
215+ g' v@(OperatorSection op (Left v1)) = g v <> g op <> g' v1
216+ g' v@(OperatorSection op (Right v1)) = g v <> g op <> g' v1
203 g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)
217 g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)
204 g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)
218 g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)
219+ g' v@(ObjectConstructor vs) = foldl (<>) (g v) (map g' (mapMaybe snd vs))
205 g' v@(TypeClassDictionaryConstructorApp _ v1) = g v <> g' v1
220 g' v@(TypeClassDictionaryConstructorApp _ v1) = g v <> g' v1
206 g' v@(Accessor _ v1) = g v <> g' v1
221 g' v@(Accessor _ v1) = g v <> g' v1
207 g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)
222 g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)
223+ g' v@(ObjectUpdater obj vs) = foldl (<>) (maybe (g v) (\x -> g v <> g' x) obj) (map g' (mapMaybe snd vs))
208 g' v@(Abs _ v1) = g v <> g' v1
224 g' v@(Abs _ v1) = g v <> g' v1
209 g' v@(App v1 v2) = g v <> g' v1 <> g' v2
225 g' v@(App v1 v2) = g v <> g' v1 <> g' v2
210 g' v@(IfThenElse v1 v2 v3) = g v <> g' v1 <> g' v2 <> g' v3
226 g' v@(IfThenElse v1 v2 v3) = g v <> g' v1 <> g' v2 <> g' v3
@@ -212,7 +228,7 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
212 g' v@(TypedValue _ v1 _) = g v <> g' v1
228 g' v@(TypedValue _ v1 _) = g v <> g' v1
213 g' v@(Let ds v1) = foldl (<>) (g v) (map f' ds) <> g' v1
229 g' v@(Let ds v1) = foldl (<>) (g v) (map f' ds) <> g' v1
214 g' v@(Do es) = foldl (<>) (g v) (map j' es)
230 g' v@(Do es) = foldl (<>) (g v) (map j' es)
215− g' v@(PositionedValue _ v1) = g v <> g' v1
231+ g' v@(PositionedValue _ _ v1) = g v <> g' v1
216 g' v = g v
232 g' v = g v
217
233
218 h' b@(ConstructorBinder _ bs) = foldl (<>) (h b) (map h' bs)
234 h' b@(ConstructorBinder _ bs) = foldl (<>) (h b) (map h' bs)
@@ -220,7 +236,7 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
220 h' b@(ArrayBinder bs) = foldl (<>) (h b) (map h' bs)
236 h' b@(ArrayBinder bs) = foldl (<>) (h b) (map h' bs)
221 h' b@(ConsBinder b1 b2) = h b <> h' b1 <> h' b2
237 h' b@(ConsBinder b1 b2) = h b <> h' b1 <> h' b2
222 h' b@(NamedBinder _ b1) = h b <> h' b1
238 h' b@(NamedBinder _ b1) = h b <> h' b1
223− h' b@(PositionedBinder _ b1) = h b <> h' b1
239+ h' b@(PositionedBinder _ _ b1) = h b <> h' b1
224 h' b = h b
240 h' b = h b
225
241
226 i' ca@(CaseAlternative bs (Right val)) = foldl (<>) (i ca) (map h' bs) <> g' val
242 i' ca@(CaseAlternative bs (Right val)) = foldl (<>) (i ca) (map h' bs) <> g' val
@@ -229,7 +245,7 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
229 j' e@(DoNotationValue v) = j e <> g' v
245 j' e@(DoNotationValue v) = j e <> g' v
230 j' e@(DoNotationBind b v) = j e <> h' b <> g' v
246 j' e@(DoNotationBind b v) = j e <> h' b <> g' v
231 j' e@(DoNotationLet ds) = foldl (<>) (j e) (map f' ds)
247 j' e@(DoNotationLet ds) = foldl (<>) (j e) (map f' ds)
232− j' e@(PositionedDoNotationElement _ e1) = j e <> j' e1
248+ j' e@(PositionedDoNotationElement _ _ e1) = j e <> j' e1
233
249
234everythingWithContextOnValues ::
250everythingWithContextOnValues ::
235 s ->
251 s ->
@@ -255,19 +271,23 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
255 f' s (BindingGroupDeclaration ds) = foldl (<>) r0 (map (\(_, _, val) -> g'' s val) ds)
271 f' s (BindingGroupDeclaration ds) = foldl (<>) r0 (map (\(_, _, val) -> g'' s val) ds)
256 f' s (TypeClassDeclaration _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)
272 f' s (TypeClassDeclaration _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)
257 f' s (TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)
273 f' s (TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)
258− f' s (PositionedDeclaration _ d1) = f'' s d1
274+ f' s (PositionedDeclaration _ _ d1) = f'' s d1
259 f' _ _ = r0
275 f' _ _ = r0
260
276
261 g'' s v = let (s', r) = g s v in r <> g' s' v
277 g'' s v = let (s', r) = g s v in r <> g' s' v
262
278
263 g' s (UnaryMinus v1) = g'' s v1
279 g' s (UnaryMinus v1) = g'' s v1
264− g' s (BinaryNoParens _ v1 v2) = g'' s v1 <> g'' s v2
280+ g' s (BinaryNoParens op v1 v2) = g'' s op <> g'' s v1 <> g'' s v2
265 g' s (Parens v1) = g'' s v1
281 g' s (Parens v1) = g'' s v1
282+ g' s (OperatorSection op (Left v)) = g'' s op <> g'' s v
283+ g' s (OperatorSection op (Right v)) = g'' s op <> g'' s v
266 g' s (ArrayLiteral vs) = foldl (<>) r0 (map (g'' s) vs)
284 g' s (ArrayLiteral vs) = foldl (<>) r0 (map (g'' s) vs)
267 g' s (ObjectLiteral vs) = foldl (<>) r0 (map (g'' s . snd) vs)
285 g' s (ObjectLiteral vs) = foldl (<>) r0 (map (g'' s . snd) vs)
286+ g' s (ObjectConstructor vs) = foldl (<>) r0 (map (g'' s) (mapMaybe snd vs))
268 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
287 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
269 g' s (Accessor _ v1) = g'' s v1
288 g' s (Accessor _ v1) = g'' s v1
270 g' s (ObjectUpdate obj vs) = foldl (<>) (g'' s obj) (map (g'' s . snd) vs)
289 g' s (ObjectUpdate obj vs) = foldl (<>) (g'' s obj) (map (g'' s . snd) vs)
290+ g' s (ObjectUpdater obj vs) = foldl (<>) (maybe r0 (g'' s) obj) (map (g'' s) (mapMaybe snd vs))
271 g' s (Abs _ v1) = g'' s v1
291 g' s (Abs _ v1) = g'' s v1
272 g' s (App v1 v2) = g'' s v1 <> g'' s v2
292 g' s (App v1 v2) = g'' s v1 <> g'' s v2
273 g' s (IfThenElse v1 v2 v3) = g'' s v1 <> g'' s v2 <> g'' s v3
293 g' s (IfThenElse v1 v2 v3) = g'' s v1 <> g'' s v2 <> g'' s v3
@@ -275,7 +295,7 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
275 g' s (TypedValue _ v1 _) = g'' s v1
295 g' s (TypedValue _ v1 _) = g'' s v1
276 g' s (Let ds v1) = foldl (<>) r0 (map (f'' s) ds) <> g'' s v1
296 g' s (Let ds v1) = foldl (<>) r0 (map (f'' s) ds) <> g'' s v1
277 g' s (Do es) = foldl (<>) r0 (map (j'' s) es)
297 g' s (Do es) = foldl (<>) r0 (map (j'' s) es)
278− g' s (PositionedValue _ v1) = g'' s v1
298+ g' s (PositionedValue _ _ v1) = g'' s v1
279 g' _ _ = r0
299 g' _ _ = r0
280
300
281 h'' s b = let (s', r) = h s b in r <> h' s' b
301 h'' s b = let (s', r) = h s b in r <> h' s' b
@@ -285,7 +305,7 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
285 h' s (ArrayBinder bs) = foldl (<>) r0 (map (h'' s) bs)
305 h' s (ArrayBinder bs) = foldl (<>) r0 (map (h'' s) bs)
286 h' s (ConsBinder b1 b2) = h'' s b1 <> h'' s b2
306 h' s (ConsBinder b1 b2) = h'' s b1 <> h'' s b2
287 h' s (NamedBinder _ b1) = h'' s b1
307 h' s (NamedBinder _ b1) = h'' s b1
288− h' s (PositionedBinder _ b1) = h'' s b1
308+ h' s (PositionedBinder _ _ b1) = h'' s b1
289 h' _ _ = r0
309 h' _ _ = r0
290
310
291 i'' s ca = let (s', r) = i s ca in r <> i' s' ca
311 i'' s ca = let (s', r) = i s ca in r <> i' s' ca
@@ -298,7 +318,7 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
298 j' s (DoNotationValue v) = g'' s v
318 j' s (DoNotationValue v) = g'' s v
299 j' s (DoNotationBind b v) = h'' s b <> g'' s v
319 j' s (DoNotationBind b v) = h'' s b <> g'' s v
300 j' s (DoNotationLet ds) = foldl (<>) r0 (map (f'' s) ds)
320 j' s (DoNotationLet ds) = foldl (<>) r0 (map (f'' s) ds)
301− j' s (PositionedDoNotationElement _ e1) = j'' s e1
321+ j' s (PositionedDoNotationElement _ _ e1) = j'' s e1
302
322
303everywhereWithContextOnValuesM :: (Functor m, Applicative m, Monad m) =>
323everywhereWithContextOnValuesM :: (Functor m, Applicative m, Monad m) =>
304 s ->
324 s ->
@@ -321,19 +341,23 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
321 f' s (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (thirdM (g'' s)) ds
341 f' s (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (thirdM (g'' s)) ds
322 f' s (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f'' s) ds
342 f' s (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f'' s) ds
323 f' s (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f'' s) ds
343 f' s (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f'' s) ds
324− f' s (PositionedDeclaration pos d1) = PositionedDeclaration pos <$> f'' s d1
344+ f' s (PositionedDeclaration pos com d1) = PositionedDeclaration pos com <$> f'' s d1
325 f' _ other = return other
345 f' _ other = return other
326
346
327 g'' s = uncurry g' <=< g s
347 g'' s = uncurry g' <=< g s
328
348
329 g' s (UnaryMinus v) = UnaryMinus <$> g'' s v
349 g' s (UnaryMinus v) = UnaryMinus <$> g'' s v
330− g' s (BinaryNoParens op v1 v2) = BinaryNoParens op <$> g'' s v1 <*> g'' s v2
350+ g' s (BinaryNoParens op v1 v2) = BinaryNoParens <$> g'' s op <*> g'' s v1 <*> g'' s v2
331 g' s (Parens v) = Parens <$> g'' s v
351 g' s (Parens v) = Parens <$> g'' s v
352+ g' s (OperatorSection op (Left v)) = OperatorSection <$> g'' s op <*> (Left <$> g'' s v)
353+ g' s (OperatorSection op (Right v)) = OperatorSection <$> g'' s op <*> (Right <$> g'' s v)
332 g' s (ArrayLiteral vs) = ArrayLiteral <$> mapM (g'' s) vs
354 g' s (ArrayLiteral vs) = ArrayLiteral <$> mapM (g'' s) vs
333 g' s (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g'' s)) vs
355 g' s (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g'' s)) vs
356+ g' s (ObjectConstructor vs) = ObjectConstructor <$> mapM (sndM $ maybeM (g'' s)) vs
334 g' s (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> g'' s v
357 g' s (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> g'' s v
335 g' s (Accessor prop v) = Accessor prop <$> g'' s v
358 g' s (Accessor prop v) = Accessor prop <$> g'' s v
336 g' s (ObjectUpdate obj vs) = ObjectUpdate <$> g'' s obj <*> mapM (sndM (g'' s)) vs
359 g' s (ObjectUpdate obj vs) = ObjectUpdate <$> g'' s obj <*> mapM (sndM (g'' s)) vs
360+ g' s (ObjectUpdater obj vs) = ObjectUpdater <$> maybeM (g'' s) obj <*> mapM (sndM $ maybeM (g'' s)) vs
337 g' s (Abs name v) = Abs name <$> g'' s v
361 g' s (Abs name v) = Abs name <$> g'' s v
338 g' s (App v1 v2) = App <$> g'' s v1 <*> g'' s v2
362 g' s (App v1 v2) = App <$> g'' s v1 <*> g'' s v2
339 g' s (IfThenElse v1 v2 v3) = IfThenElse <$> g'' s v1 <*> g'' s v2 <*> g'' s v3
363 g' s (IfThenElse v1 v2 v3) = IfThenElse <$> g'' s v1 <*> g'' s v2 <*> g'' s v3
@@ -341,7 +365,7 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
341 g' s (TypedValue check v ty) = TypedValue check <$> g'' s v <*> pure ty
365 g' s (TypedValue check v ty) = TypedValue check <$> g'' s v <*> pure ty
342 g' s (Let ds v) = Let <$> mapM (f'' s) ds <*> g'' s v
366 g' s (Let ds v) = Let <$> mapM (f'' s) ds <*> g'' s v
343 g' s (Do es) = Do <$> mapM (j'' s) es
367 g' s (Do es) = Do <$> mapM (j'' s) es
344− g' s (PositionedValue pos v) = PositionedValue pos <$> g'' s v
368+ g' s (PositionedValue pos com v) = PositionedValue pos com <$> g'' s v
345 g' _ other = return other
369 g' _ other = return other
346
370
347 h'' s = uncurry h' <=< h s
371 h'' s = uncurry h' <=< h s
@@ -351,7 +375,7 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
351 h' s (ArrayBinder bs) = ArrayBinder <$> mapM (h'' s) bs
375 h' s (ArrayBinder bs) = ArrayBinder <$> mapM (h'' s) bs
352 h' s (ConsBinder b1 b2) = ConsBinder <$> h'' s b1 <*> h'' s b2
376 h' s (ConsBinder b1 b2) = ConsBinder <$> h'' s b1 <*> h'' s b2
353 h' s (NamedBinder name b) = NamedBinder name <$> h'' s b
377 h' s (NamedBinder name b) = NamedBinder name <$> h'' s b
354− h' s (PositionedBinder pos b) = PositionedBinder pos <$> h'' s b
378+ h' s (PositionedBinder pos com b) = PositionedBinder pos com <$> h'' s b
355 h' _ other = return other
379 h' _ other = return other
356
380
357 i'' s = uncurry i' <=< i s
381 i'' s = uncurry i' <=< i s
@@ -363,7 +387,7 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
363 j' s (DoNotationValue v) = DoNotationValue <$> g'' s v
387 j' s (DoNotationValue v) = DoNotationValue <$> g'' s v
364 j' s (DoNotationBind b v) = DoNotationBind <$> h'' s b <*> g'' s v
388 j' s (DoNotationBind b v) = DoNotationBind <$> h'' s b <*> g'' s v
365 j' s (DoNotationLet ds) = DoNotationLet <$> mapM (f'' s) ds
389 j' s (DoNotationLet ds) = DoNotationLet <$> mapM (f'' s) ds
366− j' s (PositionedDoNotationElement pos e1) = PositionedDoNotationElement pos <$> j'' s e1
390+ j' s (PositionedDoNotationElement pos com e1) = PositionedDoNotationElement pos com <$> j'' s e1
367
391
368accumTypes :: (Monoid r) => (Type -> r) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
392accumTypes :: (Monoid r) => (Type -> r) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
369accumTypes f = everythingOnValues mappend forDecls forValues (const mempty) (const mempty) (const mempty)
393accumTypes f = everythingOnValues mappend forDecls forValues (const mempty) (const mempty) (const mempty)
src/Language/PureScript/CodeGen/Externs.hs+16−4
@@ -30,6 +30,7 @@ import Language.PureScript.Names
30import Language.PureScript.Pretty
30import Language.PureScript.Pretty
31import Language.PureScript.TypeClassDictionaries
31import Language.PureScript.TypeClassDictionaries
32import Language.PureScript.Types
32import Language.PureScript.Types
33+import Language.PureScript.Comments
33
34
34-- |
35-- |
35-- Generate foreign imports for all declarations in a module
36-- Generate foreign imports for all declarations in a module
@@ -44,13 +45,24 @@ moduleToPs (Module moduleName ds (Just exts)) env = intercalate "\n" . execWrite
44
45
45 declToPs :: Declaration -> Writer [String] ()
46 declToPs :: Declaration -> Writer [String] ()
46 declToPs (ImportDeclaration mn _ _) = tell ["import " ++ show mn ++ " ()"]
47 declToPs (ImportDeclaration mn _ _) = tell ["import " ++ show mn ++ " ()"]
47− declToPs (FixityDeclaration (Fixity assoc prec) ident) =
48+ declToPs (FixityDeclaration (Fixity assoc prec) op) =
49+ case find exportsOp exts of
50+ Nothing -> return ()
48− tell [ unwords [ show assoc, show prec, ident ] ]
51+ Just _ -> tell [ unwords [ show assoc, show prec, op ] ]
52+ where
53+ exportsOp :: DeclarationRef -> Bool
54+ exportsOp (PositionedDeclarationRef _ _ r) = exportsOp r
55+ exportsOp (ValueRef ident') = ident' == Op op
56+ exportsOp _ = False
49− declToPs (PositionedDeclaration _ d) = declToPs d
57+ declToPs (PositionedDeclaration _ com d) = mapM commentToPs com >> declToPs d
50 declToPs _ = return ()
58 declToPs _ = return ()
51
59
60+ commentToPs :: Comment -> Writer [String] ()
61+ commentToPs (LineComment s) = tell ["-- " ++ s]
62+ commentToPs (BlockComment s) = tell ["{- " ++ s ++ " -}"]
63+
52 exportToPs :: DeclarationRef -> Writer [String] ()
64 exportToPs :: DeclarationRef -> Writer [String] ()
53− exportToPs (PositionedDeclarationRef _ r) = exportToPs r
65+ exportToPs (PositionedDeclarationRef _ _ r) = exportToPs r
54 exportToPs (TypeRef pn dctors) = do
66 exportToPs (TypeRef pn dctors) = do
55 case Qualified (Just moduleName) pn `M.lookup` types env of
67 case Qualified (Just moduleName) pn `M.lookup` types env of
56 Nothing -> error $ show pn ++ " has no kind in exportToPs"
68 Nothing -> error $ show pn ++ " has no kind in exportToPs"
src/Language/PureScript/CodeGen/JS.hs+88−69
@@ -13,22 +13,22 @@
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16−{-# LANGUAGE GADTs #-}
16+{-# LANGUAGE GADTs, ViewPatterns, FlexibleContexts #-}
17
17
18module Language.PureScript.CodeGen.JS (
18module Language.PureScript.CodeGen.JS (
19 module AST,
19 module AST,
20 module Common,
20 module Common,
21− bindToJs,
22 moduleToJs
21 moduleToJs
23) where
22) where
24
23
25−import Data.Function (on)
24+import Data.List ((\\), delete)
26−import Data.List ((\\), delete, sortBy)
27−import Data.Maybe (catMaybes, mapMaybe)
25+import Data.Maybe (mapMaybe)
26+import qualified Data.Traversable as T (traverse)
28
27
29import Control.Applicative
28import Control.Applicative
30import Control.Arrow ((&&&))
29import Control.Arrow ((&&&))
31import Control.Monad (foldM, replicateM, forM)
30import Control.Monad (foldM, replicateM, forM)
31+import Control.Monad.Reader (MonadReader, asks, lift)
32
32
33import Language.PureScript.CodeGen.JS.AST as AST
33import Language.PureScript.CodeGen.JS.AST as AST
34import Language.PureScript.CodeGen.JS.Common as Common
34import Language.PureScript.CodeGen.JS.Common as Common
@@ -44,16 +44,18 @@ import qualified Language.PureScript.Constants as C
44-- Generate code in the simplified Javascript intermediate representation for all declarations in a
44-- Generate code in the simplified Javascript intermediate representation for all declarations in a
45-- module.
45-- module.
46--
46--
47−moduleToJs :: (Functor m, Applicative m, Monad m) => Options mode -> Module Ann -> SupplyT m [JS]
47+moduleToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
48+ => Module Ann -> SupplyT m [JS]
48−moduleToJs opts (Module name imps exps foreigns decls) = do
49+moduleToJs (Module name imps exps foreigns decls) = do
50+ additional <- lift $ asks optionsAdditional
49− let jsImports = map (importToJs opts) . delete (ModuleName [ProperName C.prim]) . (\\ [name]) $ imps
51+ jsImports <- lift . T.traverse importToJs . delete (ModuleName [ProperName C.prim]) . (\\ [name]) $ imps
50 let foreigns' = mapMaybe (\(_, js, _) -> js) foreigns
52 let foreigns' = mapMaybe (\(_, js, _) -> js) foreigns
51 jsDecls <- mapM (bindToJs name) decls
53 jsDecls <- mapM (bindToJs name) decls
52− let optimized = concatMap (map $ optimize opts) $ catMaybes jsDecls
54+ optimized <- lift $ T.traverse (T.traverse optimize) jsDecls
53 let isModuleEmpty = null exps
55 let isModuleEmpty = null exps
54− let moduleBody = JSStringLiteral "use strict" : jsImports ++ foreigns' ++ optimized
56+ let moduleBody = JSStringLiteral "use strict" : jsImports ++ foreigns' ++ concat optimized
55 let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) exps
57 let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) exps
56− return $ case optionsAdditional opts of
58+ return $ case additional of
57 MakeOptions -> moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
59 MakeOptions -> moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
58 CompileOptions ns _ _ | not isModuleEmpty ->
60 CompileOptions ns _ _ | not isModuleEmpty ->
59 [ JSVariableIntroduction ns
61 [ JSVariableIntroduction ns
@@ -66,26 +68,39 @@ moduleToJs opts (Module name imps exps foreigns decls) = do
66-- |
68-- |
67-- Generates Javascript code for a module import.
69-- Generates Javascript code for a module import.
68--
70--
69−importToJs :: Options mode -> ModuleName -> JS
71+importToJs :: (Monad m, MonadReader (Options mode) m) => ModuleName -> m JS
70−importToJs opts mn =
72+importToJs mn = do
71− JSVariableIntroduction (moduleNameToJs mn) (Just moduleBody)
72− where
73− moduleBody = case optionsAdditional opts of
73+ additional <- asks optionsAdditional
74+ let moduleBody = case additional of
74− MakeOptions -> JSApp (JSVar "require") [JSStringLiteral (runModuleName mn)]
75+ MakeOptions -> JSApp (JSVar "require") [JSStringLiteral (runModuleName mn)]
75− CompileOptions ns _ _ -> JSAccessor (moduleNameToJs mn) (JSVar ns)
76+ CompileOptions ns _ _ -> JSAccessor (moduleNameToJs mn) (JSVar ns)
77+ return $ JSVariableIntroduction (moduleNameToJs mn) (Just moduleBody)
76
78
77-- |
79-- |
78-- Generate code in the simplified Javascript intermediate representation for a declaration
80-- Generate code in the simplified Javascript intermediate representation for a declaration
79--
81--
82+bindToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
80−bindToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> Bind Ann -> SupplyT m (Maybe [JS])
83+ => ModuleName -> Bind Ann -> SupplyT m [JS]
81−bindToJs mp (NonRec ident val) = do
84+bindToJs mp (NonRec ident val) = return <$> nonRecToJS mp ident val
85+bindToJs mp (Rec vals) = forM vals (uncurry (nonRecToJS mp))
86+
87+-- |
88+-- Generate code in the simplified Javascript intermediate representation for a single non-recursive
89+-- declaration.
90+--
91+-- The main purpose of this function is to handle code generation for comments.
92+--
93+nonRecToJS :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
94+ => ModuleName -> Ident -> Expr Ann -> SupplyT m JS
95+nonRecToJS m i e@(extractAnn -> (_, com, _, _)) | not (null com) = do
96+ withoutComment <- lift $ asks optionsNoComments
97+ if withoutComment
98+ then nonRecToJS m i (modifyAnn removeComments e)
99+ else JSComment com <$> nonRecToJS m i (modifyAnn removeComments e)
100+nonRecToJS mp ident val = do
82 js <- valueToJs mp val
101 js <- valueToJs mp val
83− return $ Just [JSVariableIntroduction (identToJs ident) (Just js)]
102+ return $ JSVariableIntroduction (identToJs ident) (Just js)
84−bindToJs mp (Rec vals) = do
103+
85− jss <- forM vals $ \(ident, val) -> do
86− js <- valueToJs mp val
87− return $ JSVariableIntroduction (identToJs ident) (Just js)
88− return $ Just jss
89
104
90-- |
105-- |
91-- Generate code in the simplified Javascript intermediate representation for a variable based on a
106-- Generate code in the simplified Javascript intermediate representation for a variable based on a
@@ -110,20 +125,21 @@ accessorString prop | identNeedsEscaping prop = JSIndexer (JSStringLiteral prop)
110-- |
125-- |
111-- Generate code in the simplified Javascript intermediate representation for a value or expression.
126-- Generate code in the simplified Javascript intermediate representation for a value or expression.
112--
127--
128+valueToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
113−valueToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> Expr Ann -> SupplyT m JS
129+ => ModuleName -> Expr Ann -> SupplyT m JS
114valueToJs m (Literal _ l) =
130valueToJs m (Literal _ l) =
115 literalToValueJS m l
131 literalToValueJS m l
116−valueToJs m (Var (_, _, Just (IsConstructor _ 0)) name) =
132+valueToJs m (Var (_, _, _, Just (IsConstructor _ [])) name) =
117 return $ JSAccessor "value" $ qualifiedToJS m id name
133 return $ JSAccessor "value" $ qualifiedToJS m id name
118−valueToJs m (Var (_, _, Just (IsConstructor _ _)) name) =
134+valueToJs m (Var (_, _, _, Just (IsConstructor _ _)) name) =
119 return $ JSAccessor "create" $ qualifiedToJS m id name
135 return $ JSAccessor "create" $ qualifiedToJS m id name
120valueToJs m (Accessor _ prop val) =
136valueToJs m (Accessor _ prop val) =
121 accessorString prop <$> valueToJs m val
137 accessorString prop <$> valueToJs m val
122valueToJs m (ObjectUpdate _ o ps) = do
138valueToJs m (ObjectUpdate _ o ps) = do
123 obj <- valueToJs m o
139 obj <- valueToJs m o
124− sts <- mapM (sndM (valueToJs m)) ps
140+ sts <- mapM (sndM $ valueToJs m) ps
125 extendObj obj sts
141 extendObj obj sts
126−valueToJs _ e@(Abs (_, _, Just IsTypeClassConstructor) _ val) =
142+valueToJs _ e@(Abs (_, _, _, Just IsTypeClassConstructor) _ _) =
127 let args = unAbs e
143 let args = unAbs e
128 in return $ JSFunction Nothing (map identToJs args) (JSBlock $ map assign args)
144 in return $ JSFunction Nothing (map identToJs args) (JSBlock $ map assign args)
129 where
145 where
@@ -140,10 +156,10 @@ valueToJs m e@App{} = do
140 let (f, args) = unApp e []
156 let (f, args) = unApp e []
141 args' <- mapM (valueToJs m) args
157 args' <- mapM (valueToJs m) args
142 case f of
158 case f of
143− Var (_, _, Just IsNewtype) _ -> return (head args')
159+ Var (_, _, _, Just IsNewtype) _ -> return (head args')
144− Var (_, _, Just (IsConstructor _ arity)) name | arity == length args ->
160+ Var (_, _, _, Just (IsConstructor _ fields)) name | length args == length fields ->
145 return $ JSUnary JSNew $ JSApp (qualifiedToJS m id name) args'
161 return $ JSUnary JSNew $ JSApp (qualifiedToJS m id name) args'
146− Var (_, _, Just IsTypeClassConstructor) name ->
162+ Var (_, _, _, Just IsTypeClassConstructor) name ->
147 return $ JSUnary JSNew $ JSApp (qualifiedToJS m id name) args'
163 return $ JSUnary JSNew $ JSApp (qualifiedToJS m id name) args'
148 _ -> flip (foldl (\fn a -> JSApp fn [a])) args' <$> valueToJs m f
164 _ -> flip (foldl (\fn a -> JSApp fn [a])) args' <$> valueToJs m f
149 where
165 where
@@ -156,38 +172,33 @@ valueToJs m (Case _ values binders) = do
156 vals <- mapM (valueToJs m) values
172 vals <- mapM (valueToJs m) values
157 bindersToJs m binders vals
173 bindersToJs m binders vals
158valueToJs m (Let _ ds val) = do
174valueToJs m (Let _ ds val) = do
159− decls <- concat . catMaybes <$> mapM (bindToJs m) ds
175+ decls <- concat <$> mapM (bindToJs m) ds
160 ret <- valueToJs m val
176 ret <- valueToJs m val
161 return $ JSApp (JSFunction Nothing [] (JSBlock (decls ++ [JSReturn ret]))) []
177 return $ JSApp (JSFunction Nothing [] (JSBlock (decls ++ [JSReturn ret]))) []
162−valueToJs _ (Constructor (_, _, Just IsNewtype) _ (ProperName ctor) _) =
178+valueToJs _ (Constructor (_, _, _, Just IsNewtype) _ (ProperName ctor) _) =
163 return $ JSVariableIntroduction ctor (Just $
179 return $ JSVariableIntroduction ctor (Just $
164 JSObjectLiteral [("create",
180 JSObjectLiteral [("create",
165 JSFunction Nothing ["value"]
181 JSFunction Nothing ["value"]
166 (JSBlock [JSReturn $ JSVar "value"]))])
182 (JSBlock [JSReturn $ JSVar "value"]))])
167−valueToJs _ (Constructor _ _ (ProperName ctor) 0) =
183+valueToJs _ (Constructor _ _ (ProperName ctor) []) =
168 return $ iife ctor [ JSFunction (Just ctor) [] (JSBlock [])
184 return $ iife ctor [ JSFunction (Just ctor) [] (JSBlock [])
169 , JSAssignment (JSAccessor "value" (JSVar ctor))
185 , JSAssignment (JSAccessor "value" (JSVar ctor))
170 (JSUnary JSNew $ JSApp (JSVar ctor) []) ]
186 (JSUnary JSNew $ JSApp (JSVar ctor) []) ]
171−valueToJs _ (Constructor _ _ (ProperName ctor) arity) =
187+valueToJs _ (Constructor _ _ (ProperName ctor) fields) =
172− return $ iife ctor [ makeConstructor ctor arity
188+ let constructor =
173− , JSAssignment (JSAccessor "create" (JSVar ctor)) (go ctor 0 arity [])
174− ]
175− where
176− makeConstructor :: String -> Int -> JS
177− makeConstructor ctorName n =
178− let args = [ "value" ++ show index | index <- [0..n-1] ]
179− body = [ JSAssignment (JSAccessor arg (JSVar "this")) (JSVar arg) | arg <- args ]
189+ let body = [ JSAssignment (JSAccessor (identToJs f) (JSVar "this")) (var f) | f <- fields ]
180− in JSFunction (Just ctorName) args (JSBlock body)
190+ in JSFunction (Just ctor) (identToJs `map` fields) (JSBlock body)
181− go :: String -> Int -> Int -> [JS] -> JS
191+ createFn =
182− go pn _ 0 values = JSUnary JSNew $ JSApp (JSVar pn) (reverse values)
192+ let body = JSUnary JSNew $ JSApp (JSVar ctor) (var `map` fields)
183− go pn index n values =
193+ in foldr (\f inner -> JSFunction Nothing [identToJs f] (JSBlock [JSReturn inner])) body fields
184− JSFunction Nothing ["value" ++ show index]
194+ in return $ iife ctor [ constructor
185− (JSBlock [JSReturn (go pn (index + 1) (n - 1) (JSVar ("value" ++ show index) : values))])
195+ , JSAssignment (JSAccessor "create" (JSVar ctor)) createFn
186−
196+ ]
187iife :: String -> [JS] -> JS
197iife :: String -> [JS] -> JS
188iife v exprs = JSApp (JSFunction Nothing [] (JSBlock $ exprs ++ [JSReturn $ JSVar v])) []
198iife v exprs = JSApp (JSFunction Nothing [] (JSBlock $ exprs ++ [JSReturn $ JSVar v])) []
189
199
200+literalToValueJS :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
190−literalToValueJS :: (Functor m, Applicative m, Monad m) => ModuleName -> Literal (Expr Ann) -> SupplyT m JS
201+ => ModuleName -> Literal (Expr Ann) -> SupplyT m JS
191literalToValueJS _ (NumericLiteral n) = return $ JSNumericLiteral n
202literalToValueJS _ (NumericLiteral n) = return $ JSNumericLiteral n
192literalToValueJS _ (StringLiteral s) = return $ JSStringLiteral s
203literalToValueJS _ (StringLiteral s) = return $ JSStringLiteral s
193literalToValueJS _ (BooleanLiteral b) = return $ JSBooleanLiteral b
204literalToValueJS _ (BooleanLiteral b) = return $ JSBooleanLiteral b
@@ -234,7 +245,8 @@ qualifiedToJS _ f (Qualified _ a) = JSVar $ identToJs (f a)
234-- Generate code in the simplified Javascript intermediate representation for pattern match binders
245-- Generate code in the simplified Javascript intermediate representation for pattern match binders
235-- and guards.
246-- and guards.
236--
247--
248+bindersToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
237−bindersToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> [CaseAlternative Ann] -> [JS] -> SupplyT m JS
249+ => ModuleName -> [CaseAlternative Ann] -> [JS] -> SupplyT m JS
238bindersToJs m binders vals = do
250bindersToJs m binders vals = do
239 valNames <- replicateM (length vals) freshName
251 valNames <- replicateM (length vals) freshName
240 let assignments = zipWith JSVariableIntroduction valNames (map Just vals)
252 let assignments = zipWith JSVariableIntroduction valNames (map Just vals)
@@ -244,14 +256,16 @@ bindersToJs m binders vals = do
244 return $ JSApp (JSFunction Nothing [] (JSBlock (assignments ++ concat jss ++ [JSThrow $ JSUnary JSNew $ JSApp (JSVar "Error") [JSStringLiteral "Failed pattern match"]])))
256 return $ JSApp (JSFunction Nothing [] (JSBlock (assignments ++ concat jss ++ [JSThrow $ JSUnary JSNew $ JSApp (JSVar "Error") [JSStringLiteral "Failed pattern match"]])))
245 []
257 []
246 where
258 where
259+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
247− go :: (Functor m, Applicative m, Monad m) => [String] -> [JS] -> [Binder Ann] -> SupplyT m [JS]
260+ => [String] -> [JS] -> [Binder Ann] -> SupplyT m [JS]
248 go _ done [] = return done
261 go _ done [] = return done
249 go (v:vs) done' (b:bs) = do
262 go (v:vs) done' (b:bs) = do
250 done'' <- go vs done' bs
263 done'' <- go vs done' bs
251 binderToJs m v done'' b
264 binderToJs m v done'' b
252 go _ _ _ = error "Invalid arguments to bindersToJs"
265 go _ _ _ = error "Invalid arguments to bindersToJs"
253
266
267+ guardsToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
254− guardsToJs :: (Functor m, Applicative m, Monad m) => Either [(Guard Ann, Expr Ann)] (Expr Ann) -> SupplyT m [JS]
268+ => Either [(Guard Ann, Expr Ann)] (Expr Ann) -> SupplyT m [JS]
255 guardsToJs (Left gs) = forM gs $ \(cond, val) -> do
269 guardsToJs (Left gs) = forM gs $ \(cond, val) -> do
256 cond' <- valueToJs m cond
270 cond' <- valueToJs m cond
257 done <- valueToJs m val
271 done <- valueToJs m val
@@ -262,16 +276,17 @@ bindersToJs m binders vals = do
262-- Generate code in the simplified Javascript intermediate representation for a pattern match
276-- Generate code in the simplified Javascript intermediate representation for a pattern match
263-- binder.
277-- binder.
264--
278--
279+binderToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
265−binderToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> String -> [JS] -> Binder Ann -> SupplyT m [JS]
280+ => ModuleName -> String -> [JS] -> Binder Ann -> SupplyT m [JS]
266binderToJs _ _ done (NullBinder{}) = return done
281binderToJs _ _ done (NullBinder{}) = return done
267binderToJs m varName done (LiteralBinder _ l) =
282binderToJs m varName done (LiteralBinder _ l) =
268 literalToBinderJS m varName done l
283 literalToBinderJS m varName done l
269binderToJs _ varName done (VarBinder _ ident) =
284binderToJs _ varName done (VarBinder _ ident) =
270 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : done)
285 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : done)
271−binderToJs m varName done (ConstructorBinder (_, _, Just IsNewtype) _ _ [b]) =
286+binderToJs m varName done (ConstructorBinder (_, _, _, Just IsNewtype) _ _ [b]) =
272 binderToJs m varName done b
287 binderToJs m varName done b
273−binderToJs m varName done (ConstructorBinder (_, _, Just (IsConstructor ctorType _)) _ ctor bs) = do
288+binderToJs m varName done (ConstructorBinder (_, _, _, Just (IsConstructor ctorType fields)) _ ctor bs) = do
274− js <- go 0 done bs
289+ js <- go (zip fields bs) done
275 return $ case ctorType of
290 return $ case ctorType of
276 ProductType -> js
291 ProductType -> js
277 SumType ->
292 SumType ->
@@ -279,13 +294,14 @@ binderToJs m varName done (ConstructorBinder (_, _, Just (IsConstructor ctorType
279 (JSBlock js)
294 (JSBlock js)
280 Nothing]
295 Nothing]
281 where
296 where
282− go :: (Functor m, Applicative m, Monad m) => Integer -> [JS] -> [Binder Ann] -> SupplyT m [JS]
297+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
298+ => [(Ident, Binder Ann)] -> [JS] -> SupplyT m [JS]
283− go _ done' [] = return done'
299+ go [] done' = return done'
284− go index done' (binder:bs') = do
300+ go ((field, binder) : remain) done' = do
285 argVar <- freshName
301 argVar <- freshName
286− done'' <- go (index + 1) done' bs'
302+ done'' <- go remain done'
287 js <- binderToJs m argVar done'' binder
303 js <- binderToJs m argVar done'' binder
288− return (JSVariableIntroduction argVar (Just (JSAccessor ("value" ++ show index) (JSVar varName))) : js)
304+ return (JSVariableIntroduction argVar (Just (JSAccessor (identToJs field) (JSVar varName))) : js)
289binderToJs m varName done binder@(ConstructorBinder _ _ ctor _) | isCons ctor = do
305binderToJs m varName done binder@(ConstructorBinder _ _ ctor _) | isCons ctor = do
290 let (headBinders, tailBinder) = uncons [] binder
306 let (headBinders, tailBinder) = uncons [] binder
291 numberOfHeadBinders = fromIntegral $ length headBinders
307 numberOfHeadBinders = fromIntegral $ length headBinders
@@ -309,7 +325,8 @@ binderToJs m varName done (NamedBinder _ ident binder) = do
309 js <- binderToJs m varName done binder
325 js <- binderToJs m varName done binder
310 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : js)
326 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : js)
311
327
328+literalToBinderJS :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
312−literalToBinderJS :: (Functor m, Applicative m, Monad m) => ModuleName -> String -> [JS] -> Literal (Binder Ann) -> SupplyT m [JS]
329+ => ModuleName -> String -> [JS] -> Literal (Binder Ann) -> SupplyT m [JS]
313literalToBinderJS _ varName done (NumericLiteral num) =
330literalToBinderJS _ varName done (NumericLiteral num) =
314 return [JSIfElse (JSBinary EqualTo (JSVar varName) (JSNumericLiteral num)) (JSBlock done) Nothing]
331 return [JSIfElse (JSBinary EqualTo (JSVar varName) (JSNumericLiteral num)) (JSBlock done) Nothing]
315literalToBinderJS _ varName done (StringLiteral str) =
332literalToBinderJS _ varName done (StringLiteral str) =
@@ -320,7 +337,8 @@ literalToBinderJS _ varName done (BooleanLiteral False) =
320 return [JSIfElse (JSUnary Not (JSVar varName)) (JSBlock done) Nothing]
337 return [JSIfElse (JSUnary Not (JSVar varName)) (JSBlock done) Nothing]
321literalToBinderJS m varName done (ObjectLiteral bs) = go done bs
338literalToBinderJS m varName done (ObjectLiteral bs) = go done bs
322 where
339 where
340+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
323− go :: (Functor m, Applicative m, Monad m) => [JS] -> [(String, Binder Ann)] -> SupplyT m [JS]
341+ => [JS] -> [(String, Binder Ann)] -> SupplyT m [JS]
324 go done' [] = return done'
342 go done' [] = return done'
325 go done' ((prop, binder):bs') = do
343 go done' ((prop, binder):bs') = do
326 propVar <- freshName
344 propVar <- freshName
@@ -331,7 +349,8 @@ literalToBinderJS m varName done (ArrayLiteral bs) = do
331 js <- go done 0 bs
349 js <- go done 0 bs
332 return [JSIfElse (JSBinary EqualTo (JSAccessor "length" (JSVar varName)) (JSNumericLiteral (Left (fromIntegral $ length bs)))) (JSBlock js) Nothing]
350 return [JSIfElse (JSBinary EqualTo (JSAccessor "length" (JSVar varName)) (JSNumericLiteral (Left (fromIntegral $ length bs)))) (JSBlock js) Nothing]
333 where
351 where
352+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
334− go :: (Functor m, Applicative m, Monad m) => [JS] -> Integer -> [Binder Ann] -> SupplyT m [JS]
353+ => [JS] -> Integer -> [Binder Ann] -> SupplyT m [JS]
335 go done' _ [] = return done'
354 go done' _ [] = return done'
336 go done' index (binder:bs') = do
355 go done' index (binder:bs') = do
337 elVar <- freshName
356 elVar <- freshName
src/Language/PureScript/CodeGen/JS/AST.hs+10−1
@@ -19,6 +19,8 @@ module Language.PureScript.CodeGen.JS.AST where
19
19
20import Data.Data
20import Data.Data
21
21
22+import Language.PureScript.Comments
23+
22-- |
24-- |
23-- Built-in unary operators
25-- Built-in unary operators
24--
26--
@@ -240,7 +242,11 @@ data JS
240 -- |
242 -- |
241 -- Raw Javascript (generated when parsing fails for an inline foreign import declaration)
243 -- Raw Javascript (generated when parsing fails for an inline foreign import declaration)
242 --
244 --
245+ | JSRaw String
246+ -- |
247+ -- Commented Javascript
248+ --
243− | JSRaw String deriving (Show, Eq, Data, Typeable)
249+ | JSComment [Comment] JS deriving (Show, Eq, Data, Typeable)
244
250
245--
251--
246-- Traversals
252-- Traversals
@@ -271,6 +277,7 @@ everywhereOnJS f = go
271 go (JSTypeOf js) = f (JSTypeOf (go js))
277 go (JSTypeOf js) = f (JSTypeOf (go js))
272 go (JSLabel name js) = f (JSLabel name (go js))
278 go (JSLabel name js) = f (JSLabel name (go js))
273 go (JSInstanceOf j1 j2) = f (JSInstanceOf (go j1) (go j2))
279 go (JSInstanceOf j1 j2) = f (JSInstanceOf (go j1) (go j2))
280+ go (JSComment com j) = f (JSComment com (go j))
274 go other = f other
281 go other = f other
275
282
276everywhereOnJSTopDown :: (JS -> JS) -> JS -> JS
283everywhereOnJSTopDown :: (JS -> JS) -> JS -> JS
@@ -298,6 +305,7 @@ everywhereOnJSTopDown f = go . f
298 go (JSTypeOf j) = JSTypeOf (go (f j))
305 go (JSTypeOf j) = JSTypeOf (go (f j))
299 go (JSLabel name j) = JSLabel name (go (f j))
306 go (JSLabel name j) = JSLabel name (go (f j))
300 go (JSInstanceOf j1 j2) = JSInstanceOf (go (f j1)) (go (f j2))
307 go (JSInstanceOf j1 j2) = JSInstanceOf (go (f j1)) (go (f j2))
308+ go (JSComment com j) = JSComment com (go (f j))
301 go other = f other
309 go other = f other
302
310
303everythingOnJS :: (r -> r -> r) -> (JS -> r) -> JS -> r
311everythingOnJS :: (r -> r -> r) -> (JS -> r) -> JS -> r
@@ -325,4 +333,5 @@ everythingOnJS (<>) f = go
325 go j@(JSTypeOf j1) = f j <> go j1
333 go j@(JSTypeOf j1) = f j <> go j1
326 go j@(JSLabel _ j1) = f j <> go j1
334 go j@(JSLabel _ j1) = f j <> go j1
327 go j@(JSInstanceOf j1 j2) = f j <> go j1 <> go j2
335 go j@(JSInstanceOf j1 j2) = f j <> go j1 <> go j2
336+ go j@(JSComment _ j1) = f j <> go j1
328 go other = f other
337 go other = f other
src/Language/PureScript/CodeGen/JS/Common.hs+42−2
@@ -135,7 +135,47 @@ nameIsJsReserved name =
135 , "volatile"
135 , "volatile"
136 , "while"
136 , "while"
137 , "with"
137 , "with"
138− , "yield" ]
138+ , "yield" ] || properNameIsJsReserved name
139
139
140moduleNameToJs :: ModuleName -> String
140moduleNameToJs :: ModuleName -> String
141+moduleNameToJs (ModuleName pns) =
141−moduleNameToJs (ModuleName pns) = intercalate "_" (runProperName `map` pns)
142+ let name = intercalate "_" (runProperName `map` pns)
143+ in if properNameIsJsReserved name then "$$" ++ name else name
144+
145+-- |
146+-- Checks whether a proper name is reserved in Javascript.
147+--
148+properNameIsJsReserved :: String -> Bool
149+properNameIsJsReserved name =
150+ name `elem` [ "Infinity"
151+ , "NaN"
152+ , "Object"
153+ , "Function"
154+ , "Boolean"
155+ , "Error"
156+ , "EvalError"
157+ , "InternalError"
158+ , "RangeError"
159+ , "ReferenceError"
160+ , "SyntaxError"
161+ , "TypeError"
162+ , "URIError"
163+ , "Number"
164+ , "Math"
165+ , "Date"
166+ , "String"
167+ , "RegExp"
168+ , "Array"
169+ , "Int8Array"
170+ , "Uint8Array"
171+ , "Uint8ClampedArray"
172+ , "Int16Array"
173+ , "Uint16Array"
174+ , "Int32Array"
175+ , "Uint32Array"
176+ , "Float32Array"
177+ , "Float64Array"
178+ , "ArrayBuffer"
179+ , "DataView"
180+ , "JSON"
181+ , "Intl" ]
src/Language/PureScript/CodeGen/JS/Optimizer.hs+29−19
@@ -31,10 +31,14 @@
31--
31--
32-----------------------------------------------------------------------------
32-----------------------------------------------------------------------------
33
33
34+{-# LANGUAGE FlexibleContexts #-}
35+
34module Language.PureScript.CodeGen.JS.Optimizer (
36module Language.PureScript.CodeGen.JS.Optimizer (
35 optimize
37 optimize
36) where
38) where
37
39
40+import Control.Monad.Reader (MonadReader, ask, asks)
41+
38import Language.PureScript.CodeGen.JS.AST
42import Language.PureScript.CodeGen.JS.AST
39import Language.PureScript.Options
43import Language.PureScript.Options
40import qualified Language.PureScript.Constants as C
44import qualified Language.PureScript.Constants as C
@@ -49,28 +53,34 @@ import Language.PureScript.CodeGen.JS.Optimizer.Blocks
49-- |
53-- |
50-- Apply a series of optimizer passes to simplified Javascript code
54-- Apply a series of optimizer passes to simplified Javascript code
51--
55--
52−optimize :: Options mode -> JS -> JS
56+optimize :: (Monad m, MonadReader (Options mode) m) => JS -> m JS
57+optimize js = do
53−optimize opts | optionsNoOptimizations opts = id
58+ noOpt <- asks optionsNoOptimizations
59+ if noOpt then return js else optimize' js
60+
61+optimize' :: (Monad m, MonadReader (Options mode) m) => JS -> m JS
62+optimize' js = do
63+ opts <- ask
54− | otherwise = untilFixedPoint (applyAll
64+ return $ untilFixedPoint (applyAll
55− [ collapseNestedBlocks
65+ [ collapseNestedBlocks
56− , collapseNestedIfs
66+ , collapseNestedIfs
57− , tco opts
67+ , tco opts
58− , magicDo opts
68+ , magicDo opts
59− , removeCodeAfterReturnStatements
69+ , removeCodeAfterReturnStatements
60− , removeUnusedArg
70+ , removeUnusedArg
61− , removeUndefinedApp
71+ , removeUndefinedApp
62− , unThunk
72+ , unThunk
63− , etaConvert
73+ , etaConvert
64− , evaluateIifes
74+ , evaluateIifes
65− , inlineVariables
75+ , inlineVariables
76+ , inlineValues
66− , inlineOperator (C.prelude, (C.$)) $ \f x -> JSApp f [x]
77+ , inlineOperator (C.prelude, (C.$)) $ \f x -> JSApp f [x]
67− , inlineOperator (C.prelude, (C.#)) $ \x f -> JSApp f [x]
78+ , inlineOperator (C.prelude, (C.#)) $ \x f -> JSApp f [x]
68− , inlineOperator (C.preludeUnsafe, C.unsafeIndex) $ flip JSIndexer
79+ , inlineOperator (C.preludeUnsafe, C.unsafeIndex) $ flip JSIndexer
69− , inlineCommonOperators ])
80+ , inlineCommonOperators ]) js
70
81
71untilFixedPoint :: (Eq a) => (a -> a) -> a -> a
82untilFixedPoint :: (Eq a) => (a -> a) -> a -> a
72untilFixedPoint f = go
83untilFixedPoint f = go
73 where
84 where
74 go a = let a' = f a in
85 go a = let a' = f a in
75 if a' == a then a' else go a'
86 if a' == a then a' else go a'
76−
src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+28−18
@@ -15,6 +15,7 @@
15
15
16module Language.PureScript.CodeGen.JS.Optimizer.Inliner (
16module Language.PureScript.CodeGen.JS.Optimizer.Inliner (
17 inlineVariables,
17 inlineVariables,
18+ inlineValues,
18 inlineOperator,
19 inlineOperator,
19 inlineCommonOperators,
20 inlineCommonOperators,
20 etaConvert,
21 etaConvert,
@@ -79,6 +80,15 @@ inlineVariables = everywhereOnJS $ removeFromBlock go
79 go (map (replaceIdent var js) sts)
80 go (map (replaceIdent var js) sts)
80 go (s:sts) = s : go sts
81 go (s:sts) = s : go sts
81
82
83+inlineValues :: JS -> JS
84+inlineValues = everywhereOnJS convert
85+ where
86+ convert :: JS -> JS
87+ convert (JSApp fn [dict]) | isPreludeDict C.semiringNumber dict && isPreludeFn C.zero fn = JSNumericLiteral (Left 0)
88+ convert (JSApp fn [dict]) | isPreludeDict C.semiringNumber dict && isPreludeFn C.one fn = JSNumericLiteral (Left 1)
89+ convert (JSApp (JSApp fn [x]) [y]) | isPreludeFn (C.%) fn = JSBinary Modulus x y
90+ convert other = other
91+
82inlineOperator :: (String, String) -> (JS -> JS -> JS) -> JS -> JS
92inlineOperator :: (String, String) -> (JS -> JS -> JS) -> JS -> JS
83inlineOperator (m, op) f = everywhereOnJS convert
93inlineOperator (m, op) f = everywhereOnJS convert
84 where
94 where
@@ -91,12 +101,11 @@ inlineOperator (m, op) f = everywhereOnJS convert
91
101
92inlineCommonOperators :: JS -> JS
102inlineCommonOperators :: JS -> JS
93inlineCommonOperators = applyAll $
103inlineCommonOperators = applyAll $
94− [ binary C.numNumber (C.+) Add
104+ [ binary C.semiringNumber (C.+) Add
95− , binary C.numNumber (C.-) Subtract
105+ , binary C.semiringNumber (C.*) Multiply
96− , binary C.numNumber (C.*) Multiply
106+ , binary C.ringNumber (C.-) Subtract
97− , binary C.numNumber (C./) Divide
98− , binary C.numNumber (C.%) Modulus
99− , unary C.numNumber C.negate Negate
107+ , unary C.ringNumber C.negate Negate
108+ , binary C.moduloSemiringNumber (C./) Divide
100
109
101 , binary C.ordNumber (C.<) LessThan
110 , binary C.ordNumber (C.<) LessThan
102 , binary C.ordNumber (C.>) GreaterThan
111 , binary C.ordNumber (C.>) GreaterThan
@@ -131,29 +140,20 @@ inlineCommonOperators = applyAll $
131 binary dictName opString op = everywhereOnJS convert
140 binary dictName opString op = everywhereOnJS convert
132 where
141 where
133 convert :: JS -> JS
142 convert :: JS -> JS
134− convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isOp fn && isOpDict dictName dict = JSBinary op x y
143+ convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isPreludeDict dictName dict && isPreludeFn opString fn = JSBinary op x y
135 convert other = other
144 convert other = other
136− isOp (JSAccessor longForm (JSAccessor prelude (JSVar _))) = prelude == C.prelude && longForm == identToJs (Op opString)
137− isOp (JSIndexer (JSStringLiteral op') (JSVar prelude)) = prelude == C.prelude && opString == op'
138− isOp _ = False
139 binaryFunction :: String -> String -> BinaryOperator -> JS -> JS
145 binaryFunction :: String -> String -> BinaryOperator -> JS -> JS
140 binaryFunction dictName fnName op = everywhereOnJS convert
146 binaryFunction dictName fnName op = everywhereOnJS convert
141 where
147 where
142 convert :: JS -> JS
148 convert :: JS -> JS
143− convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isOp fn && isOpDict dictName dict = JSBinary op x y
149+ convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isPreludeFn fnName fn && isPreludeDict dictName dict = JSBinary op x y
144 convert other = other
150 convert other = other
145− isOp (JSAccessor fnName' (JSVar prelude)) = prelude == C.prelude && fnName == fnName'
146− isOp _ = False
147 unary :: String -> String -> UnaryOperator -> JS -> JS
151 unary :: String -> String -> UnaryOperator -> JS -> JS
148 unary dictName fnName op = everywhereOnJS convert
152 unary dictName fnName op = everywhereOnJS convert
149 where
153 where
150 convert :: JS -> JS
154 convert :: JS -> JS
151− convert (JSApp (JSApp fn [dict]) [x]) | isOp fn && isOpDict dictName dict = JSUnary op x
155+ convert (JSApp (JSApp fn [dict]) [x]) | isPreludeFn fnName fn && isPreludeDict dictName dict = JSUnary op x
152 convert other = other
156 convert other = other
153− isOp (JSAccessor fnName' (JSVar prelude)) = prelude == C.prelude && fnName' == fnName
154− isOp _ = False
155− isOpDict dictName (JSAccessor prop (JSVar prelude)) = prelude == C.prelude && prop == dictName
156− isOpDict _ _ = False
157 mkFn :: Int -> JS -> JS
157 mkFn :: Int -> JS -> JS
158 mkFn 0 = everywhereOnJS convert
158 mkFn 0 = everywhereOnJS convert
159 where
159 where
@@ -189,3 +189,13 @@ inlineCommonOperators = applyAll $
189 go 0 acc (JSApp runFnN [fn]) | isNFn C.runFn n runFnN && length acc == n = Just (JSApp fn acc)
189 go 0 acc (JSApp runFnN [fn]) | isNFn C.runFn n runFnN && length acc == n = Just (JSApp fn acc)
190 go m acc (JSApp lhs [arg]) = go (m - 1) (arg : acc) lhs
190 go m acc (JSApp lhs [arg]) = go (m - 1) (arg : acc) lhs
191 go _ _ _ = Nothing
191 go _ _ _ = Nothing
192+
193+isPreludeDict :: String -> JS -> Bool
194+isPreludeDict dictName (JSAccessor prop (JSVar prelude)) = prelude == C.prelude && prop == dictName
195+isPreludeDict _ _ = False
196+
197+isPreludeFn :: String -> JS -> Bool
198+isPreludeFn fnName (JSAccessor fnName' (JSVar prelude)) = prelude == C.prelude && fnName' == fnName
199+isPreludeFn fnName (JSIndexer (JSStringLiteral fnName') (JSVar prelude)) = prelude == C.prelude && fnName' == fnName
200+isPreludeFn fnName (JSAccessor longForm (JSAccessor prelude (JSVar _))) = prelude == C.prelude && longForm == identToJs (Op fnName)
201+isPreludeFn _ _ = False
src/Language/PureScript/Comments.hsnew file+25
@@ -0,0 +1,25 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Language.PureScript.Parser.Comments
4+-- Copyright : (c) Phil Freeman 2015
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- |
12+-- Defines the types of source code comments
13+--
14+-----------------------------------------------------------------------------
15+
16+{-# LANGUAGE DeriveDataTypeable #-}
17+
18+module Language.PureScript.Comments where
19+
20+import qualified Data.Data as D
21+
22+data Comment
23+ = LineComment String
24+ | BlockComment String
25+ deriving (Show, Eq, Ord, D.Data, D.Typeable)
src/Language/PureScript/Constants.hs+15
@@ -105,6 +105,12 @@ not = "not"
105
105
106-- Prelude Values
106-- Prelude Values
107
107
108+zero :: String
109+zero = "zero"
110+
111+one :: String
112+one = "one"
113+
108return :: String
114return :: String
109return = "return"
115return = "return"
110
116
@@ -163,6 +169,15 @@ applicativeEffDictionary = "applicativeEff"
163bindEffDictionary :: String
169bindEffDictionary :: String
164bindEffDictionary = "bindEff"
170bindEffDictionary = "bindEff"
165
171
172+semiringNumber :: String
173+semiringNumber = "semiringNumber"
174+
175+ringNumber :: String
176+ringNumber = "ringNumber"
177+
178+moduloSemiringNumber :: String
179+moduloSemiringNumber = "moduloSemiringNumber"
180+
166numNumber :: String
181numNumber :: String
167numNumber = "numNumber"
182numNumber = "numNumber"
168
183
src/Language/PureScript/CoreFn/Ann.hs+9−2
@@ -17,14 +17,21 @@ module Language.PureScript.CoreFn.Ann where
17import Language.PureScript.AST.SourcePos
17import Language.PureScript.AST.SourcePos
18import Language.PureScript.CoreFn.Meta
18import Language.PureScript.CoreFn.Meta
19import Language.PureScript.Types
19import Language.PureScript.Types
20+import Language.PureScript.Comments
20
21
21-- |
22-- |
22-- Type alias for basic annotations
23-- Type alias for basic annotations
23--
24--
24−type Ann = (Maybe SourceSpan, Maybe Type, Maybe Meta)
25+type Ann = (Maybe SourceSpan, [Comment], Maybe Type, Maybe Meta)
25
26
26-- |
27-- |
27-- Initial annotation with no metadata
28-- Initial annotation with no metadata
28--
29--
29nullAnn :: Ann
30nullAnn :: Ann
30−nullAnn = (Nothing, Nothing, Nothing)
31+nullAnn = (Nothing, [], Nothing, Nothing)
32+
33+-- |
34+-- Remove the comments from an annotation
35+--
36+removeComments :: Ann -> Ann
37+removeComments (ss, _, ty, meta) = (ss, [], ty, meta)
src/Language/PureScript/CoreFn/Binders.hs+2−1
@@ -13,6 +13,7 @@
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15{-# LANGUAGE DeriveDataTypeable #-}
15{-# LANGUAGE DeriveDataTypeable #-}
16+{-# LANGUAGE DeriveFunctor #-}
16
17
17module Language.PureScript.CoreFn.Binders where
18module Language.PureScript.CoreFn.Binders where
18
19
@@ -44,4 +45,4 @@ data Binder a
44 -- |
45 -- |
45 -- A binder which binds its input to an identifier
46 -- A binder which binds its input to an identifier
46 --
47 --
47− | NamedBinder a Ident (Binder a) deriving (Show, D.Data, D.Typeable)
48+ | NamedBinder a Ident (Binder a) deriving (Show, D.Data, D.Typeable, Functor)
src/Language/PureScript/CoreFn/Desugar.hs+150−143
@@ -33,22 +33,161 @@ import Language.PureScript.Environment
33import Language.PureScript.Names
33import Language.PureScript.Names
34import Language.PureScript.Sugar.TypeClasses (typeClassMemberName, superClassDictionaryNames)
34import Language.PureScript.Sugar.TypeClasses (typeClassMemberName, superClassDictionaryNames)
35import Language.PureScript.Types
35import Language.PureScript.Types
36+import Language.PureScript.Comments
36import qualified Language.PureScript.AST as A
37import qualified Language.PureScript.AST as A
37−import qualified Language.PureScript.Constants as C
38
38
39-- |
39-- |
40-- Desugars a module from AST to CoreFn representation.
40-- Desugars a module from AST to CoreFn representation.
41--
41--
42moduleToCoreFn :: Environment -> A.Module -> Module Ann
42moduleToCoreFn :: Environment -> A.Module -> Module Ann
43+moduleToCoreFn _ (A.Module _ _ Nothing) =
44+ error "Module exports were not elaborated before moduleToCoreFn"
43moduleToCoreFn env (A.Module mn decls (Just exps)) =
45moduleToCoreFn env (A.Module mn decls (Just exps)) =
44 let imports = nub $ mapMaybe importToCoreFn decls ++ findQualModules decls
46 let imports = nub $ mapMaybe importToCoreFn decls ++ findQualModules decls
45 exps' = nub $ concatMap exportToCoreFn exps
47 exps' = nub $ concatMap exportToCoreFn exps
46 externs = nub $ mapMaybe externToCoreFn decls
48 externs = nub $ mapMaybe externToCoreFn decls
47− decls' = concatMap (declToCoreFn env Nothing) decls
49+ decls' = concatMap (declToCoreFn Nothing []) decls
48 in Module mn imports exps' externs decls'
50 in Module mn imports exps' externs decls'
49−moduleToCoreFn _ (A.Module{}) =
50− error "Module exports were not elaborated before moduleToCoreFn"
51
51
52+ where
53+
54+ -- |
55+ -- Desugars member declarations from AST to CoreFn representation.
56+ --
57+ declToCoreFn :: Maybe SourceSpan -> [Comment] -> A.Declaration -> [Bind Ann]
58+ declToCoreFn ss com (A.DataDeclaration Newtype _ _ [(ctor, _)]) =
59+ [NonRec (properToIdent ctor) $
60+ Abs (ss, com, Nothing, Just IsNewtype) (Ident "x") (Var nullAnn $ Qualified Nothing (Ident "x"))]
61+ declToCoreFn _ _ d@(A.DataDeclaration Newtype _ _ _) =
62+ error $ "Found newtype with multiple constructors: " ++ show d
63+ declToCoreFn ss com (A.DataDeclaration Data tyName _ ctors) =
64+ flip map ctors $ \(ctor, _) ->
65+ let (_, _, _, fields) = lookupConstructor env (Qualified (Just mn) ctor)
66+ in NonRec (properToIdent ctor) $ Constructor (ss, com, Nothing, Nothing) tyName ctor fields
67+ declToCoreFn ss _ (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn ss []) ds
68+ declToCoreFn ss com (A.ValueDeclaration name _ _ (Right e)) =
69+ [NonRec name (exprToCoreFn ss com Nothing e)]
70+ declToCoreFn ss _ (A.BindingGroupDeclaration ds) =
71+ [Rec $ map (\(name, _, e) -> (name, exprToCoreFn ss [] Nothing e)) ds]
72+ declToCoreFn ss com (A.TypeClassDeclaration name _ supers members) =
73+ [NonRec (properToIdent name) $ mkTypeClassConstructor ss com supers members]
74+ declToCoreFn _ com (A.PositionedDeclaration ss com1 d) =
75+ declToCoreFn (Just ss) (com ++ com1) d
76+ declToCoreFn _ _ _ = []
77+
78+ -- |
79+ -- Desugars expressions from AST to CoreFn representation.
80+ --
81+ exprToCoreFn :: Maybe SourceSpan -> [Comment] -> Maybe Type -> A.Expr -> Expr Ann
82+ exprToCoreFn ss com ty (A.NumericLiteral v) =
83+ Literal (ss, com, ty, Nothing) (NumericLiteral v)
84+ exprToCoreFn ss com ty (A.StringLiteral v) =
85+ Literal (ss, com, ty, Nothing) (StringLiteral v)
86+ exprToCoreFn ss com ty (A.BooleanLiteral v) =
87+ Literal (ss, com, ty, Nothing) (BooleanLiteral v)
88+ exprToCoreFn ss com ty (A.ArrayLiteral vs) =
89+ Literal (ss, com, ty, Nothing) (ArrayLiteral $ map (exprToCoreFn ss [] Nothing) vs)
90+ exprToCoreFn ss com ty (A.ObjectLiteral vs) =
91+ Literal (ss, com, ty, Nothing) (ObjectLiteral $ map (second (exprToCoreFn ss [] Nothing)) vs)
92+ exprToCoreFn ss com ty (A.Accessor name v) =
93+ Accessor (ss, com, ty, Nothing) name (exprToCoreFn ss [] Nothing v)
94+ exprToCoreFn ss com ty (A.ObjectUpdate obj vs) =
95+ ObjectUpdate (ss, com, ty, Nothing) (exprToCoreFn ss [] Nothing obj) $ map (second (exprToCoreFn ss [] Nothing)) vs
96+ exprToCoreFn ss com ty (A.Abs (Left name) v) =
97+ Abs (ss, com, ty, Nothing) name (exprToCoreFn ss [] Nothing v)
98+ exprToCoreFn _ _ _ (A.Abs _ _) =
99+ error "Abs with Binder argument was not desugared before exprToCoreFn mn"
100+ exprToCoreFn ss com ty (A.App v1 v2) =
101+ App (ss, com, ty, Nothing) (exprToCoreFn ss [] Nothing v1) (exprToCoreFn ss [] Nothing v2)
102+ exprToCoreFn ss com ty (A.Var ident) =
103+ Var (ss, com, ty, Nothing) ident
104+ exprToCoreFn ss com ty (A.IfThenElse v1 v2 v3) =
105+ Case (ss, com, ty, Nothing) [exprToCoreFn ss [] Nothing v1]
106+ [ CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral True]
107+ (Right $ exprToCoreFn Nothing [] Nothing v2)
108+ , CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral False]
109+ (Right $ exprToCoreFn Nothing [] Nothing v3) ]
110+ exprToCoreFn ss com ty (A.Constructor name) =
111+ Var (ss, com, ty, Just $ getConstructorMeta name) $ fmap properToIdent name
112+ exprToCoreFn ss com ty (A.Case vs alts) =
113+ Case (ss, com, ty, Nothing) (map (exprToCoreFn ss [] Nothing) vs) (map (altToCoreFn ss) alts)
114+ exprToCoreFn ss com _ (A.TypedValue _ v ty) =
115+ exprToCoreFn ss com (Just ty) v
116+ exprToCoreFn ss com ty (A.Let ds v) =
117+ Let (ss, com, ty, Nothing) (concatMap (declToCoreFn ss []) ds) (exprToCoreFn ss [] Nothing v)
118+ exprToCoreFn ss com _ (A.TypeClassDictionaryConstructorApp name (A.TypedValue _ (A.ObjectLiteral vs) _)) =
119+ let args = map (exprToCoreFn ss [] Nothing . snd) $ sortBy (compare `on` fst) vs
120+ ctor = Var (ss, [], Nothing, Just IsTypeClassConstructor) (fmap properToIdent name)
121+ in foldl (App (ss, com, Nothing, Nothing)) ctor args
122+ exprToCoreFn ss com ty (A.TypeClassDictionaryAccessor _ ident) =
123+ Abs (ss, com, ty, Nothing) (Ident "dict")
124+ (Accessor nullAnn (runIdent ident) (Var nullAnn $ Qualified Nothing (Ident "dict")))
125+ exprToCoreFn _ com ty (A.PositionedValue ss com1 v) =
126+ exprToCoreFn (Just ss) (com ++ com1) ty v
127+ exprToCoreFn _ _ _ e =
128+ error $ "Unexpected value in exprToCoreFn mn: " ++ show e
129+
130+ -- |
131+ -- Desugars case alternatives from AST to CoreFn representation.
132+ --
133+ altToCoreFn :: Maybe SourceSpan -> A.CaseAlternative -> CaseAlternative Ann
134+ altToCoreFn ss (A.CaseAlternative bs vs) = CaseAlternative (map (binderToCoreFn ss []) bs) (go vs)
135+ where
136+ go :: Either [(A.Guard, A.Expr)] A.Expr -> Either [(Guard Ann, Expr Ann)] (Expr Ann)
137+ go (Left ges) = Left $ map (exprToCoreFn ss [] Nothing *** exprToCoreFn ss [] Nothing) ges
138+ go (Right e) = Right (exprToCoreFn ss [] Nothing e)
139+
140+ -- |
141+ -- Desugars case binders from AST to CoreFn representation.
142+ --
143+ binderToCoreFn :: Maybe SourceSpan -> [Comment] -> A.Binder -> Binder Ann
144+ binderToCoreFn ss com (A.NullBinder) =
145+ NullBinder (ss, com, Nothing, Nothing)
146+ binderToCoreFn ss com (A.BooleanBinder b) =
147+ LiteralBinder (ss, com, Nothing, Nothing) (BooleanLiteral b)
148+ binderToCoreFn ss com (A.StringBinder s) =
149+ LiteralBinder (ss, com, Nothing, Nothing) (StringLiteral s)
150+ binderToCoreFn ss com (A.NumberBinder n) =
151+ LiteralBinder (ss, com, Nothing, Nothing) (NumericLiteral n)
152+ binderToCoreFn ss com (A.VarBinder name) =
153+ VarBinder (ss, com, Nothing, Nothing) name
154+ binderToCoreFn ss com (A.ConstructorBinder dctor@(Qualified mn' _) bs) =
155+ let (_, tctor, _, _) = lookupConstructor env dctor
156+ in ConstructorBinder (ss, com, Nothing, Just $ getConstructorMeta dctor) (Qualified mn' tctor) dctor (map (binderToCoreFn ss []) bs)
157+ binderToCoreFn ss com (A.ObjectBinder bs) =
158+ LiteralBinder (ss, com, Nothing, Nothing) (ObjectLiteral $ map (second (binderToCoreFn ss [])) bs)
159+ binderToCoreFn ss com (A.ArrayBinder bs) =
160+ LiteralBinder (ss, com, Nothing, Nothing) (ArrayLiteral $ map (binderToCoreFn ss []) bs)
161+ binderToCoreFn ss com (A.ConsBinder b1 b2) =
162+ let arrCtor = Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Array")
163+ in ConstructorBinder (ss, com, Nothing, Nothing) arrCtor arrCtor $ map (binderToCoreFn ss []) [b1, b2]
164+ binderToCoreFn ss com (A.NamedBinder name b) =
165+ NamedBinder (ss, com, Nothing, Nothing) name (binderToCoreFn ss [] b)
166+ binderToCoreFn _ com (A.PositionedBinder ss com1 b) =
167+ binderToCoreFn (Just ss) (com ++ com1) b
168+
169+ -- |
170+ -- Gets metadata for data constructors.
171+ --
172+ getConstructorMeta :: Qualified ProperName -> Meta
173+ getConstructorMeta ctor =
174+ case lookupConstructor env ctor of
175+ (Newtype, _, _, _) -> IsNewtype
176+ dc@(Data, _, _, fields) ->
177+ let constructorType = if numConstructors (ctor, dc) == 1 then ProductType else SumType
178+ in IsConstructor constructorType fields
179+ where
180+ numConstructors :: (Qualified ProperName, (DataDeclType, ProperName, Type, [Ident])) -> Int
181+ numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors env
182+ typeConstructor :: (Qualified ProperName, (DataDeclType, ProperName, Type, [Ident])) -> (ModuleName, ProperName)
183+ typeConstructor (Qualified (Just mn') _, (_, tyCtor, _, _)) = (mn', tyCtor)
184+ typeConstructor _ = error "Invalid argument to typeConstructor"
185+
186+-- |
187+-- Find module names from qualified references to values. This is used to
188+-- ensure instances are imported from any module that is referenced by the
189+-- current module, not just from those that are imported explicitly (#667).
190+--
52findQualModules :: [A.Declaration] -> [ModuleName]
191findQualModules :: [A.Declaration] -> [ModuleName]
53findQualModules decls =
192findQualModules decls =
54 let (f, _, _, _, _) = everythingOnValues (++) (const []) fqValues (const []) (const []) (const [])
193 let (f, _, _, _, _) = everythingOnValues (++) (const []) fqValues (const []) (const []) (const [])
@@ -63,7 +202,7 @@ findQualModules decls =
63--
202--
64importToCoreFn :: A.Declaration -> Maybe ModuleName
203importToCoreFn :: A.Declaration -> Maybe ModuleName
65importToCoreFn (A.ImportDeclaration name _ _) = Just name
204importToCoreFn (A.ImportDeclaration name _ _) = Just name
66−importToCoreFn (A.PositionedDeclaration _ d) = importToCoreFn d
205+importToCoreFn (A.PositionedDeclaration _ _ d) = importToCoreFn d
67importToCoreFn _ = Nothing
206importToCoreFn _ = Nothing
68
207
69-- |
208-- |
@@ -72,7 +211,7 @@ importToCoreFn _ = Nothing
72externToCoreFn :: A.Declaration -> Maybe ForeignDecl
211externToCoreFn :: A.Declaration -> Maybe ForeignDecl
73externToCoreFn (A.ExternDeclaration _ name js ty) = Just (name, js, ty)
212externToCoreFn (A.ExternDeclaration _ name js ty) = Just (name, js, ty)
74externToCoreFn (A.ExternInstanceDeclaration name _ _ _) = Just (name, Nothing, tyObject)
213externToCoreFn (A.ExternInstanceDeclaration name _ _ _) = Just (name, Nothing, tyObject)
75−externToCoreFn (A.PositionedDeclaration _ d) = externToCoreFn d
214+externToCoreFn (A.PositionedDeclaration _ _ d) = externToCoreFn d
76externToCoreFn _ = Nothing
215externToCoreFn _ = Nothing
77
216
78-- |
217-- |
@@ -85,158 +224,26 @@ exportToCoreFn (A.TypeRef _ (Just dctors)) = map properToIdent dctors
85exportToCoreFn (A.ValueRef name) = [name]
224exportToCoreFn (A.ValueRef name) = [name]
86exportToCoreFn (A.TypeClassRef name) = [properToIdent name]
225exportToCoreFn (A.TypeClassRef name) = [properToIdent name]
87exportToCoreFn (A.TypeInstanceRef name) = [name]
226exportToCoreFn (A.TypeInstanceRef name) = [name]
88−exportToCoreFn (A.PositionedDeclarationRef _ d) = exportToCoreFn d
227+exportToCoreFn (A.PositionedDeclarationRef _ _ d) = exportToCoreFn d
89exportToCoreFn _ = []
228exportToCoreFn _ = []
90
229
91−-- |
92−-- Desugars member declarations from AST to CoreFn representation.
93−--
94−declToCoreFn :: Environment -> Maybe SourceSpan -> A.Declaration -> [Bind Ann]
95−declToCoreFn _ ss (A.DataDeclaration Newtype _ _ [(ctor, _)]) =
96− [NonRec (properToIdent ctor) $
97− Abs (ss, Nothing, Just IsNewtype) (Ident "x") (Var nullAnn $ Qualified Nothing (Ident "x"))]
98−declToCoreFn _ _ d@(A.DataDeclaration Newtype _ _ _) =
99− error $ "Found newtype with multiple constructors: " ++ show d
100−declToCoreFn _ ss (A.DataDeclaration Data tyName _ ctors) =
101− flip map ctors $ \(ctor, tys) ->
102− NonRec (properToIdent ctor) $ Constructor (ss, Nothing, Nothing) tyName ctor (length tys)
103−declToCoreFn env ss (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn env ss) ds
104−declToCoreFn env ss (A.ValueDeclaration name _ _ (Right e)) =
105− [NonRec name (exprToCoreFn env ss Nothing e)]
106−declToCoreFn env ss (A.BindingGroupDeclaration ds) =
107− [Rec $ map (\(name, _, e) -> (name, exprToCoreFn env ss Nothing e)) ds]
108−declToCoreFn _ ss (A.TypeClassDeclaration name _ supers members) =
109− [NonRec (properToIdent name) $ mkTypeClassConstructor ss supers members]
110−declToCoreFn env _ (A.PositionedDeclaration ss d) =
111− declToCoreFn env (Just ss) d
112−declToCoreFn _ _ _ = []
113−
114-- |
230-- |
115-- Makes a typeclass dictionary constructor function. The returned expression
231-- Makes a typeclass dictionary constructor function. The returned expression
116-- is a function that accepts the superclass instances and member
232-- is a function that accepts the superclass instances and member
117-- implementations and returns a record for the instance dictionary.
233-- implementations and returns a record for the instance dictionary.
118--
234--
119−mkTypeClassConstructor :: Maybe SourceSpan -> [Constraint] -> [A.Declaration] -> Expr Ann
235+mkTypeClassConstructor :: Maybe SourceSpan -> [Comment] -> [Constraint] -> [A.Declaration] -> Expr Ann
120−mkTypeClassConstructor ss [] [] = Literal (ss, Nothing, Just IsTypeClassConstructor) (ObjectLiteral [])
236+mkTypeClassConstructor ss com [] [] = Literal (ss, com, Nothing, Just IsTypeClassConstructor) (ObjectLiteral [])
121−mkTypeClassConstructor ss supers members =
237+mkTypeClassConstructor ss com supers members =
122 let args@(a:as) = sort $ map typeClassMemberName members ++ superClassDictionaryNames supers
238 let args@(a:as) = sort $ map typeClassMemberName members ++ superClassDictionaryNames supers
123 props = [ (arg, Var nullAnn $ Qualified Nothing (Ident arg)) | arg <- args ]
239 props = [ (arg, Var nullAnn $ Qualified Nothing (Ident arg)) | arg <- args ]
124 dict = Literal nullAnn (ObjectLiteral props)
240 dict = Literal nullAnn (ObjectLiteral props)
125− in Abs (ss, Nothing, Just IsTypeClassConstructor)
241+ in Abs (ss, com, Nothing, Just IsTypeClassConstructor)
126 (Ident a)
242 (Ident a)
127 (foldr (Abs nullAnn . Ident) dict as)
243 (foldr (Abs nullAnn . Ident) dict as)
128
244
129−-- |
130−-- Desugars expressions from AST to CoreFn representation.
131−--
132−exprToCoreFn :: Environment -> Maybe SourceSpan -> Maybe Type -> A.Expr -> Expr Ann
133−exprToCoreFn _ ss ty (A.NumericLiteral v) =
134− Literal (ss, ty, Nothing) (NumericLiteral v)
135−exprToCoreFn _ ss ty (A.StringLiteral v) =
136− Literal (ss, ty, Nothing) (StringLiteral v)
137−exprToCoreFn _ ss ty (A.BooleanLiteral v) =
138− Literal (ss, ty, Nothing) (BooleanLiteral v)
139−exprToCoreFn env ss ty (A.ArrayLiteral vs) =
140− Literal (ss, ty, Nothing) (ArrayLiteral $ map (exprToCoreFn env ss Nothing) vs)
141−exprToCoreFn env ss ty (A.ObjectLiteral vs) =
142− Literal (ss, ty, Nothing) (ObjectLiteral $ map (second (exprToCoreFn env ss Nothing)) vs)
143−exprToCoreFn env ss ty (A.Accessor name v) =
144− Accessor (ss, ty, Nothing) name (exprToCoreFn env ss Nothing v)
145−exprToCoreFn env ss ty (A.ObjectUpdate obj vs) =
146− ObjectUpdate (ss, ty, Nothing) (exprToCoreFn env ss Nothing obj) $ map (second (exprToCoreFn env ss Nothing)) vs
147−exprToCoreFn env ss ty (A.Abs (Left name) v) =
148− Abs (ss, ty, Nothing) name (exprToCoreFn env ss Nothing v)
149−exprToCoreFn _ _ _ (A.Abs _ _) =
150− error "Abs with Binder argument was not desugared before exprToCoreFn"
151−exprToCoreFn env ss ty (A.App v1 v2) =
152− App (ss, ty, Nothing) (exprToCoreFn env ss Nothing v1) (exprToCoreFn env ss Nothing v2)
153−exprToCoreFn _ ss ty (A.Var ident) =
154− Var (ss, ty, Nothing) ident
155−exprToCoreFn env ss ty (A.IfThenElse v1 v2 v3) =
156− Case (ss, ty, Nothing) [exprToCoreFn env ss Nothing v1]
157− [ CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral True]
158− (Right $ exprToCoreFn env Nothing Nothing v2)
159− , CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral False]
160− (Right $ exprToCoreFn env Nothing Nothing v3) ]
161−exprToCoreFn env ss ty (A.Constructor name) =
162− Var (ss, ty, Just $ getConstructorMeta env name) $ fmap properToIdent name
163−exprToCoreFn env ss ty (A.Case vs alts) =
164− Case (ss, ty, Nothing) (map (exprToCoreFn env ss Nothing) vs) (map (altToCoreFn env ss) alts)
165−exprToCoreFn env ss _ (A.TypedValue _ v ty) =
166− exprToCoreFn env ss (Just ty) v
167−exprToCoreFn env ss ty (A.Let ds v) =
168− Let (ss, ty, Nothing) (concatMap (declToCoreFn env ss) ds) (exprToCoreFn env ss Nothing v)
169−exprToCoreFn env ss ty (A.TypeClassDictionaryConstructorApp name (A.TypedValue _ (A.ObjectLiteral vs) _)) =
170− let args = map (exprToCoreFn env ss Nothing . snd) $ sortBy (compare `on` fst) vs
171− ctor = Var (ss, Nothing, Just IsTypeClassConstructor) (fmap properToIdent name)
172− in foldl (App (ss, Nothing, Nothing)) ctor args
173−exprToCoreFn env _ ty (A.PositionedValue ss v) =
174− exprToCoreFn env (Just ss) ty v
175−exprToCoreFn _ _ _ e =
176− error $ "Unexpected value in exprToCoreFn: " ++ show e
177−
178−-- |
179−-- Desugars case alternatives from AST to CoreFn representation.
180−--
181−altToCoreFn :: Environment -> Maybe SourceSpan -> A.CaseAlternative -> CaseAlternative Ann
182−altToCoreFn env ss (A.CaseAlternative bs vs) = CaseAlternative (map (binderToCoreFn env ss) bs) (go vs)
183− where
184− go :: Either [(A.Guard, A.Expr)] A.Expr -> Either [(Guard Ann, Expr Ann)] (Expr Ann)
185− go (Left ges) = Left $ map (exprToCoreFn env ss Nothing *** exprToCoreFn env ss Nothing) ges
186− go (Right e) = Right (exprToCoreFn env ss Nothing e)
187−
188−-- |
189−-- Desugars case binders from AST to CoreFn representation.
190−--
191−binderToCoreFn :: Environment -> Maybe SourceSpan -> A.Binder -> Binder Ann
192−binderToCoreFn _ ss (A.NullBinder) =
193− NullBinder (ss, Nothing, Nothing)
194−binderToCoreFn _ ss (A.BooleanBinder b) =
195− LiteralBinder (ss, Nothing, Nothing) (BooleanLiteral b)
196−binderToCoreFn _ ss (A.StringBinder s) =
197− LiteralBinder (ss, Nothing, Nothing) (StringLiteral s)
198−binderToCoreFn _ ss (A.NumberBinder n) =
199− LiteralBinder (ss, Nothing, Nothing) (NumericLiteral n)
200−binderToCoreFn _ ss (A.VarBinder name) =
201− VarBinder (ss, Nothing, Nothing) name
202−binderToCoreFn env ss (A.ConstructorBinder dctor@(Qualified mn _) bs) =
203− let (_, tctor, _) = lookupConstructor env dctor
204− in ConstructorBinder (ss, Nothing, Just $ getConstructorMeta env dctor) (Qualified mn tctor) dctor (map (binderToCoreFn env ss) bs)
205−binderToCoreFn env ss (A.ObjectBinder bs) =
206− LiteralBinder (ss, Nothing, Nothing) (ObjectLiteral $ map (second (binderToCoreFn env ss)) bs)
207−binderToCoreFn env ss (A.ArrayBinder bs) =
208− LiteralBinder (ss, Nothing, Nothing) (ArrayLiteral $ map (binderToCoreFn env ss) bs)
209−binderToCoreFn env ss (A.ConsBinder b1 b2) =
210− let arrCtor = Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Array")
211− in ConstructorBinder (ss, Nothing, Nothing) arrCtor arrCtor $ map (binderToCoreFn env ss) [b1, b2]
212−binderToCoreFn env ss (A.NamedBinder name b) =
213− NamedBinder (ss, Nothing, Nothing) name (binderToCoreFn env ss b)
214−binderToCoreFn env _ (A.PositionedBinder ss b) =
215− binderToCoreFn env (Just ss) b
216−
217-- |
245-- |
218-- Converts a ProperName to an Ident.
246-- Converts a ProperName to an Ident.
219--
247--
220properToIdent :: ProperName -> Ident
248properToIdent :: ProperName -> Ident
221properToIdent = Ident . runProperName
249properToIdent = Ident . runProperName
222−
223−-- |
224−-- Gets metadata for data constructors.
225−--
226−getConstructorMeta :: Environment -> Qualified ProperName -> Meta
227−getConstructorMeta env ctor =
228− case lookupConstructor env ctor of
229− (Newtype, _, _) -> IsNewtype
230− dc@(Data, _, ty) ->
231− let constructorType = if numConstructors (ctor, dc) == 1 then ProductType else SumType
232− in IsConstructor constructorType (getArity ty)
233− where
234− getArity :: Type -> Int
235− getArity (TypeApp (TypeApp f _) t) | f == tyFunction = getArity t + 1
236− getArity (ForAll _ ty _) = getArity ty
237− getArity _ = 0
238− numConstructors :: (Qualified ProperName, (DataDeclType, ProperName, Type)) -> Int
239− numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors env
240− typeConstructor :: (Qualified ProperName, (DataDeclType, ProperName, Type)) -> (ModuleName, ProperName)
241− typeConstructor (Qualified (Just mn) _, (_, tyCtor, _)) = (mn, tyCtor)
242− typeConstructor _ = error "Invalid argument to typeConstructor"
src/Language/PureScript/CoreFn/Expr.hs+42−5
@@ -13,14 +13,16 @@
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15{-# LANGUAGE DeriveDataTypeable #-}
15{-# LANGUAGE DeriveDataTypeable #-}
16+{-# LANGUAGE DeriveFunctor #-}
16
17
17module Language.PureScript.CoreFn.Expr where
18module Language.PureScript.CoreFn.Expr where
18
19
20+import Control.Arrow ((***))
21+
19import qualified Data.Data as D
22import qualified Data.Data as D
20
23
21import Language.PureScript.CoreFn.Binders
24import Language.PureScript.CoreFn.Binders
22import Language.PureScript.CoreFn.Literals
25import Language.PureScript.CoreFn.Literals
23−import Language.PureScript.CoreFn.Meta
24import Language.PureScript.Names
26import Language.PureScript.Names
25
27
26-- |
28-- |
@@ -32,9 +34,9 @@ data Expr a
32 --
34 --
33 = Literal a (Literal (Expr a))
35 = Literal a (Literal (Expr a))
34 -- |
36 -- |
35− -- A data constructor (type name, constructor name, arity)
37+ -- A data constructor (type name, constructor name, field names)
36 --
38 --
37− | Constructor a ProperName ProperName Arity
39+ | Constructor a ProperName ProperName [Ident]
38 -- |
40 -- |
39 -- A record property accessor
41 -- A record property accessor
40 --
42 --
@@ -62,7 +64,7 @@ data Expr a
62 -- |
64 -- |
63 -- A let binding
65 -- A let binding
64 --
66 --
65− | Let a [Bind a] (Expr a) deriving (Show, D.Data, D.Typeable)
67+ | Let a [Bind a] (Expr a) deriving (Show, D.Data, D.Typeable, Functor)
66
68
67-- |
69-- |
68-- A let or module binding.
70-- A let or module binding.
@@ -75,7 +77,7 @@ data Bind a
75 -- |
77 -- |
76 -- Mutually recursive binding group for several values
78 -- Mutually recursive binding group for several values
77 --
79 --
78− | Rec [(Ident, Expr a)] deriving (Show, D.Data, D.Typeable)
80+ | Rec [(Ident, Expr a)] deriving (Show, D.Data, D.Typeable, Functor)
79
81
80-- |
82-- |
81-- A guard is just a boolean-valued expression that appears alongside a set of binders
83-- A guard is just a boolean-valued expression that appears alongside a set of binders
@@ -95,3 +97,38 @@ data CaseAlternative a = CaseAlternative
95 --
97 --
96 , caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a)
98 , caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a)
97 } deriving (Show, D.Data, D.Typeable)
99 } deriving (Show, D.Data, D.Typeable)
100+
101+instance Functor CaseAlternative where
102+
103+ fmap f (CaseAlternative cabs car) = CaseAlternative
104+ (fmap (fmap f) $ cabs)
105+ (either (Left . fmap (fmap f *** fmap f)) (Right . fmap f) car)
106+
107+-- |
108+-- Extract the annotation from a term
109+--
110+extractAnn :: Expr a -> a
111+extractAnn (Literal a _) = a
112+extractAnn (Constructor a _ _ _) = a
113+extractAnn (Accessor a _ _) = a
114+extractAnn (ObjectUpdate a _ _) = a
115+extractAnn (Abs a _ _) = a
116+extractAnn (App a _ _) = a
117+extractAnn (Var a _) = a
118+extractAnn (Case a _ _) = a
119+extractAnn (Let a _ _) = a
120+
121+
122+-- |
123+-- Modify the annotation on a term
124+--
125+modifyAnn :: (a -> a) -> Expr a -> Expr a
126+modifyAnn f (Literal a b) = Literal (f a) b
127+modifyAnn f (Constructor a b c d) = Constructor (f a) b c d
128+modifyAnn f (Accessor a b c) = Accessor (f a) b c
129+modifyAnn f (ObjectUpdate a b c) = ObjectUpdate (f a) b c
130+modifyAnn f (Abs a b c) = Abs (f a) b c
131+modifyAnn f (App a b c) = App (f a) b c
132+modifyAnn f (Var a b) = Var (f a) b
133+modifyAnn f (Case a b c) = Case (f a) b c
134+modifyAnn f (Let a b c) = Let (f a) b c
src/Language/PureScript/CoreFn/Literals.hs+2−1
@@ -13,6 +13,7 @@
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15{-# LANGUAGE DeriveDataTypeable #-}
15{-# LANGUAGE DeriveDataTypeable #-}
16+{-# LANGUAGE DeriveFunctor #-}
16
17
17module Language.PureScript.CoreFn.Literals where
18module Language.PureScript.CoreFn.Literals where
18
19
@@ -42,4 +43,4 @@ data Literal a
42 -- |
43 -- |
43 -- An object literal
44 -- An object literal
44 --
45 --
45− | ObjectLiteral [(String, a)] deriving (Show, D.Data, D.Typeable)
46+ | ObjectLiteral [(String, a)] deriving (Show, D.Data, D.Typeable, Functor)
src/Language/PureScript/CoreFn/Meta.hs+3−6
@@ -18,6 +18,8 @@ module Language.PureScript.CoreFn.Meta where
18
18
19import qualified Data.Data as D
19import qualified Data.Data as D
20
20
21+import Language.PureScript.Names
22+
21-- |
23-- |
22-- Metadata annotations
24-- Metadata annotations
23--
25--
@@ -25,7 +27,7 @@ data Meta
25 -- |
27 -- |
26 -- The contained value is a data constructor
28 -- The contained value is a data constructor
27 --
29 --
28− = IsConstructor ConstructorType Arity
30+ = IsConstructor ConstructorType [Ident]
29 -- |
31 -- |
30 -- The contained value is a newtype
32 -- The contained value is a newtype
31 --
33 --
@@ -35,11 +37,6 @@ data Meta
35 --
37 --
36 | IsTypeClassConstructor deriving (Show, D.Data, D.Typeable)
38 | IsTypeClassConstructor deriving (Show, D.Data, D.Typeable)
37
39
38−-- |
39−-- Type alias for constructor arity
40−--
41−type Arity = Int
42−
43-- |
40-- |
44-- Data constructor metadata
41-- Data constructor metadata
45--
42--
src/Language/PureScript/Environment.hs+10−5
@@ -41,7 +41,7 @@ data Environment = Environment {
41 -- |
41 -- |
42 -- Data constructors currently in scope, along with their associated data type constructors
42 -- Data constructors currently in scope, along with their associated data type constructors
43 --
43 --
44− , dataConstructors :: M.Map (Qualified ProperName) (DataDeclType, ProperName, Type)
44+ , dataConstructors :: M.Map (Qualified ProperName) (DataDeclType, ProperName, Type, [Ident])
45 -- |
45 -- |
46 -- Type synonyms currently in scope
46 -- Type synonyms currently in scope
47 --
47 --
@@ -136,7 +136,12 @@ data TypeKind
136 -- |
136 -- |
137 -- A local type variable
137 -- A local type variable
138 --
138 --
139+ | LocalTypeVariable
140+ -- |
141+ -- A scoped type variable
142+ --
143+ | ScopedTypeVar
139− | LocalTypeVariable deriving (Show, Eq, Data, Typeable)
144+ deriving (Show, Eq, Data, Typeable)
140
145
141-- |
146-- |
142-- The type ('data' or 'newtype') of a data type declaration
147-- The type ('data' or 'newtype') of a data type declaration
@@ -223,7 +228,7 @@ primTypes = M.fromList [ (primName "Function" , (FunKind Star (FunKind Star Star
223-- |
228-- |
224-- Finds information about data constructors from the current environment.
229-- Finds information about data constructors from the current environment.
225--
230--
226−lookupConstructor :: Environment -> Qualified ProperName -> (DataDeclType, ProperName, Type)
231+lookupConstructor :: Environment -> Qualified ProperName -> (DataDeclType, ProperName, Type, [Ident])
227lookupConstructor env ctor =
232lookupConstructor env ctor =
228 fromMaybe (error "Data constructor not found") $ ctor `M.lookup` dataConstructors env
233 fromMaybe (error "Data constructor not found") $ ctor `M.lookup` dataConstructors env
229
234
@@ -232,5 +237,5 @@ lookupConstructor env ctor =
232--
237--
233isNewtypeConstructor :: Environment -> Qualified ProperName -> Bool
238isNewtypeConstructor :: Environment -> Qualified ProperName -> Bool
234isNewtypeConstructor e ctor = case lookupConstructor e ctor of
239isNewtypeConstructor e ctor = case lookupConstructor e ctor of
235− (Newtype, _, _) -> True
240+ (Newtype, _, _, _) -> True
236− (Data, _, _) -> False
241+ (Data, _, _, _) -> False
src/Language/PureScript/Errors.hs+28−15
@@ -17,10 +17,11 @@
17module Language.PureScript.Errors where
17module Language.PureScript.Errors where
18
18
19import Data.Either (lefts, rights)
19import Data.Either (lefts, rights)
20+import Data.String (IsString(..))
20import Data.List (intersperse, intercalate)
21import Data.List (intersperse, intercalate)
21import Data.Monoid
22import Data.Monoid
22
23
23−import Control.Monad.Error
24+import Control.Monad.Except
24import Control.Applicative ((<$>))
25import Control.Applicative ((<$>))
25
26
26import Language.PureScript.AST
27import Language.PureScript.AST
@@ -67,15 +68,14 @@ data ErrorStack
67 = ErrorStack { runErrorStack :: [CompileError] }
68 = ErrorStack { runErrorStack :: [CompileError] }
68 | MultipleErrors [ErrorStack] deriving (Show)
69 | MultipleErrors [ErrorStack] deriving (Show)
69
70
70−instance Monoid ErrorStack where
71+-- TODO: Remove strMsg, the IsString instance, and unnecessary
71− mempty = ErrorStack []
72+-- OverloadedStrings pragmas. See #745
72− mappend (ErrorStack xs) (ErrorStack ys) = ErrorStack (xs ++ ys)
73+-- | Create an ErrorStack from a string
73− mappend (MultipleErrors es) x = MultipleErrors [ e <> x | e <- es ]
74+strMsg :: String -> ErrorStack
74− mappend x (MultipleErrors es) = MultipleErrors [ x <> e | e <- es ]
75+strMsg s = ErrorStack [CompileError s Nothing Nothing]
75
76
76−instance Error ErrorStack where
77+instance IsString ErrorStack where
77− strMsg s = ErrorStack [CompileError s Nothing Nothing]
78+ fromString = strMsg
78− noMsg = ErrorStack []
79
79
80prettyPrintErrorStack :: Bool -> ErrorStack -> String
80prettyPrintErrorStack :: Bool -> ErrorStack -> String
81prettyPrintErrorStack printFullStack (ErrorStack es) =
81prettyPrintErrorStack printFullStack (ErrorStack es) =
@@ -95,8 +95,8 @@ prettyPrintErrorStack printFullStack (ErrorStack es) =
95prettyPrintErrorStack printFullStack (MultipleErrors es) =
95prettyPrintErrorStack printFullStack (MultipleErrors es) =
96 unlines $ intersperse "" $ "Multiple errors:" : map (prettyPrintErrorStack printFullStack) es
96 unlines $ intersperse "" $ "Multiple errors:" : map (prettyPrintErrorStack printFullStack) es
97
97
98−stringifyErrorStack :: Bool -> Either ErrorStack a -> Either String a
98+stringifyErrorStack :: (MonadError String m) => Bool -> Either ErrorStack a -> m a
99−stringifyErrorStack printFullStack = either (Left . prettyPrintErrorStack printFullStack) Right
99+stringifyErrorStack printFullStack = either (throwError . prettyPrintErrorStack printFullStack) return
100
100
101isErrorNonEmpty :: CompileError -> Bool
101isErrorNonEmpty :: CompileError -> Bool
102isErrorNonEmpty = not . null . compileErrorMessage
102isErrorNonEmpty = not . null . compileErrorMessage
@@ -107,10 +107,13 @@ showError (CompileError msg (Just (ExprError val)) _) = "Error in expression " +
107showError (CompileError msg (Just (TypeError ty)) _) = "Error in type " ++ prettyPrintType ty ++ ":\n" ++ msg
107showError (CompileError msg (Just (TypeError ty)) _) = "Error in type " ++ prettyPrintType ty ++ ":\n" ++ msg
108
108
109mkErrorStack :: String -> Maybe ErrorSource -> ErrorStack
109mkErrorStack :: String -> Maybe ErrorSource -> ErrorStack
110−mkErrorStack msg t = ErrorStack [CompileError msg t Nothing]
110+mkErrorStack msg t = ErrorStack [mkCompileError msg t]
111
111
112+mkCompileError :: String -> Maybe ErrorSource -> CompileError
113+mkCompileError msg t = CompileError msg t Nothing
114+
112−positionError :: SourceSpan -> ErrorStack
115+positionError :: SourceSpan -> CompileError
113−positionError pos = ErrorStack [CompileError "" Nothing (Just pos)]
116+positionError pos = CompileError "" Nothing (Just pos)
114
117
115-- |
118-- |
116-- Rethrow an error with a more detailed error message in the case of failure
119-- Rethrow an error with a more detailed error message in the case of failure
@@ -122,7 +125,7 @@ rethrow f = flip catchError $ \e -> throwError (f e)
122-- Rethrow an error with source position information
125-- Rethrow an error with source position information
123--
126--
124rethrowWithPosition :: (MonadError ErrorStack m) => SourceSpan -> m a -> m a
127rethrowWithPosition :: (MonadError ErrorStack m) => SourceSpan -> m a -> m a
125−rethrowWithPosition pos = rethrow (positionError pos <>)
128+rethrowWithPosition pos = rethrow (positionError pos `combineErrors`)
126
129
127-- |
130-- |
128-- Collect errors in in parallel
131-- Collect errors in in parallel
@@ -138,3 +141,13 @@ parU xs f = forM xs (withError . f) >>= collectErrors
138 [err] -> throwError err
141 [err] -> throwError err
139 [] -> return $ rights es
142 [] -> return $ rights es
140 errs -> throwError $ MultipleErrors errs
143 errs -> throwError $ MultipleErrors errs
144+
145+-- |
146+-- Add an extra error string onto the top of each error stack in a list of possibly many errors
147+--
148+combineErrors :: CompileError -> ErrorStack -> ErrorStack
149+combineErrors ce err = go (ErrorStack [ce]) err
150+ where
151+ go (ErrorStack xs) (ErrorStack ys) = ErrorStack (xs ++ ys)
152+ go (MultipleErrors es) x = MultipleErrors [ go e x | e <- es ]
153+ go x (MultipleErrors es) = MultipleErrors [ go x e | e <- es ]
src/Language/PureScript/ModuleDependencies.hs+7−7
@@ -12,11 +12,15 @@
12--
12--
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15+{-# LANGUAGE FlexibleContexts #-}
16+
15module Language.PureScript.ModuleDependencies (
17module Language.PureScript.ModuleDependencies (
16 sortModules,
18 sortModules,
17 ModuleGraph
19 ModuleGraph
18) where
20) where
19
21
22+import Control.Monad.Except
23+
20import Data.Graph
24import Data.Graph
21import Data.List (nub)
25import Data.List (nub)
22import Data.Maybe (mapMaybe)
26import Data.Maybe (mapMaybe)
@@ -35,7 +39,7 @@ type ModuleGraph = [(ModuleName, [ModuleName])]
35--
39--
36-- Reports an error if the module graph contains a cycle.
40-- Reports an error if the module graph contains a cycle.
37--
41--
38−sortModules :: [Module] -> Either String ([Module], ModuleGraph)
42+sortModules :: (MonadError String m) => [Module] -> m ([Module], ModuleGraph)
39sortModules ms = do
43sortModules ms = do
40 let verts = map (\m@(Module _ ds _) -> (m, getModuleName m, nub (concatMap usedModules ds))) ms
44 let verts = map (\m@(Module _ ds _) -> (m, getModuleName m, nub (concatMap usedModules ds))) ms
41 ms' <- mapM toModule $ stronglyConnComp verts
45 ms' <- mapM toModule $ stronglyConnComp verts
@@ -54,7 +58,6 @@ usedModules = let (f, _, _, _, _) = everythingOnValues (++) forDecls forValues (
54
58
55 forValues :: Expr -> [ModuleName]
59 forValues :: Expr -> [ModuleName]
56 forValues (Var (Qualified (Just mn) _)) = [mn]
60 forValues (Var (Qualified (Just mn) _)) = [mn]
57− forValues (BinaryNoParens (Qualified (Just mn) _) _ _) = [mn]
58 forValues (Constructor (Qualified (Just mn) _)) = [mn]
61 forValues (Constructor (Qualified (Just mn) _)) = [mn]
59 forValues (TypedValue _ _ ty) = forTypes ty
62 forValues (TypedValue _ _ ty) = forTypes ty
60 forValues _ = []
63 forValues _ = []
@@ -64,13 +67,10 @@ usedModules = let (f, _, _, _, _) = everythingOnValues (++) forDecls forValues (
64 forTypes (ConstrainedType cs _) = mapMaybe (\(Qualified mn _, _) -> mn) cs
67 forTypes (ConstrainedType cs _) = mapMaybe (\(Qualified mn _, _) -> mn) cs
65 forTypes _ = []
68 forTypes _ = []
66
69
67−getModuleName :: Module -> ModuleName
68−getModuleName (Module mn _ _) = mn
69−
70-- |
70-- |
71-- Convert a strongly connected component of the module graph to a module
71-- Convert a strongly connected component of the module graph to a module
72--
72--
73−toModule :: SCC Module -> Either String Module
73+toModule :: (MonadError String m) => SCC Module -> m Module
74toModule (AcyclicSCC m) = return m
74toModule (AcyclicSCC m) = return m
75toModule (CyclicSCC [m]) = return m
75toModule (CyclicSCC [m]) = return m
76−toModule (CyclicSCC ms) = Left $ "Cycle in module dependencies: " ++ show (map getModuleName ms)
76+toModule (CyclicSCC ms) = throwError $ "Cycle in module dependencies: " ++ show (map getModuleName ms)
src/Language/PureScript/Options.hs+5−2
@@ -69,6 +69,9 @@ data Options mode = Options {
69 -- Verbose error message
69 -- Verbose error message
70 --
70 --
71 , optionsVerboseErrors :: Bool
71 , optionsVerboseErrors :: Bool
72+ -- |
73+ -- Remove the comments from the generated js
74+ , optionsNoComments :: Bool
72 -- |
75 -- |
73 -- Specify the namespace that PureScript modules will be exported to when running in the
76 -- Specify the namespace that PureScript modules will be exported to when running in the
74 -- browser.
77 -- browser.
@@ -80,10 +83,10 @@ data Options mode = Options {
80-- Default compiler options
83-- Default compiler options
81--
84--
82defaultCompileOptions :: Options Compile
85defaultCompileOptions :: Options Compile
83−defaultCompileOptions = Options False False False Nothing False False (CompileOptions "PS" [] [])
86+defaultCompileOptions = Options False False False Nothing False False False (CompileOptions "PS" [] [])
84
87
85-- |
88-- |
86-- Default make options
89-- Default make options
87--
90--
88defaultMakeOptions :: Options Make
91defaultMakeOptions :: Options Make
89−defaultMakeOptions = Options False False False Nothing False False MakeOptions
92+defaultMakeOptions = Options False False False Nothing False False False MakeOptions
src/Language/PureScript/Parser.hs+1−1
@@ -32,4 +32,4 @@ import Language.PureScript.Parser.Types as P
32import Language.PureScript.Parser.State as P
32import Language.PureScript.Parser.State as P
33import Language.PureScript.Parser.Kinds as P
33import Language.PureScript.Parser.Kinds as P
34import Language.PureScript.Parser.Lexer as P
34import Language.PureScript.Parser.Lexer as P
35−import Language.PureScript.Parser.Declarations as P
35+import Language.PureScript.Parser.Declarations as P
src/Language/PureScript/Parser/Common.hs+7−6
@@ -20,6 +20,7 @@ module Language.PureScript.Parser.Common where
20import Control.Applicative
20import Control.Applicative
21import Control.Monad (guard)
21import Control.Monad (guard)
22
22
23+import Language.PureScript.Comments
23import Language.PureScript.Parser.Lexer
24import Language.PureScript.Parser.Lexer
24import Language.PureScript.Parser.State
25import Language.PureScript.Parser.State
25import Language.PureScript.Names
26import Language.PureScript.Names
@@ -87,12 +88,6 @@ buildPostfixParser fs first = do
87 Nothing -> return a
88 Nothing -> return a
88 Just a' -> go a'
89 Just a' -> go a'
89
90
90−-- |
91−-- Parse an identifier in backticks or an operator
92−--
93−parseIdentInfix :: TokenParser (Qualified Ident)
94−parseIdentInfix = P.between tick tick (parseQualified (Ident <$> identifier)) <|> (parseQualified (Op <$> symbol))
95−
96-- |
91-- |
97-- Mark the current indentation level
92-- Mark the current indentation level
98--
93--
@@ -126,6 +121,12 @@ indented = checkIndentation (>) P.<?> "indentation"
126same :: P.Parsec s ParseState ()
121same :: P.Parsec s ParseState ()
127same = checkIndentation (==) P.<?> "no indentation"
122same = checkIndentation (==) P.<?> "no indentation"
128
123
124+-- |
125+-- Read the comments from the the next token, without consuming it
126+--
127+readComments :: P.Parsec [PositionedToken] u [Comment]
128+readComments = P.lookAhead $ ptComments <$> P.anyToken
129+
129-- |
130-- |
130-- Run a parser
131-- Run a parser
131--
132--
src/Language/PureScript/Parser/Declarations.hs+42−12
@@ -35,11 +35,13 @@ import Control.Applicative
35import Control.Arrow ((+++))
35import Control.Arrow ((+++))
36
36
37import Language.PureScript.Kinds
37import Language.PureScript.Kinds
38−import Language.PureScript.Parser.Common
39import Language.PureScript.AST
38import Language.PureScript.AST
39+import Language.PureScript.Comments
40+import Language.PureScript.Parser.Common
40import Language.PureScript.Parser.Types
41import Language.PureScript.Parser.Types
41import Language.PureScript.Parser.Kinds
42import Language.PureScript.Parser.Kinds
42import Language.PureScript.Parser.Lexer
43import Language.PureScript.Parser.Lexer
44+import Language.PureScript.Names
43import Language.PureScript.CodeGen.JS.AST
45import Language.PureScript.CodeGen.JS.AST
44import Language.PureScript.Environment
46import Language.PureScript.Environment
45
47
@@ -50,13 +52,14 @@ import qualified Text.Parsec.Expr as P
50-- |
52-- |
51-- Read source position information
53-- Read source position information
52--
54--
53−withSourceSpan :: (SourceSpan -> a -> a) -> P.Parsec s u a -> P.Parsec s u a
55+withSourceSpan :: (SourceSpan -> [Comment] -> a -> a) -> P.Parsec [PositionedToken] u a -> P.Parsec [PositionedToken] u a
54withSourceSpan f p = do
56withSourceSpan f p = do
55 start <- P.getPosition
57 start <- P.getPosition
58+ comments <- C.readComments
56 x <- p
59 x <- p
57 end <- P.getPosition
60 end <- P.getPosition
58 let sp = SourceSpan (P.sourceName start) (toSourcePos start) (toSourcePos end)
61 let sp = SourceSpan (P.sourceName start) (toSourcePos start) (toSourcePos end)
59− return $ f sp x
62+ return $ f sp comments x
60 where
63 where
61 toSourcePos pos = SourcePos (P.sourceLine pos) (P.sourceColumn pos)
64 toSourcePos pos = SourcePos (P.sourceLine pos) (P.sourceColumn pos)
62
65
@@ -283,11 +286,13 @@ parseArrayLiteral :: TokenParser Expr
283parseArrayLiteral = ArrayLiteral <$> squares (commaSep parseValue)
286parseArrayLiteral = ArrayLiteral <$> squares (commaSep parseValue)
284
287
285parseObjectLiteral :: TokenParser Expr
288parseObjectLiteral :: TokenParser Expr
286−parseObjectLiteral = ObjectLiteral <$> braces (commaSep parseIdentifierAndValue)
289+parseObjectLiteral = ObjectConstructor <$> braces (commaSep parseIdentifierAndValue)
287
290
288−parseIdentifierAndValue :: TokenParser (String, Expr)
291+parseIdentifierAndValue :: TokenParser (String, Maybe Expr)
289parseIdentifierAndValue = (,) <$> (C.indented *> (lname <|> stringLiteral) <* C.indented <* colon)
292parseIdentifierAndValue = (,) <$> (C.indented *> (lname <|> stringLiteral) <* C.indented <* colon)
290− <*> (C.indented *> parseValue)
293+ <*> (C.indented *> val)
294+ where
295+ val = (Just <$> parseValue) <|> (underscore *> pure Nothing)
291
296
292parseAbs :: TokenParser Expr
297parseAbs :: TokenParser Expr
293parseAbs = do
298parseAbs = do
@@ -341,6 +346,7 @@ parseValueAtom = P.choice
341 , P.try parseBooleanLiteral
346 , P.try parseBooleanLiteral
342 , parseArrayLiteral
347 , parseArrayLiteral
343 , P.try parseObjectLiteral
348 , P.try parseObjectLiteral
349+ , P.try parseObjectGetter
344 , parseAbs
350 , parseAbs
345 , P.try parseConstructor
351 , P.try parseConstructor
346 , P.try parseVar
352 , P.try parseVar
@@ -348,13 +354,28 @@ parseValueAtom = P.choice
348 , parseIfThenElse
354 , parseIfThenElse
349 , parseDo
355 , parseDo
350 , parseLet
356 , parseLet
351− , Parens <$> parens parseValue ]
357+ , P.try $ Parens <$> parens parseValue
358+ , parseOperatorSection
359+ , P.try parseObjectUpdaterWildcard ]
360+
361+-- |
362+-- Parse an expression in backticks or an operator
363+--
364+parseInfixExpr :: TokenParser Expr
365+parseInfixExpr = P.between tick tick parseValue
366+ <|> Var <$> parseQualified (Op <$> symbol)
352
367
368+parseOperatorSection :: TokenParser Expr
369+parseOperatorSection = parens $ left <|> right
370+ where
371+ right = OperatorSection <$> parseInfixExpr <* indented <*> (Right <$> parseValueAtom)
372+ left = flip OperatorSection <$> (Left <$> parseValueAtom) <* indented <*> parseInfixExpr
373+
353−parsePropertyUpdate :: TokenParser (String, Expr)
374+parsePropertyUpdate :: TokenParser (String, Maybe Expr)
354parsePropertyUpdate = do
375parsePropertyUpdate = do
355 name <- lname <|> stringLiteral
376 name <- lname <|> stringLiteral
356 _ <- C.indented *> equals
377 _ <- C.indented *> equals
357− value <- C.indented *> parseValue
378+ value <- C.indented *> (underscore *> pure Nothing) <|> (Just <$> parseValue)
358 return (name, value)
379 return (name, value)
359
380
360parseAccessor :: Expr -> TokenParser Expr
381parseAccessor :: Expr -> TokenParser Expr
@@ -379,6 +400,9 @@ parseDoNotationElement = P.choice
379 , parseDoNotationLet
400 , parseDoNotationLet
380 , P.try (DoNotationValue <$> parseValue) ]
401 , P.try (DoNotationValue <$> parseValue) ]
381
402
403+parseObjectGetter :: TokenParser Expr
404+parseObjectGetter = ObjectGetter <$> (underscore *> C.indented *> dot *> C.indented *> (lname <|> stringLiteral))
405+
382-- |
406-- |
383-- Parse a value
407-- Parse a value
384--
408--
@@ -390,17 +414,23 @@ parseValue = withSourceSpan PositionedValue
390 where
414 where
391 indexersAndAccessors = C.buildPostfixParser postfixTable1 parseValueAtom
415 indexersAndAccessors = C.buildPostfixParser postfixTable1 parseValueAtom
392 postfixTable1 = [ parseAccessor
416 postfixTable1 = [ parseAccessor
393− , \v -> P.try $ flip ObjectUpdate <$> (C.indented *> braces (commaSep1 (C.indented *> parsePropertyUpdate))) <*> pure v ]
417+ , P.try . parseUpdaterBody . Just ]
394 postfixTable2 = [ \v -> P.try (flip App <$> (C.indented *> indexersAndAccessors)) <*> pure v
418 postfixTable2 = [ \v -> P.try (flip App <$> (C.indented *> indexersAndAccessors)) <*> pure v
395 , \v -> flip (TypedValue True) <$> (P.try (C.indented *> doubleColon) *> parsePolyType) <*> pure v
419 , \v -> flip (TypedValue True) <$> (P.try (C.indented *> doubleColon) *> parsePolyType) <*> pure v
396 ]
420 ]
397 operators = [ [ P.Prefix (P.try (C.indented *> symbol' "-") >> return UnaryMinus)
421 operators = [ [ P.Prefix (P.try (C.indented *> symbol' "-") >> return UnaryMinus)
398 ]
422 ]
399− , [ P.Infix (P.try (C.indented *> C.parseIdentInfix P.<?> "operator") >>= \ident ->
423+ , [ P.Infix (P.try (C.indented *> parseInfixExpr P.<?> "infix expression") >>= \ident ->
400 return (BinaryNoParens ident)) P.AssocRight
424 return (BinaryNoParens ident)) P.AssocRight
401 ]
425 ]
402 ]
426 ]
403
427
428+parseUpdaterBody :: Maybe Expr -> TokenParser Expr
429+parseUpdaterBody v = ObjectUpdater v <$> (C.indented *> braces (commaSep1 (C.indented *> parsePropertyUpdate)))
430+
431+parseObjectUpdaterWildcard :: TokenParser Expr
432+parseObjectUpdaterWildcard = underscore *> C.indented *> parseUpdaterBody Nothing
433+
404parseStringBinder :: TokenParser Binder
434parseStringBinder :: TokenParser Binder
405parseStringBinder = StringBinder <$> stringLiteral
435parseStringBinder = StringBinder <$> stringLiteral
406
436
@@ -435,7 +465,7 @@ parseNamedBinder = NamedBinder <$> (C.parseIdent <* C.indented <* at)
435 <*> (C.indented *> parseBinder)
465 <*> (C.indented *> parseBinder)
436
466
437parseNullBinder :: TokenParser Binder
467parseNullBinder :: TokenParser Binder
438−parseNullBinder = reserved "_" *> return NullBinder
468+parseNullBinder = underscore *> return NullBinder
439
469
440parseIdentifierAndBinder :: TokenParser (String, Binder)
470parseIdentifierAndBinder :: TokenParser (String, Binder)
441parseIdentifierAndBinder = do
471parseIdentifierAndBinder = do
src/Language/PureScript/Parser/Lexer.hs+44−34
@@ -15,11 +15,12 @@
15
15
16{-# LANGUAGE TupleSections #-}
16{-# LANGUAGE TupleSections #-}
17
17
18−module Language.PureScript.Parser.Lexer
18+module Language.PureScript.Parser.Lexer
19 ( PositionedToken(..)
19 ( PositionedToken(..)
20 , Token()
20 , Token()
21 , TokenParser()
21 , TokenParser()
22 , lex
22 , lex
23+ , anyToken
23 , token
24 , token
24 , match
25 , match
25 , lparen
26 , lparen
@@ -33,8 +34,8 @@ module Language.PureScript.Parser.Lexer
33 , squares
34 , squares
34 , indent
35 , indent
35 , indentAt
36 , indentAt
36− , larrow
37+ , larrow
37− , rarrow
38+ , rarrow
38 , lfatArrow
39 , lfatArrow
39 , rfatArrow
40 , rfatArrow
40 , colon
41 , colon
@@ -46,6 +47,7 @@ module Language.PureScript.Parser.Lexer
46 , comma
47 , comma
47 , semi
48 , semi
48 , at
49 , at
50+ , underscore
49 , semiSep
51 , semiSep
50 , semiSep1
52 , semiSep1
51 , commaSep
53 , commaSep
@@ -70,21 +72,19 @@ module Language.PureScript.Parser.Lexer
70
72
71import Prelude hiding (lex)
73import Prelude hiding (lex)
72
74
75+import Data.Char (isSpace)
76+
73import Control.Monad (void, guard)
77import Control.Monad (void, guard)
74import Data.Functor.Identity
78import Data.Functor.Identity
75
79
76import Control.Applicative
80import Control.Applicative
77
81
78import Language.PureScript.Parser.State
82import Language.PureScript.Parser.State
83+import Language.PureScript.Comments
79
84
80import qualified Text.Parsec as P
85import qualified Text.Parsec as P
81import qualified Text.Parsec.Token as PT
86import qualified Text.Parsec.Token as PT
82
87
83−data Comment
84− = LineComment String
85− | BlockComment String
86− deriving (Show, Eq, Ord)
87−
88data Token
88data Token
89 = LParen
89 = LParen
90 | RParen
90 | RParen
@@ -106,6 +106,7 @@ data Token
106 | Comma
106 | Comma
107 | Semi
107 | Semi
108 | At
108 | At
109+ | Underscore
109 | LName String
110 | LName String
110 | UName String
111 | UName String
111 | Qualifier String
112 | Qualifier String
@@ -113,7 +114,7 @@ data Token
113 | StringLiteral String
114 | StringLiteral String
114 | Number (Either Integer Double)
115 | Number (Either Integer Double)
115 deriving (Show, Eq, Ord)
116 deriving (Show, Eq, Ord)
116−
117+
117prettyPrintToken :: Token -> String
118prettyPrintToken :: Token -> String
118prettyPrintToken LParen = "("
119prettyPrintToken LParen = "("
119prettyPrintToken RParen = ")"
120prettyPrintToken RParen = ")"
@@ -134,6 +135,7 @@ prettyPrintToken Dot = "."
134prettyPrintToken Comma = ","
135prettyPrintToken Comma = ","
135prettyPrintToken Semi = ";"
136prettyPrintToken Semi = ";"
136prettyPrintToken At = "@"
137prettyPrintToken At = "@"
138+prettyPrintToken Underscore = "_"
137prettyPrintToken (Indent n) = "indentation at level " ++ show n
139prettyPrintToken (Indent n) = "indentation at level " ++ show n
138prettyPrintToken (LName s) = show s
140prettyPrintToken (LName s) = show s
139prettyPrintToken (UName s) = show s
141prettyPrintToken (UName s) = show s
@@ -147,19 +149,19 @@ data PositionedToken = PositionedToken
147 , ptToken :: Token
149 , ptToken :: Token
148 , ptComments :: [Comment]
150 , ptComments :: [Comment]
149 } deriving (Eq)
151 } deriving (Eq)
150−
152+
151instance Show PositionedToken where
153instance Show PositionedToken where
152 show = show . ptToken
154 show = show . ptToken
153
155
154lex :: FilePath -> String -> Either P.ParseError [PositionedToken]
156lex :: FilePath -> String -> Either P.ParseError [PositionedToken]
155lex filePath input = P.parse parseTokens filePath input
157lex filePath input = P.parse parseTokens filePath input
156−
158+
157parseTokens :: P.Parsec String u [PositionedToken]
159parseTokens :: P.Parsec String u [PositionedToken]
158parseTokens = whitespace *> P.many parsePositionedToken <* P.skipMany parseComment <* P.eof
160parseTokens = whitespace *> P.many parsePositionedToken <* P.skipMany parseComment <* P.eof
159
161
160whitespace :: P.Parsec String u ()
162whitespace :: P.Parsec String u ()
161−whitespace = P.skipMany (P.oneOf " \t\r\n")
163+whitespace = P.skipMany (P.satisfy isSpace)
162−
164+
163parseComment :: P.Parsec String u Comment
165parseComment :: P.Parsec String u Comment
164parseComment = (BlockComment <$> blockComment <|> LineComment <$> lineComment) <* whitespace
166parseComment = (BlockComment <$> blockComment <|> LineComment <$> lineComment) <* whitespace
165 where
167 where
@@ -178,11 +180,11 @@ parsePositionedToken = P.try $ do
178
180
179parseToken :: P.Parsec String u Token
181parseToken :: P.Parsec String u Token
180parseToken = P.choice
182parseToken = P.choice
181− [ P.try $ P.string "<-" *> P.notFollowedBy symbolChar *> pure LArrow
183+ [ P.try $ P.string "<-" *> P.notFollowedBy symbolChar *> pure LArrow
182 , P.try $ P.string "<=" *> P.notFollowedBy symbolChar *> pure LFatArrow
184 , P.try $ P.string "<=" *> P.notFollowedBy symbolChar *> pure LFatArrow
183− , P.try $ P.string "->" *> P.notFollowedBy symbolChar *> pure RArrow
185+ , P.try $ P.string "->" *> P.notFollowedBy symbolChar *> pure RArrow
184− , P.try $ P.string "=>" *> P.notFollowedBy symbolChar *> pure RFatArrow
186+ , P.try $ P.string "=>" *> P.notFollowedBy symbolChar *> pure RFatArrow
185− , P.try $ P.string "::" *> P.notFollowedBy symbolChar *> pure DoubleColon
187+ , P.try $ P.string "::" *> P.notFollowedBy symbolChar *> pure DoubleColon
186 , P.try $ P.char '(' *> pure LParen
188 , P.try $ P.char '(' *> pure LParen
187 , P.try $ P.char ')' *> pure RParen
189 , P.try $ P.char ')' *> pure RParen
188 , P.try $ P.char '{' *> pure LBrace
190 , P.try $ P.char '{' *> pure LBrace
@@ -197,10 +199,11 @@ parseToken = P.choice
197 , P.try $ P.char '.' *> P.notFollowedBy symbolChar *> pure Dot
199 , P.try $ P.char '.' *> P.notFollowedBy symbolChar *> pure Dot
198 , P.try $ P.char ';' *> P.notFollowedBy symbolChar *> pure Semi
200 , P.try $ P.char ';' *> P.notFollowedBy symbolChar *> pure Semi
199 , P.try $ P.char '@' *> P.notFollowedBy symbolChar *> pure At
201 , P.try $ P.char '@' *> P.notFollowedBy symbolChar *> pure At
202+ , P.try $ P.char '_' *> P.notFollowedBy identLetter *> pure Underscore
200− , LName <$> parseLName
203+ , LName <$> parseLName
201 , do uName <- parseUName
204 , do uName <- parseUName
202 (guard (validModuleName uName) >> Qualifier uName <$ P.char '.') <|> pure (UName uName)
205 (guard (validModuleName uName) >> Qualifier uName <$ P.char '.') <|> pure (UName uName)
203− , Symbol <$> parseSymbol
206+ , Symbol <$> parseSymbol
204 , StringLiteral <$> parseStringLiteral
207 , StringLiteral <$> parseStringLiteral
205 , Number <$> parseNumber
208 , Number <$> parseNumber
206 ] <* whitespace
209 ] <* whitespace
@@ -208,16 +211,16 @@ parseToken = P.choice
208 where
211 where
209 parseLName :: P.Parsec String u String
212 parseLName :: P.Parsec String u String
210 parseLName = (:) <$> identStart <*> P.many identLetter
213 parseLName = (:) <$> identStart <*> P.many identLetter
211−
214+
212 parseUName :: P.Parsec String u String
215 parseUName :: P.Parsec String u String
213 parseUName = (:) <$> P.upper <*> P.many uidentLetter
216 parseUName = (:) <$> P.upper <*> P.many uidentLetter
214−
217+
215 parseSymbol :: P.Parsec String u String
218 parseSymbol :: P.Parsec String u String
216 parseSymbol = P.many1 symbolChar
219 parseSymbol = P.many1 symbolChar
217−
220+
218 identStart :: P.Parsec String u Char
221 identStart :: P.Parsec String u Char
219 identStart = P.lower <|> P.oneOf "_"
222 identStart = P.lower <|> P.oneOf "_"
220−
223+
221 identLetter :: P.Parsec String u Char
224 identLetter :: P.Parsec String u Char
222 identLetter = P.alphaNum <|> P.oneOf "_'"
225 identLetter = P.alphaNum <|> P.oneOf "_'"
223
226
@@ -226,13 +229,13 @@ parseToken = P.choice
226
229
227 symbolChar :: P.Parsec String u Char
230 symbolChar :: P.Parsec String u Char
228 symbolChar = P.oneOf opChars
231 symbolChar = P.oneOf opChars
229−
232+
230 parseStringLiteral :: P.Parsec String u String
233 parseStringLiteral :: P.Parsec String u String
231 parseStringLiteral = blockString <|> PT.stringLiteral tokenParser
234 parseStringLiteral = blockString <|> PT.stringLiteral tokenParser
232− where
235+ where
233 delimeter = P.try (P.string "\"\"\"")
236 delimeter = P.try (P.string "\"\"\"")
234 blockString = delimeter >> P.manyTill P.anyChar delimeter
237 blockString = delimeter >> P.manyTill P.anyChar delimeter
235−
238+
236 parseNumber :: P.Parsec String u (Either Integer Double)
239 parseNumber :: P.Parsec String u (Either Integer Double)
237 parseNumber = (Right <$> P.try (PT.float tokenParser) <|>
240 parseNumber = (Right <$> P.try (PT.float tokenParser) <|>
238 Left <$> P.try (PT.natural tokenParser)) P.<?> "number"
241 Left <$> P.try (PT.natural tokenParser)) P.<?> "number"
@@ -262,7 +265,10 @@ tokenParser :: PT.GenTokenParser String u Identity
262tokenParser = PT.makeTokenParser langDef
265tokenParser = PT.makeTokenParser langDef
263
266
264type TokenParser a = P.Parsec [PositionedToken] ParseState a
267type TokenParser a = P.Parsec [PositionedToken] ParseState a
265−
268+
269+anyToken :: TokenParser PositionedToken
270+anyToken = P.token (prettyPrintToken . ptToken) ptSourcePos Just
271+
266token :: (Token -> Maybe a) -> TokenParser a
272token :: (Token -> Maybe a) -> TokenParser a
267token f = P.token (prettyPrintToken . ptToken) ptSourcePos (f . ptToken)
273token f = P.token (prettyPrintToken . ptToken) ptSourcePos (f . ptToken)
268
274
@@ -345,7 +351,10 @@ semi :: TokenParser ()
345semi = match Semi
351semi = match Semi
346
352
347at :: TokenParser ()
353at :: TokenParser ()
348−at = match At
354+at = match At
355+
356+underscore :: TokenParser ()
357+underscore = match Underscore
349
358
350-- |
359-- |
351-- Parse zero or more values separated by semicolons
360-- Parse zero or more values separated by semicolons
@@ -406,13 +415,14 @@ uname' s = token go P.<?> show s
406 where
415 where
407 go (UName s') | s == s' = Just ()
416 go (UName s') | s == s' = Just ()
408 go _ = Nothing
417 go _ = Nothing
409−
418+
410symbol :: TokenParser String
419symbol :: TokenParser String
411symbol = token go P.<?> "symbol"
420symbol = token go P.<?> "symbol"
412 where
421 where
413 go (Symbol s) = Just s
422 go (Symbol s) = Just s
414 go Colon = Just ":"
423 go Colon = Just ":"
415 go LFatArrow = Just "<="
424 go LFatArrow = Just "<="
425+ go At = Just "@"
416 go _ = Nothing
426 go _ = Nothing
417
427
418symbol' :: String -> TokenParser ()
428symbol' :: String -> TokenParser ()
@@ -422,7 +432,7 @@ symbol' s = token go P.<?> show s
422 go Colon | s == ":" = Just ()
432 go Colon | s == ":" = Just ()
423 go LFatArrow | s == "<=" = Just ()
433 go LFatArrow | s == "<=" = Just ()
424 go _ = Nothing
434 go _ = Nothing
425−
435+
426stringLiteral :: TokenParser String
436stringLiteral :: TokenParser String
427stringLiteral = token go P.<?> "string literal"
437stringLiteral = token go P.<?> "string literal"
428 where
438 where
@@ -446,10 +456,10 @@ identifier = token go P.<?> "identifier"
446 where
456 where
447 go (LName s) | s `notElem` reservedPsNames = Just s
457 go (LName s) | s `notElem` reservedPsNames = Just s
448 go _ = Nothing
458 go _ = Nothing
449−
459+
450validModuleName :: String -> Bool
460validModuleName :: String -> Bool
451validModuleName s = not ('_' `elem` s)
461validModuleName s = not ('_' `elem` s)
452−
462+
453-- |
463-- |
454-- A list of purescript reserved identifiers
464-- A list of purescript reserved identifiers
455--
465--
@@ -477,7 +487,7 @@ reservedPsNames = [ "data"
477 , "in"
487 , "in"
478 , "where"
488 , "where"
479 ]
489 ]
480−
490+
481reservedTypeNames :: [String]
491reservedTypeNames :: [String]
482reservedTypeNames = [ "forall", "where" ]
492reservedTypeNames = [ "forall", "where" ]
483
493
@@ -486,4 +496,4 @@ reservedTypeNames = [ "forall", "where" ]
486--
496--
487opChars :: [Char]
497opChars :: [Char]
488opChars = ":!#$%&*+./<=>?@\\^|-~"
498opChars = ":!#$%&*+./<=>?@\\^|-~"
489−
499+
src/Language/PureScript/Parser/Types.hs+1−1
@@ -45,7 +45,7 @@ parseObject :: TokenParser Type
45parseObject = braces $ TypeApp tyObject <$> parseRow
45parseObject = braces $ TypeApp tyObject <$> parseRow
46
46
47parseTypeWildcard :: TokenParser Type
47parseTypeWildcard :: TokenParser Type
48−parseTypeWildcard = reserved "_" >> return TypeWildcard
48+parseTypeWildcard = underscore >> return TypeWildcard
49
49
50parseTypeVariable :: TokenParser Type
50parseTypeVariable :: TokenParser Type
51parseTypeVariable = do
51parseTypeVariable = do
src/Language/PureScript/Pretty/JS.hs+45−9
@@ -29,6 +29,7 @@ import qualified Control.Arrow as A
29import Language.PureScript.CodeGen.JS.AST
29import Language.PureScript.CodeGen.JS.AST
30import Language.PureScript.CodeGen.JS.Common
30import Language.PureScript.CodeGen.JS.Common
31import Language.PureScript.Pretty.Common
31import Language.PureScript.Pretty.Common
32+import Language.PureScript.Comments
32
33
33import Numeric
34import Numeric
34
35
@@ -119,6 +120,32 @@ literals = mkPattern' match
119 [ return $ lbl ++ ": "
120 [ return $ lbl ++ ": "
120 , prettyPrintJS' js
121 , prettyPrintJS' js
121 ]
122 ]
123+ match (JSComment com js) = fmap concat $ sequence $
124+ [ return "\n"
125+ , currentIndent
126+ , return "/**\n"
127+ ] ++
128+ map asLine (concatMap commentLines com) ++
129+ [ currentIndent
130+ , return " */\n"
131+ , currentIndent
132+ , prettyPrintJS' js
133+ ]
134+ where
135+ commentLines :: Comment -> [String]
136+ commentLines (LineComment s) = [s]
137+ commentLines (BlockComment s) = lines s
138+
139+ asLine :: String -> StateT PrinterState Maybe String
140+ asLine s = do
141+ i <- currentIndent
142+ return $ i ++ " * " ++ removeComments s ++ "\n"
143+
144+ removeComments :: String -> String
145+ removeComments ('*' : '/' : s) = removeComments s
146+ removeComments (c : s) = c : removeComments s
147+
148+ removeComments [] = []
122 match (JSRaw js) = return js
149 match (JSRaw js) = return js
123 match _ = mzero
150 match _ = mzero
124
151
@@ -182,15 +209,24 @@ instanceOf = mkPattern match
182 match (JSInstanceOf val ty) = Just (val, ty)
209 match (JSInstanceOf val ty) = Just (val, ty)
183 match _ = Nothing
210 match _ = Nothing
184
211
185−unary :: UnaryOperator -> String -> Operator PrinterState JS String
212+unary' :: UnaryOperator -> (JS -> String) -> Operator PrinterState JS String
186−unary op str = Wrap match (++)
213+unary' op mkStr = Wrap match (++)
187 where
214 where
188 match :: Pattern PrinterState JS (String, JS)
215 match :: Pattern PrinterState JS (String, JS)
189 match = mkPattern match'
216 match = mkPattern match'
190 where
217 where
191− match' (JSUnary op' val) | op' == op = Just (str, val)
218+ match' (JSUnary op' val) | op' == op = Just (mkStr val, val)
192 match' _ = Nothing
219 match' _ = Nothing
193
220
221+unary :: UnaryOperator -> String -> Operator PrinterState JS String
222+unary op str = unary' op (const str)
223+
224+negateOperator :: Operator PrinterState JS String
225+negateOperator = unary' Negate (\v -> if isNegate v then "- " else "-")
226+ where
227+ isNegate (JSUnary Negate _) = True
228+ isNegate _ = False
229+
194binary :: BinaryOperator -> String -> Operator PrinterState JS String
230binary :: BinaryOperator -> String -> Operator PrinterState JS String
195binary op str = AssocL match (\v1 v2 -> v1 ++ " " ++ str ++ " " ++ v2)
231binary op str = AssocL match (\v1 v2 -> v1 ++ " " ++ str ++ " " ++ v2)
196 where
232 where
@@ -244,13 +280,13 @@ prettyPrintJS' = A.runKleisli $ runPattern matchValue
244 , [ AssocR instanceOf $ \v1 v2 -> v1 ++ " instanceof " ++ v2 ]
280 , [ AssocR instanceOf $ \v1 v2 -> v1 ++ " instanceof " ++ v2 ]
245 , [ unary Not "!" ]
281 , [ unary Not "!" ]
246 , [ unary BitwiseNot "~" ]
282 , [ unary BitwiseNot "~" ]
247− , [ unary Negate "-" ]
283+ , [ negateOperator ]
248 , [ unary Positive "+" ]
284 , [ unary Positive "+" ]
249− , [ binary Multiply "*" ]
285+ , [ binary Multiply "*"
250− , [ binary Divide "/" ]
286+ , binary Divide "/"
251− , [ binary Modulus "%" ]
287+ , binary Modulus "%" ]
252− , [ binary Add "+" ]
288+ , [ binary Add "+"
253− , [ binary Subtract "-" ]
289+ , binary Subtract "-" ]
254 , [ binary ShiftLeft "<<" ]
290 , [ binary ShiftLeft "<<" ]
255 , [ binary ShiftRight ">>" ]
291 , [ binary ShiftRight ">>" ]
256 , [ binary ZeroFillShiftRight ">>>" ]
292 , [ binary ZeroFillShiftRight ">>>" ]
src/Language/PureScript/Pretty/Types.hs+1−1
@@ -34,7 +34,7 @@ import Language.PureScript.Environment
34typeLiterals :: Pattern () Type String
34typeLiterals :: Pattern () Type String
35typeLiterals = mkPattern match
35typeLiterals = mkPattern match
36 where
36 where
37− match TypeWildcard = Just "_"
37+ match TypeWildcard = Just "_"
38 match (TypeVar var) = Just var
38 match (TypeVar var) = Just var
39 match (PrettyPrintObject row) = Just $ "{ " ++ prettyPrintRow row ++ " }"
39 match (PrettyPrintObject row) = Just $ "{ " ++ prettyPrintRow row ++ " }"
40 match (PrettyPrintArray ty) = Just $ "[" ++ prettyPrintType ty ++ "]"
40 match (PrettyPrintArray ty) = Just $ "[" ++ prettyPrintType ty ++ "]"
src/Language/PureScript/Pretty/Values.hs+40−31
@@ -21,12 +21,13 @@ module Language.PureScript.Pretty.Values (
21import Data.Maybe (fromMaybe)
21import Data.Maybe (fromMaybe)
22import Data.List (intercalate)
22import Data.List (intercalate)
23
23
24−import Control.Arrow ((<+>), runKleisli)
24+import Control.Arrow ((<+>), runKleisli, second)
25import Control.PatternArrows
25import Control.PatternArrows
26import Control.Monad.State
26import Control.Monad.State
27import Control.Applicative
27import Control.Applicative
28
28
29import Language.PureScript.AST
29import Language.PureScript.AST
30+import Language.PureScript.Names
30import Language.PureScript.Pretty.Common
31import Language.PureScript.Pretty.Common
31import Language.PureScript.Pretty.Types (prettyPrintType)
32import Language.PureScript.Pretty.Types (prettyPrintType)
32
33
@@ -38,33 +39,28 @@ literals = mkPattern' match
38 match (StringLiteral s) = return $ show s
39 match (StringLiteral s) = return $ show s
39 match (BooleanLiteral True) = return "true"
40 match (BooleanLiteral True) = return "true"
40 match (BooleanLiteral False) = return "false"
41 match (BooleanLiteral False) = return "false"
41− match (ArrayLiteral xs) = fmap concat $ sequence
42+ match (ArrayLiteral xs) = concat <$> sequence
42 [ return "[ "
43 [ return "[ "
43 , withIndent $ prettyPrintMany prettyPrintValue' xs
44 , withIndent $ prettyPrintMany prettyPrintValue' xs
44 , return " ]"
45 , return " ]"
45 ]
46 ]
46− match (ObjectLiteral []) = return "{}"
47+ match (ObjectLiteral ps) = prettyPrintObject' $ second Just `map` ps
47− match (ObjectLiteral ps) = fmap concat $ sequence
48+ match (ObjectConstructor ps) = prettyPrintObject' ps
48− [ return "{\n"
49+ match (ObjectGetter prop) = return $ "(." ++ prop ++ ")"
49− , withIndent $ prettyPrintMany prettyPrintObjectProperty ps
50− , return "\n"
51− , currentIndent
52− , return "}"
53− ]
54− match (TypeClassDictionaryConstructorApp className ps) = fmap concat $ sequence
50+ match (TypeClassDictionaryConstructorApp className ps) = concat <$> sequence
55− [ return ((show className) ++ "(\n")
51+ [ return (show className ++ "(\n")
56 , match ps
52 , match ps
57 , return ")"
53 , return ")"
58 ]
54 ]
59 match (Constructor name) = return $ show name
55 match (Constructor name) = return $ show name
60− match (Case values binders) = fmap concat $ sequence
56+ match (Case values binders) = concat <$> sequence
61 [ return "case "
57 [ return "case "
62 , unwords <$> forM values prettyPrintValue'
58 , unwords <$> forM values prettyPrintValue'
63 , return " of\n"
59 , return " of\n"
64 , withIndent $ prettyPrintMany prettyPrintCaseAlternative binders
60 , withIndent $ prettyPrintMany prettyPrintCaseAlternative binders
65 , currentIndent
61 , currentIndent
66 ]
62 ]
67− match (Let ds val) = fmap concat $ sequence
63+ match (Let ds val) = concat <$> sequence
68 [ return "let\n"
64 [ return "let\n"
69 , withIndent $ prettyPrintMany prettyPrintDeclaration ds
65 , withIndent $ prettyPrintMany prettyPrintDeclaration ds
70 , return "\n"
66 , return "\n"
@@ -73,29 +69,31 @@ literals = mkPattern' match
73 , prettyPrintValue' val
69 , prettyPrintValue' val
74 ]
70 ]
75 match (Var ident) = return $ show ident
71 match (Var ident) = return $ show ident
76− match (Do els) = fmap concat $ sequence
72+ match (Do els) = concat <$> sequence
77 [ return "do "
73 [ return "do "
78 , withIndent $ prettyPrintMany prettyPrintDoNotationElement els
74 , withIndent $ prettyPrintMany prettyPrintDoNotationElement els
79 , currentIndent
75 , currentIndent
80 ]
76 ]
77+ match (OperatorSection op (Right val)) = return $ "(" ++ prettyPrintValue op ++ " " ++ prettyPrintValue val ++ ")"
78+ match (OperatorSection op (Left val)) = return $ "(" ++ prettyPrintValue val ++ " " ++ prettyPrintValue op ++ ")"
81 match (TypeClassDictionary name _ _) = return $ "<<dict " ++ show name ++ ">>"
79 match (TypeClassDictionary name _ _) = return $ "<<dict " ++ show name ++ ">>"
82 match (SuperClassDictionary name _) = return $ "<<superclass dict " ++ show name ++ ">>"
80 match (SuperClassDictionary name _) = return $ "<<superclass dict " ++ show name ++ ">>"
83 match (TypedValue _ val _) = prettyPrintValue' val
81 match (TypedValue _ val _) = prettyPrintValue' val
84− match (PositionedValue _ val) = prettyPrintValue' val
82+ match (PositionedValue _ _ val) = prettyPrintValue' val
85 match _ = mzero
83 match _ = mzero
86
84
87prettyPrintDeclaration :: Declaration -> StateT PrinterState Maybe String
85prettyPrintDeclaration :: Declaration -> StateT PrinterState Maybe String
88prettyPrintDeclaration (TypeDeclaration ident ty) = return $ show ident ++ " :: " ++ prettyPrintType ty
86prettyPrintDeclaration (TypeDeclaration ident ty) = return $ show ident ++ " :: " ++ prettyPrintType ty
89−prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) = fmap concat $ sequence
87+prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) = concat <$> sequence
90 [ return $ show ident ++ " = "
88 [ return $ show ident ++ " = "
91 , prettyPrintValue' val
89 , prettyPrintValue' val
92 ]
90 ]
93−prettyPrintDeclaration (PositionedDeclaration _ d) = prettyPrintDeclaration d
91+prettyPrintDeclaration (PositionedDeclaration _ _ d) = prettyPrintDeclaration d
94prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
92prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
95
93
96prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String
94prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String
97prettyPrintCaseAlternative (CaseAlternative binders result) =
95prettyPrintCaseAlternative (CaseAlternative binders result) =
98− fmap concat $ sequence
96+ concat <$> sequence
99 [ intercalate ", " <$> forM binders prettyPrintBinder'
97 [ intercalate ", " <$> forM binders prettyPrintBinder'
100 , prettyPrintResult result
98 , prettyPrintResult result
101 ]
99 ]
@@ -104,7 +102,7 @@ prettyPrintCaseAlternative (CaseAlternative binders result) =
104 prettyPrintResult (Right v) = (" -> " ++) <$> prettyPrintValue' v
102 prettyPrintResult (Right v) = (" -> " ++) <$> prettyPrintValue' v
105
103
106 prettyPrintGuardedValue (grd, val) =
104 prettyPrintGuardedValue (grd, val) =
107− fmap concat $ sequence
105+ concat <$> sequence
108 [ return "| "
106 [ return "| "
109 , prettyPrintValue' grd
107 , prettyPrintValue' grd
110 , return " -> "
108 , return " -> "
@@ -116,17 +114,27 @@ prettyPrintDoNotationElement :: DoNotationElement -> StateT PrinterState Maybe S
116prettyPrintDoNotationElement (DoNotationValue val) =
114prettyPrintDoNotationElement (DoNotationValue val) =
117 prettyPrintValue' val
115 prettyPrintValue' val
118prettyPrintDoNotationElement (DoNotationBind binder val) =
116prettyPrintDoNotationElement (DoNotationBind binder val) =
119− fmap concat $ sequence
117+ concat <$> sequence
120 [ prettyPrintBinder' binder
118 [ prettyPrintBinder' binder
121 , return " <- "
119 , return " <- "
122 , prettyPrintValue' val
120 , prettyPrintValue' val
123 ]
121 ]
124prettyPrintDoNotationElement (DoNotationLet ds) =
122prettyPrintDoNotationElement (DoNotationLet ds) =
125− fmap concat $ sequence
123+ concat <$> sequence
126 [ return "let "
124 [ return "let "
127 , withIndent $ prettyPrintMany prettyPrintDeclaration ds
125 , withIndent $ prettyPrintMany prettyPrintDeclaration ds
128 ]
126 ]
129−prettyPrintDoNotationElement (PositionedDoNotationElement _ el) = prettyPrintDoNotationElement el
127+prettyPrintDoNotationElement (PositionedDoNotationElement _ _ el) = prettyPrintDoNotationElement el
128+
129+prettyPrintObject' :: [(String, Maybe Expr)] -> StateT PrinterState Maybe String
130+prettyPrintObject' [] = return "{}"
131+prettyPrintObject' ps = concat <$> sequence
132+ [ return "{\n"
133+ , withIndent $ prettyPrintMany prettyPrintObjectProperty ps
134+ , return "\n"
135+ , currentIndent
136+ , return "}"
137+ ]
130
138
131ifThenElse :: Pattern PrinterState Expr ((Expr, Expr), Expr)
139ifThenElse :: Pattern PrinterState Expr ((Expr, Expr), Expr)
132ifThenElse = mkPattern match
140ifThenElse = mkPattern match
@@ -144,6 +152,7 @@ objectUpdate :: Pattern PrinterState Expr ([String], Expr)
144objectUpdate = mkPattern match
152objectUpdate = mkPattern match
145 where
153 where
146 match (ObjectUpdate o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ prettyPrintValue val, o)
154 match (ObjectUpdate o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ prettyPrintValue val, o)
155+ match (ObjectUpdater o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ maybe "_" prettyPrintValue val, fromMaybe (Var (Qualified Nothing $ Ident "_")) o)
147 match _ = Nothing
156 match _ = Nothing
148
157
149app :: Pattern PrinterState Expr (String, Expr)
158app :: Pattern PrinterState Expr (String, Expr)
@@ -188,23 +197,23 @@ prettyPrintBinderAtom = mkPattern' match
188 match (BooleanBinder True) = return "true"
197 match (BooleanBinder True) = return "true"
189 match (BooleanBinder False) = return "false"
198 match (BooleanBinder False) = return "false"
190 match (VarBinder ident) = return $ show ident
199 match (VarBinder ident) = return $ show ident
191− match (ConstructorBinder ctor args) = fmap concat $ sequence
200+ match (ConstructorBinder ctor args) = concat <$> sequence
192 [ return $ show ctor ++ " "
201 [ return $ show ctor ++ " "
193 , unwords <$> forM args match
202 , unwords <$> forM args match
194 ]
203 ]
195− match (ObjectBinder bs) = fmap concat $ sequence
204+ match (ObjectBinder bs) = concat <$> sequence
196 [ return "{\n"
205 [ return "{\n"
197 , withIndent $ prettyPrintMany prettyPrintObjectPropertyBinder bs
206 , withIndent $ prettyPrintMany prettyPrintObjectPropertyBinder bs
198 , currentIndent
207 , currentIndent
199 , return "}"
208 , return "}"
200 ]
209 ]
201− match (ArrayBinder bs) = fmap concat $ sequence
210+ match (ArrayBinder bs) = concat <$> sequence
202 [ return "["
211 [ return "["
203 , unwords <$> mapM prettyPrintBinder' bs
212 , unwords <$> mapM prettyPrintBinder' bs
204 , return "]"
213 , return "]"
205 ]
214 ]
206 match (NamedBinder ident binder) = ((show ident ++ "@") ++) <$> prettyPrintBinder' binder
215 match (NamedBinder ident binder) = ((show ident ++ "@") ++) <$> prettyPrintBinder' binder
207− match (PositionedBinder _ binder) = prettyPrintBinder' binder
216+ match (PositionedBinder _ _ binder) = prettyPrintBinder' binder
208 match _ = mzero
217 match _ = mzero
209
218
210-- |
219-- |
@@ -229,13 +238,13 @@ matchConsBinder = mkPattern match'
229 match' _ = Nothing
238 match' _ = Nothing
230
239
231prettyPrintObjectPropertyBinder :: (String, Binder) -> StateT PrinterState Maybe String
240prettyPrintObjectPropertyBinder :: (String, Binder) -> StateT PrinterState Maybe String
232−prettyPrintObjectPropertyBinder (key, binder) = fmap concat $ sequence
241+prettyPrintObjectPropertyBinder (key, binder) = concat <$> sequence
233 [ return $ prettyPrintObjectKey key ++ ": "
242 [ return $ prettyPrintObjectKey key ++ ": "
234 , prettyPrintBinder' binder
243 , prettyPrintBinder' binder
235 ]
244 ]
236
245
237−prettyPrintObjectProperty :: (String, Expr) -> StateT PrinterState Maybe String
246+prettyPrintObjectProperty :: (String, Maybe Expr) -> StateT PrinterState Maybe String
238−prettyPrintObjectProperty (key, value) = fmap concat $ sequence
247+prettyPrintObjectProperty (key, value) = concat <$> sequence
239 [ return $ prettyPrintObjectKey key ++ ": "
248 [ return $ prettyPrintObjectKey key ++ ": "
240− , prettyPrintValue' value
249+ , maybe (pure "_") prettyPrintValue' value
241 ]
250 ]
src/Language/PureScript/Renamer.hs+1−1
@@ -150,7 +150,7 @@ renameInValue (Accessor ann prop v) =
150 Accessor ann prop <$> renameInValue v
150 Accessor ann prop <$> renameInValue v
151renameInValue (ObjectUpdate ann obj vs) =
151renameInValue (ObjectUpdate ann obj vs) =
152 ObjectUpdate ann <$> renameInValue obj <*> mapM (\(name, v) -> (,) name <$> renameInValue v) vs
152 ObjectUpdate ann <$> renameInValue obj <*> mapM (\(name, v) -> (,) name <$> renameInValue v) vs
153−renameInValue e@(Abs (_, _, Just IsTypeClassConstructor) _ _) = return e
153+renameInValue e@(Abs (_, _, _, Just IsTypeClassConstructor) _ _) = return e
154renameInValue (Abs ann name v) =
154renameInValue (Abs ann name v) =
155 newScope $ Abs ann <$> updateScope name <*> renameInValue v
155 newScope $ Abs ann <$> updateScope name <*> renameInValue v
156renameInValue (App ann v1 v2) =
156renameInValue (App ann v1 v2) =
src/Language/PureScript/Sugar.hs+19−10
@@ -23,20 +23,23 @@ import Language.PureScript.AST
23import Language.PureScript.Errors
23import Language.PureScript.Errors
24import Language.PureScript.Supply
24import Language.PureScript.Supply
25
25
26−import Language.PureScript.Sugar.Operators as S
27−import Language.PureScript.Sugar.DoNotation as S
28−import Language.PureScript.Sugar.CaseDeclarations as S
29−import Language.PureScript.Sugar.TypeDeclarations as S
30import Language.PureScript.Sugar.BindingGroups as S
26import Language.PureScript.Sugar.BindingGroups as S
31−import Language.PureScript.Sugar.TypeClasses as S
27+import Language.PureScript.Sugar.CaseDeclarations as S
28+import Language.PureScript.Sugar.DoNotation as S
32import Language.PureScript.Sugar.Names as S
29import Language.PureScript.Sugar.Names as S
30+import Language.PureScript.Sugar.ObjectWildcards as S
31+import Language.PureScript.Sugar.Operators as S
32+import Language.PureScript.Sugar.TypeClasses as S
33+import Language.PureScript.Sugar.TypeDeclarations as S
33
34
34-- |
35-- |
35-- The desugaring pipeline proceeds as follows:
36-- The desugaring pipeline proceeds as follows:
36--
37--
37−-- * Introduce type synonyms for type class dictionaries
38+-- * Remove signed literals in favour of `negate` applications
38--
39--
39−-- * Rebracket user-defined binary operators
40+-- * Desugar object literals with wildcards into lambdas
41+--
42+-- * Desugar operator sections
40--
43--
41-- * Desugar do-notation using the @Prelude.Monad@ type class
44-- * Desugar do-notation using the @Prelude.Monad@ type class
42--
45--
@@ -44,13 +47,19 @@ import Language.PureScript.Sugar.Names as S
44--
47--
45-- * Desugar type declarations into value declarations with explicit type annotations
48-- * Desugar type declarations into value declarations with explicit type annotations
46--
49--
47−-- * Group mutually recursive value and data declarations into binding groups.
48−--
49-- * Qualify any unqualified names and types
50-- * Qualify any unqualified names and types
50--
51--
52+-- * Rebracket user-defined binary operators
53+--
54+-- * Introduce type synonyms for type class dictionaries
55+--
56+-- * Group mutually recursive value and data declarations into binding groups.
57+--
51desugar :: [Module] -> SupplyT (Either ErrorStack) [Module]
58desugar :: [Module] -> SupplyT (Either ErrorStack) [Module]
52desugar = map removeSignedLiterals
59desugar = map removeSignedLiterals
60+ >>> mapM desugarObjectConstructors
61+ >=> mapM desugarOperatorSections
53− >>> mapM desugarDoModule
62+ >=> mapM desugarDoModule
54 >=> desugarCasesModule
63 >=> desugarCasesModule
55 >=> lift . (desugarTypeDeclarationsModule
64 >=> lift . (desugarTypeDeclarationsModule
56 >=> desugarImports
65 >=> desugarImports
src/Language/PureScript/Sugar/BindingGroups.hs+10−11
@@ -24,7 +24,6 @@ module Language.PureScript.Sugar.BindingGroups (
24import Data.Graph
24import Data.Graph
25import Data.List (nub, intersect)
25import Data.List (nub, intersect)
26import Data.Maybe (isJust, mapMaybe)
26import Data.Maybe (isJust, mapMaybe)
27−import Data.Monoid ((<>))
28import Control.Applicative ((<$>), (<*>), pure)
27import Control.Applicative ((<$>), (<*>), pure)
29import Control.Monad ((<=<))
28import Control.Monad ((<=<))
30
29
@@ -52,12 +51,12 @@ createBindingGroups :: ModuleName -> [Declaration] -> Either ErrorStack [Declara
52createBindingGroups moduleName = mapM f <=< handleDecls
51createBindingGroups moduleName = mapM f <=< handleDecls
53
52
54 where
53 where
55− (f, _, _) = everywhereOnValuesTopDownM return handleExprs return
54+ (f, _, _) = everywhereOnValuesTopDownM return handleExprs return
56−
55+
57 handleExprs :: Expr -> Either ErrorStack Expr
56 handleExprs :: Expr -> Either ErrorStack Expr
58 handleExprs (Let ds val) = flip Let val <$> handleDecls ds
57 handleExprs (Let ds val) = flip Let val <$> handleDecls ds
59 handleExprs other = return other
58 handleExprs other = return other
60−
59+
61 -- |
60 -- |
62 -- Replace all sets of mutually-recursive declarations with binding groups
61 -- Replace all sets of mutually-recursive declarations with binding groups
63 --
62 --
@@ -88,7 +87,7 @@ collapseBindingGroups = let (f, _, _) = everywhereOnValues id collapseBindingGro
88 where
87 where
89 go (DataBindingGroupDeclaration ds) = ds
88 go (DataBindingGroupDeclaration ds) = ds
90 go (BindingGroupDeclaration ds) = map (\(ident, nameKind, val) -> ValueDeclaration ident nameKind [] (Right val)) ds
89 go (BindingGroupDeclaration ds) = map (\(ident, nameKind, val) -> ValueDeclaration ident nameKind [] (Right val)) ds
91− go (PositionedDeclaration pos d) = map (PositionedDeclaration pos) $ go d
90+ go (PositionedDeclaration pos com d) = map (PositionedDeclaration pos com) $ go d
92 go other = [other]
91 go other = [other]
93
92
94collapseBindingGroupsForValue :: Expr -> Expr
93collapseBindingGroupsForValue :: Expr -> Expr
@@ -139,13 +138,13 @@ usedProperNames moduleName =
139
138
140getIdent :: Declaration -> Ident
139getIdent :: Declaration -> Ident
141getIdent (ValueDeclaration ident _ _ _) = ident
140getIdent (ValueDeclaration ident _ _ _) = ident
142−getIdent (PositionedDeclaration _ d) = getIdent d
141+getIdent (PositionedDeclaration _ _ d) = getIdent d
143getIdent _ = error "Expected ValueDeclaration"
142getIdent _ = error "Expected ValueDeclaration"
144
143
145getProperName :: Declaration -> ProperName
144getProperName :: Declaration -> ProperName
146getProperName (DataDeclaration _ pn _ _) = pn
145getProperName (DataDeclaration _ pn _ _) = pn
147getProperName (TypeSynonymDeclaration pn _ _) = pn
146getProperName (TypeSynonymDeclaration pn _ _) = pn
148−getProperName (PositionedDeclaration _ d) = getProperName d
147+getProperName (PositionedDeclaration _ _ d) = getProperName d
149getProperName _ = error "Expected DataDeclaration"
148getProperName _ = error "Expected DataDeclaration"
150
149
151-- |
150-- |
@@ -178,10 +177,10 @@ toBindingGroup moduleName (CyclicSCC ds') =
178 toBinding (CyclicSCC ~(d:ds)) = cycleError d ds
177 toBinding (CyclicSCC ~(d:ds)) = cycleError d ds
179
178
180 cycleError :: Declaration -> [Declaration] -> Either ErrorStack a
179 cycleError :: Declaration -> [Declaration] -> Either ErrorStack a
181− cycleError (PositionedDeclaration p d) ds = rethrowWithPosition p $ cycleError d ds
180+ cycleError (PositionedDeclaration p _ d) ds = rethrowWithPosition p $ cycleError d ds
182 cycleError (ValueDeclaration n _ _ (Right e)) [] = Left $
181 cycleError (ValueDeclaration n _ _ (Right e)) [] = Left $
183 mkErrorStack ("Cycle in definition of " ++ show n) (Just (ExprError e))
182 mkErrorStack ("Cycle in definition of " ++ show n) (Just (ExprError e))
184− cycleError d ds@(_:_) = rethrow (<> mkErrorStack ("The following are not yet defined here: " ++ unwords (map (show . getIdent) ds)) Nothing) $ cycleError d []
183+ cycleError d ds@(_:_) = rethrow (mkCompileError ("The following are not yet defined here: " ++ unwords (map (show . getIdent) ds)) Nothing `combineErrors`) $ cycleError d []
185 cycleError _ _ = error "Expected ValueDeclaration"
184 cycleError _ _ = error "Expected ValueDeclaration"
186
185
187toDataBindingGroup :: SCC Declaration -> Either ErrorStack Declaration
186toDataBindingGroup :: SCC Declaration -> Either ErrorStack Declaration
@@ -195,11 +194,11 @@ toDataBindingGroup (CyclicSCC ds')
195
194
196isTypeSynonym :: Declaration -> Maybe ProperName
195isTypeSynonym :: Declaration -> Maybe ProperName
197isTypeSynonym (TypeSynonymDeclaration pn _ _) = Just pn
196isTypeSynonym (TypeSynonymDeclaration pn _ _) = Just pn
198−isTypeSynonym (PositionedDeclaration _ d) = isTypeSynonym d
197+isTypeSynonym (PositionedDeclaration _ _ d) = isTypeSynonym d
199isTypeSynonym _ = Nothing
198isTypeSynonym _ = Nothing
200
199
201fromValueDecl :: Declaration -> (Ident, NameKind, Expr)
200fromValueDecl :: Declaration -> (Ident, NameKind, Expr)
202fromValueDecl (ValueDeclaration ident nameKind [] (Right val)) = (ident, nameKind, val)
201fromValueDecl (ValueDeclaration ident nameKind [] (Right val)) = (ident, nameKind, val)
203fromValueDecl ValueDeclaration{} = error "Binders should have been desugared"
202fromValueDecl ValueDeclaration{} = error "Binders should have been desugared"
204−fromValueDecl (PositionedDeclaration _ d) = fromValueDecl d
203+fromValueDecl (PositionedDeclaration _ _ d) = fromValueDecl d
205fromValueDecl _ = error "Expected ValueDeclaration"
204fromValueDecl _ = error "Expected ValueDeclaration"
src/Language/PureScript/Sugar/CaseDeclarations.hs+9−10
@@ -19,12 +19,11 @@ module Language.PureScript.Sugar.CaseDeclarations (
19 desugarCasesModule
19 desugarCasesModule
20) where
20) where
21
21
22−import Data.Monoid ((<>))
23import Data.List (nub, groupBy)
22import Data.List (nub, groupBy)
24
23
25import Control.Applicative
24import Control.Applicative
26import Control.Monad ((<=<), forM, join, unless, replicateM)
25import Control.Monad ((<=<), forM, join, unless, replicateM)
27−import Control.Monad.Error.Class
26+import Control.Monad.Except (throwError)
28
27
29import Language.PureScript.Names
28import Language.PureScript.Names
30import Language.PureScript.AST
29import Language.PureScript.AST
@@ -44,7 +43,7 @@ isLeft (Right _) = False
44--
43--
45desugarCasesModule :: [Module] -> SupplyT (Either ErrorStack) [Module]
44desugarCasesModule :: [Module] -> SupplyT (Either ErrorStack) [Module]
46desugarCasesModule ms = forM ms $ \(Module name ds exps) ->
45desugarCasesModule ms = forM ms $ \(Module name ds exps) ->
47− rethrow (strMsg ("Error in module " ++ show name) <>) $
46+ rethrow (mkCompileError ("Error in module " ++ show name) Nothing `combineErrors`) $
48 Module name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps
47 Module name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps
49
48
50desugarAbs :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]
49desugarAbs :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]
@@ -75,16 +74,16 @@ desugarCases = desugarRest <=< fmap join . flip parU toDecls . groupBy inSameGro
75 where
74 where
76 go (Let ds val') = Let <$> desugarCases ds <*> pure val'
75 go (Let ds val') = Let <$> desugarCases ds <*> pure val'
77 go other = return other
76 go other = return other
78− desugarRest (PositionedDeclaration pos d : ds) = do
77+ desugarRest (PositionedDeclaration pos com d : ds) = do
79 (d' : ds') <- desugarRest (d : ds)
78 (d' : ds') <- desugarRest (d : ds)
80− return (PositionedDeclaration pos d' : ds')
79+ return (PositionedDeclaration pos com d' : ds')
81 desugarRest (d : ds) = (:) d <$> desugarRest ds
80 desugarRest (d : ds) = (:) d <$> desugarRest ds
82 desugarRest [] = pure []
81 desugarRest [] = pure []
83
82
84inSameGroup :: Declaration -> Declaration -> Bool
83inSameGroup :: Declaration -> Declaration -> Bool
85inSameGroup (ValueDeclaration ident1 _ _ _) (ValueDeclaration ident2 _ _ _) = ident1 == ident2
84inSameGroup (ValueDeclaration ident1 _ _ _) (ValueDeclaration ident2 _ _ _) = ident1 == ident2
86−inSameGroup (PositionedDeclaration _ d1) d2 = inSameGroup d1 d2
85+inSameGroup (PositionedDeclaration _ _ d1) d2 = inSameGroup d1 d2
87−inSameGroup d1 (PositionedDeclaration _ d2) = inSameGroup d1 d2
86+inSameGroup d1 (PositionedDeclaration _ _ d2) = inSameGroup d1 d2
88inSameGroup _ _ = False
87inSameGroup _ _ = False
89
88
90toDecls :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]
89toDecls :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]
@@ -101,9 +100,9 @@ toDecls ds@(ValueDeclaration ident _ bs result : _) = do
101 throwError $ mkErrorStack ("Duplicate value declaration '" ++ show ident ++ "'") Nothing
100 throwError $ mkErrorStack ("Duplicate value declaration '" ++ show ident ++ "'") Nothing
102 caseDecl <- makeCaseDeclaration ident tuples
101 caseDecl <- makeCaseDeclaration ident tuples
103 return [caseDecl]
102 return [caseDecl]
104−toDecls (PositionedDeclaration pos d : ds) = do
103+toDecls (PositionedDeclaration pos com d : ds) = do
105 (d' : ds') <- rethrowWithPosition pos $ toDecls (d : ds)
104 (d' : ds') <- rethrowWithPosition pos $ toDecls (d : ds)
106− return (PositionedDeclaration pos d' : ds')
105+ return (PositionedDeclaration pos com d' : ds')
107toDecls ds = return ds
106toDecls ds = return ds
108
107
109isVarBinder :: Binder -> Bool
108isVarBinder :: Binder -> Bool
@@ -112,7 +111,7 @@ isVarBinder _ = False
112
111
113toTuple :: Declaration -> ([Binder], Either [(Guard, Expr)] Expr)
112toTuple :: Declaration -> ([Binder], Either [(Guard, Expr)] Expr)
114toTuple (ValueDeclaration _ _ bs result) = (bs, result)
113toTuple (ValueDeclaration _ _ bs result) = (bs, result)
115−toTuple (PositionedDeclaration _ d) = toTuple d
114+toTuple (PositionedDeclaration _ _ d) = toTuple d
116toTuple _ = error "Not a value declaration"
115toTuple _ = error "Not a value declaration"
117
116
118makeCaseDeclaration :: Ident -> [([Binder], Either [(Guard, Expr)] Expr)] -> SupplyT (Either ErrorStack) Declaration
117makeCaseDeclaration :: Ident -> [([Binder], Either [(Guard, Expr)] Expr)] -> SupplyT (Either ErrorStack) Declaration
src/Language/PureScript/Sugar/DoNotation.hs+3−3
@@ -36,7 +36,7 @@ desugarDoModule :: Module -> SupplyT (Either ErrorStack) Module
36desugarDoModule (Module mn ds exts) = Module mn <$> parU ds desugarDo <*> pure exts
36desugarDoModule (Module mn ds exts) = Module mn <$> parU ds desugarDo <*> pure exts
37
37
38desugarDo :: Declaration -> SupplyT (Either ErrorStack) Declaration
38desugarDo :: Declaration -> SupplyT (Either ErrorStack) Declaration
39−desugarDo (PositionedDeclaration pos d) = (PositionedDeclaration pos) <$> (rethrowWithPosition pos $ desugarDo d)
39+desugarDo (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> (rethrowWithPosition pos $ desugarDo d)
40desugarDo d =
40desugarDo d =
41 let (f, _, _) = everywhereOnValuesM return replace return
41 let (f, _, _) = everywhereOnValuesM return replace return
42 in f d
42 in f d
@@ -49,7 +49,7 @@ desugarDo d =
49
49
50 replace :: Expr -> SupplyT (Either ErrorStack) Expr
50 replace :: Expr -> SupplyT (Either ErrorStack) Expr
51 replace (Do els) = go els
51 replace (Do els) = go els
52− replace (PositionedValue pos v) = PositionedValue pos <$> rethrowWithPosition pos (replace v)
52+ replace (PositionedValue pos com v) = PositionedValue pos com <$> rethrowWithPosition pos (replace v)
53 replace other = return other
53 replace other = return other
54
54
55 go :: [DoNotationElement] -> SupplyT (Either ErrorStack) Expr
55 go :: [DoNotationElement] -> SupplyT (Either ErrorStack) Expr
@@ -71,4 +71,4 @@ desugarDo d =
71 go (DoNotationLet ds : rest) = do
71 go (DoNotationLet ds : rest) = do
72 rest' <- go rest
72 rest' <- go rest
73 return $ Let ds rest'
73 return $ Let ds rest'
74− go (PositionedDoNotationElement pos el : rest) = rethrowWithPosition pos $ PositionedValue pos <$> go (el : rest)
74+ go (PositionedDoNotationElement pos com el : rest) = rethrowWithPosition pos $ PositionedValue pos com <$> go (el : rest)
src/Language/PureScript/Sugar/Names.hs+58−32
@@ -18,10 +18,9 @@ module Language.PureScript.Sugar.Names (
18
18
19import Data.List (nub)
19import Data.List (nub)
20import Data.Maybe (fromMaybe, isJust, mapMaybe)
20import Data.Maybe (fromMaybe, isJust, mapMaybe)
21−import Data.Monoid ((<>))
22
21
23import Control.Applicative (Applicative(..), (<$>), (<*>))
22import Control.Applicative (Applicative(..), (<$>), (<*>))
24−import Control.Monad.Error
23+import Control.Monad.Except
25
24
26import qualified Data.Map as M
25import qualified Data.Map as M
27
26
@@ -54,8 +53,8 @@ data Exports = Exports
54 , exportedTypeClasses :: [ProperName]
53 , exportedTypeClasses :: [ProperName]
55 -- |
54 -- |
56 -- The values exported from each module
55 -- The values exported from each module
57− , exportedValues :: [Ident]
58 --
56 --
57+ , exportedValues :: [Ident]
59 } deriving (Show)
58 } deriving (Show)
60
59
61-- |
60-- |
@@ -105,15 +104,26 @@ addEmptyModule env name =
105--
104--
106addType :: ExportEnvironment -> ModuleName -> ProperName -> [ProperName] -> Either ErrorStack ExportEnvironment
105addType :: ExportEnvironment -> ModuleName -> ProperName -> [ProperName] -> Either ErrorStack ExportEnvironment
107addType env mn name dctors = updateExportedModule env mn $ \m -> do
106addType env mn name dctors = updateExportedModule env mn $ \m -> do
108− types' <- addExport (exportedTypes m) (name, dctors)
107+ let exTypes = exportedTypes m
108+ let exDctors = snd `concatMap` exTypes
109+ let exClasses = exportedTypeClasses m
110+ when (any ((== name) . fst) exTypes) $ throwMultipleDefError "type" name
111+ when (name `elem` exClasses) $ throwConflictingDefError "Type" "type class" name
112+ forM_ dctors $ \dctor -> do
113+ when (dctor `elem` exDctors) $ throwMultipleDefError "data constructor" dctor
114+ when (dctor `elem` exClasses) $ throwConflictingDefError "Data constructor" "type class" dctor
109− return $ m { exportedTypes = types' }
115+ return $ m { exportedTypes = (name, dctors) : exTypes }
110
116
111-- |
117-- |
112-- Adds a class to the export environment.
118-- Adds a class to the export environment.
113--
119--
114addTypeClass :: ExportEnvironment -> ModuleName -> ProperName -> Either ErrorStack ExportEnvironment
120addTypeClass :: ExportEnvironment -> ModuleName -> ProperName -> Either ErrorStack ExportEnvironment
115addTypeClass env mn name = updateExportedModule env mn $ \m -> do
121addTypeClass env mn name = updateExportedModule env mn $ \m -> do
122+ let exTypes = exportedTypes m
123+ let exDctors = snd `concatMap` exTypes
124+ when (any ((== name) . fst) exTypes) $ throwConflictingDefError "Type class" "type" name
125+ when (name `elem` exDctors) $ throwConflictingDefError "Type class" "data constructor" name
116− classes <- addExport (exportedTypeClasses m) name
126+ classes <- addExport "type class" (exportedTypeClasses m) name
117 return $ m { exportedTypeClasses = classes }
127 return $ m { exportedTypeClasses = classes }
118
128
119-- |
129-- |
@@ -121,17 +131,17 @@ addTypeClass env mn name = updateExportedModule env mn $ \m -> do
121--
131--
122addValue :: ExportEnvironment -> ModuleName -> Ident -> Either ErrorStack ExportEnvironment
132addValue :: ExportEnvironment -> ModuleName -> Ident -> Either ErrorStack ExportEnvironment
123addValue env mn name = updateExportedModule env mn $ \m -> do
133addValue env mn name = updateExportedModule env mn $ \m -> do
124− values <- addExport (exportedValues m) name
134+ values <- addExport "value" (exportedValues m) name
125 return $ m { exportedValues = values }
135 return $ m { exportedValues = values }
126
136
127-- |
137-- |
128-- Adds an entry to a list of exports unless it is already present, in which case an error is
138-- Adds an entry to a list of exports unless it is already present, in which case an error is
129-- returned.
139-- returned.
130--
140--
131−addExport :: (Eq a, Show a) => [a] -> a -> Either ErrorStack [a]
141+addExport :: (Eq a, Show a) => String -> [a] -> a -> Either ErrorStack [a]
132−addExport exports name =
142+addExport what exports name =
133 if name `elem` exports
143 if name `elem` exports
134− then throwError $ mkErrorStack ("Multiple definitions for '" ++ show name ++ "'") Nothing
144+ then throwMultipleDefError what name
135 else return $ name : exports
145 else return $ name : exports
136
146
137-- |
147-- |
@@ -155,7 +165,7 @@ desugarImports modules = do
155 -- the module has access to an unfiltered list of its own members.
165 -- the module has access to an unfiltered list of its own members.
156 renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> Either ErrorStack Module
166 renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> Either ErrorStack Module
157 renameInModule' unfilteredExports exports m@(Module mn _ _) =
167 renameInModule' unfilteredExports exports m@(Module mn _ _) =
158− rethrow (strMsg ("Error in module " ++ show mn) <>) $ do
168+ rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ do
159 let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports
169 let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports
160 let exps = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn exports
170 let exps = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn exports
161 imports <- resolveImports env m
171 imports <- resolveImports env m
@@ -199,7 +209,7 @@ renameInModule imports exports (Module mn decls exps) =
199 (go, _, _, _, _) = everywhereWithContextOnValuesM (Nothing, []) updateDecl updateValue updateBinder updateCase defS
209 (go, _, _, _, _) = everywhereWithContextOnValuesM (Nothing, []) updateDecl updateValue updateBinder updateCase defS
200
210
201 updateDecl :: (Maybe SourceSpan, [Ident]) -> Declaration -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Declaration)
211 updateDecl :: (Maybe SourceSpan, [Ident]) -> Declaration -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Declaration)
202− updateDecl (_, bound) d@(PositionedDeclaration pos _) = return ((Just pos, bound), d)
212+ updateDecl (_, bound) d@(PositionedDeclaration pos _ _) = return ((Just pos, bound), d)
203 updateDecl (pos, bound) (DataDeclaration dtype name args dctors) =
213 updateDecl (pos, bound) (DataDeclaration dtype name args dctors) =
204 (,) (pos, bound) <$> (DataDeclaration dtype name args <$> mapM (sndM (mapM (updateTypesEverywhere pos))) dctors)
214 (,) (pos, bound) <$> (DataDeclaration dtype name args <$> mapM (sndM (mapM (updateTypesEverywhere pos))) dctors)
205 updateDecl (pos, bound) (TypeSynonymDeclaration name ps ty) =
215 updateDecl (pos, bound) (TypeSynonymDeclaration name ps ty) =
@@ -217,25 +227,25 @@ renameInModule imports exports (Module mn decls exps) =
217 updateDecl s d = return (s, d)
227 updateDecl s d = return (s, d)
218
228
219 updateValue :: (Maybe SourceSpan, [Ident]) -> Expr -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Expr)
229 updateValue :: (Maybe SourceSpan, [Ident]) -> Expr -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Expr)
220− updateValue (_, bound) v@(PositionedValue pos' _) = return ((Just pos', bound), v)
230+ updateValue (_, bound) v@(PositionedValue pos' _ _) = return ((Just pos', bound), v)
221 updateValue (pos, bound) (Abs (Left arg) val') = return ((pos, arg : bound), Abs (Left arg) val')
231 updateValue (pos, bound) (Abs (Left arg) val') = return ((pos, arg : bound), Abs (Left arg) val')
222− updateValue (pos, bound) (Let ds val') =
232+ updateValue (pos, bound) (Let ds val') = do
223 let args = mapMaybe letBoundVariable ds
233 let args = mapMaybe letBoundVariable ds
234+ unless (length (nub args) == length args) $
235+ maybe id rethrowWithPosition pos $
236+ throwError $ mkErrorStack ("Overlapping names in let binding.") Nothing
224− in return ((pos, args ++ bound), Let ds val')
237+ return ((pos, args ++ bound), Let ds val')
238+ where
225 updateValue (pos, bound) (Var name'@(Qualified Nothing ident)) | ident `notElem` bound =
239 updateValue (pos, bound) (Var name'@(Qualified Nothing ident)) | ident `notElem` bound =
226 (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
240 (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
227 updateValue (pos, bound) (Var name'@(Qualified (Just _) _)) =
241 updateValue (pos, bound) (Var name'@(Qualified (Just _) _)) =
228 (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
242 (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
229− updateValue (pos, bound) (BinaryNoParens name'@(Qualified Nothing ident) v1 v2) | ident `notElem` bound =
230− (,) (pos, bound) <$> (BinaryNoParens <$> updateValueName name' pos <*> pure v1 <*> pure v2)
231− updateValue (pos, bound) (BinaryNoParens name'@(Qualified (Just _) _) v1 v2) =
232− (,) (pos, bound) <$> (BinaryNoParens <$> updateValueName name' pos <*> pure v1 <*> pure v2)
233 updateValue s@(pos, _) (Constructor name) = (,) s <$> (Constructor <$> updateDataConstructorName name pos)
243 updateValue s@(pos, _) (Constructor name) = (,) s <$> (Constructor <$> updateDataConstructorName name pos)
234 updateValue s@(pos, _) (TypedValue check val ty) = (,) s <$> (TypedValue check val <$> updateTypesEverywhere pos ty)
244 updateValue s@(pos, _) (TypedValue check val ty) = (,) s <$> (TypedValue check val <$> updateTypesEverywhere pos ty)
235 updateValue s v = return (s, v)
245 updateValue s v = return (s, v)
236
246
237 updateBinder :: (Maybe SourceSpan, [Ident]) -> Binder -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Binder)
247 updateBinder :: (Maybe SourceSpan, [Ident]) -> Binder -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Binder)
238− updateBinder (_, bound) v@(PositionedBinder pos _) = return ((Just pos, bound), v)
248+ updateBinder (_, bound) v@(PositionedBinder pos _ _) = return ((Just pos, bound), v)
239 updateBinder s@(pos, _) (ConstructorBinder name b) = (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)
249 updateBinder s@(pos, _) (ConstructorBinder name b) = (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)
240 updateBinder s v = return (s, v)
250 updateBinder s v = return (s, v)
241
251
@@ -244,7 +254,7 @@ renameInModule imports exports (Module mn decls exps) =
244
254
245 letBoundVariable :: Declaration -> Maybe Ident
255 letBoundVariable :: Declaration -> Maybe Ident
246 letBoundVariable (ValueDeclaration ident _ _ _) = Just ident
256 letBoundVariable (ValueDeclaration ident _ _ _) = Just ident
247− letBoundVariable (PositionedDeclaration _ d) = letBoundVariable d
257+ letBoundVariable (PositionedDeclaration _ _ d) = letBoundVariable d
248 letBoundVariable _ = Nothing
258 letBoundVariable _ = Nothing
249
259
250 updateTypesEverywhere :: Maybe SourceSpan -> Type -> Either ErrorStack Type
260 updateTypesEverywhere :: Maybe SourceSpan -> Type -> Either ErrorStack Type
@@ -308,7 +318,7 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
308 addModule :: ExportEnvironment -> Module -> Either ErrorStack ExportEnvironment
318 addModule :: ExportEnvironment -> Module -> Either ErrorStack ExportEnvironment
309 addModule env (Module mn ds _) = do
319 addModule env (Module mn ds _) = do
310 env' <- addEmptyModule env mn
320 env' <- addEmptyModule env mn
311− rethrow (strMsg ("Error in module " ++ show mn) <>) $ foldM (addDecl mn) env' ds
321+ rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ foldM (addDecl mn) env' ds
312
322
313 -- Add a declaration from a module to the global export environment
323 -- Add a declaration from a module to the global export environment
314 addDecl :: ModuleName -> ExportEnvironment -> Declaration -> Either ErrorStack ExportEnvironment
324 addDecl :: ModuleName -> ExportEnvironment -> Declaration -> Either ErrorStack ExportEnvironment
@@ -317,14 +327,14 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
317 foldM go env' ds
327 foldM go env' ds
318 where
328 where
319 go env'' (TypeDeclaration name _) = addValue env'' mn name
329 go env'' (TypeDeclaration name _) = addValue env'' mn name
320− go env'' (PositionedDeclaration pos d) = rethrowWithPosition pos $ go env'' d
330+ go env'' (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ go env'' d
321 go _ _ = error "Invalid declaration in TypeClassDeclaration"
331 go _ _ = error "Invalid declaration in TypeClassDeclaration"
322 addDecl mn env (DataDeclaration _ tn _ dcs) = addType env mn tn (map fst dcs)
332 addDecl mn env (DataDeclaration _ tn _ dcs) = addType env mn tn (map fst dcs)
323 addDecl mn env (TypeSynonymDeclaration tn _ _) = addType env mn tn []
333 addDecl mn env (TypeSynonymDeclaration tn _ _) = addType env mn tn []
324 addDecl mn env (ExternDataDeclaration tn _) = addType env mn tn []
334 addDecl mn env (ExternDataDeclaration tn _) = addType env mn tn []
325 addDecl mn env (ValueDeclaration name _ _ _) = addValue env mn name
335 addDecl mn env (ValueDeclaration name _ _ _) = addValue env mn name
326 addDecl mn env (ExternDeclaration _ name _ _) = addValue env mn name
336 addDecl mn env (ExternDeclaration _ name _ _) = addValue env mn name
327− addDecl mn env (PositionedDeclaration _ d) = addDecl mn env d
337+ addDecl mn env (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ addDecl mn env d
328 addDecl _ env _ = return env
338 addDecl _ env _ = return env
329
339
330-- |
340-- |
@@ -334,7 +344,7 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
334filterExports :: ModuleName -> [DeclarationRef] -> ExportEnvironment -> Either ErrorStack ExportEnvironment
344filterExports :: ModuleName -> [DeclarationRef] -> ExportEnvironment -> Either ErrorStack ExportEnvironment
335filterExports mn exps env = do
345filterExports mn exps env = do
336 let moduleExports = fromMaybe (error "Module is missing") (mn `M.lookup` env)
346 let moduleExports = fromMaybe (error "Module is missing") (mn `M.lookup` env)
337− moduleExports' <- rethrow (strMsg ("Error in module " ++ show mn) <>) $ filterModule moduleExports
347+ moduleExports' <- rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ filterModule moduleExports
338 return $ M.insert mn moduleExports' env
348 return $ M.insert mn moduleExports' env
339 where
349 where
340
350
@@ -349,7 +359,7 @@ filterExports mn exps env = do
349 -- Ensure the exported types and data constructors exist in the module and add them to the set of
359 -- Ensure the exported types and data constructors exist in the module and add them to the set of
350 -- exports
360 -- exports
351 filterTypes :: [(ProperName, [ProperName])] -> [(ProperName, [ProperName])] -> DeclarationRef -> Either ErrorStack [(ProperName, [ProperName])]
361 filterTypes :: [(ProperName, [ProperName])] -> [(ProperName, [ProperName])] -> DeclarationRef -> Either ErrorStack [(ProperName, [ProperName])]
352− filterTypes expTys result (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ filterTypes expTys result r
362+ filterTypes expTys result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterTypes expTys result r
353 filterTypes expTys result (TypeRef name expDcons) = do
363 filterTypes expTys result (TypeRef name expDcons) = do
354 dcons <- maybe (throwError $ mkErrorStack ("Cannot export undefined type '" ++ show name ++ "'") Nothing) return $ name `lookup` expTys
364 dcons <- maybe (throwError $ mkErrorStack ("Cannot export undefined type '" ++ show name ++ "'") Nothing) return $ name `lookup` expTys
355 dcons' <- maybe (return dcons) (foldM (filterDcons name dcons) []) expDcons
365 dcons' <- maybe (return dcons) (foldM (filterDcons name dcons) []) expDcons
@@ -365,7 +375,7 @@ filterExports mn exps env = do
365
375
366 -- Ensure the exported classes exist in the module and add them to the set of exports
376 -- Ensure the exported classes exist in the module and add them to the set of exports
367 filterClasses :: [ProperName] -> [ProperName] -> DeclarationRef -> Either ErrorStack [ProperName]
377 filterClasses :: [ProperName] -> [ProperName] -> DeclarationRef -> Either ErrorStack [ProperName]
368− filterClasses exps' result (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ filterClasses exps' result r
378+ filterClasses exps' result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterClasses exps' result r
369 filterClasses exps' result (TypeClassRef name) =
379 filterClasses exps' result (TypeClassRef name) =
370 if name `elem` exps'
380 if name `elem` exps'
371 then return $ name : result
381 then return $ name : result
@@ -374,7 +384,7 @@ filterExports mn exps env = do
374
384
375 -- Ensure the exported values exist in the module and add them to the set of exports
385 -- Ensure the exported values exist in the module and add them to the set of exports
376 filterValues :: [Ident] -> [Ident] -> DeclarationRef -> Either ErrorStack [Ident]
386 filterValues :: [Ident] -> [Ident] -> DeclarationRef -> Either ErrorStack [Ident]
377− filterValues exps' result (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ filterValues exps' result r
387+ filterValues exps' result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterValues exps' result r
378 filterValues exps' result (ValueRef name) =
388 filterValues exps' result (ValueRef name) =
379 if name `elem` exps'
389 if name `elem` exps'
380 then return $ name : result
390 then return $ name : result
@@ -389,7 +399,7 @@ findImports :: [Declaration] -> M.Map ModuleName (Maybe SourceSpan, ImportDeclar
389findImports = foldl (findImports' Nothing) M.empty
399findImports = foldl (findImports' Nothing) M.empty
390 where
400 where
391 findImports' pos result (ImportDeclaration mn typ qual) = M.insert mn (pos, typ, qual) result
401 findImports' pos result (ImportDeclaration mn typ qual) = M.insert mn (pos, typ, qual) result
392− findImports' _ result (PositionedDeclaration pos d) = findImports' (Just pos) result d
402+ findImports' _ result (PositionedDeclaration pos _ d) = findImports' (Just pos) result d
393 findImports' _ result _ = result
403 findImports' _ result _ = result
394
404
395-- |
405-- |
@@ -443,7 +453,7 @@ resolveImport currentModule importModule exps imps impQual =
443 checkTypeRef (TypeRef _ Nothing) acc (TypeRef _ (Just _)) = acc
453 checkTypeRef (TypeRef _ Nothing) acc (TypeRef _ (Just _)) = acc
444 checkTypeRef (TypeRef name (Just dctor)) _ (TypeRef name' (Just dctor')) = name == name' && dctor == dctor'
454 checkTypeRef (TypeRef name (Just dctor)) _ (TypeRef name' (Just dctor')) = name == name' && dctor == dctor'
445 checkTypeRef (TypeRef name _) _ (TypeRef name' Nothing) = name == name'
455 checkTypeRef (TypeRef name _) _ (TypeRef name' Nothing) = name == name'
446− checkTypeRef (PositionedDeclarationRef _ r) acc hiddenRef = checkTypeRef r acc hiddenRef
456+ checkTypeRef (PositionedDeclarationRef _ _ r) acc hiddenRef = checkTypeRef r acc hiddenRef
447 checkTypeRef _ acc _ = acc
457 checkTypeRef _ acc _ = acc
448 in foldl (checkTypeRef ref) False hidden
458 in foldl (checkTypeRef ref) False hidden
449 isHidden hidden ref = ref `elem` hidden
459 isHidden hidden ref = ref `elem` hidden
@@ -457,7 +467,7 @@ resolveImport currentModule importModule exps imps impQual =
457
467
458 -- Import something explicitly
468 -- Import something explicitly
459 importExplicit :: ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment
469 importExplicit :: ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment
460− importExplicit imp (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ importExplicit imp r
470+ importExplicit imp (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ importExplicit imp r
461 importExplicit imp (ValueRef name) = do
471 importExplicit imp (ValueRef name) = do
462 values' <- updateImports (importedValues imp) name
472 values' <- updateImports (importedValues imp) name
463 return $ imp { importedValues = values' }
473 return $ imp { importedValues = values' }
@@ -476,7 +486,7 @@ resolveImport currentModule importModule exps imps impQual =
476 checkedRefs :: [DeclarationRef] -> Either ErrorStack [DeclarationRef]
486 checkedRefs :: [DeclarationRef] -> Either ErrorStack [DeclarationRef]
477 checkedRefs = mapM check
487 checkedRefs = mapM check
478 where
488 where
479− check (PositionedDeclarationRef pos r) =
489+ check (PositionedDeclarationRef pos _ r) =
480 rethrowWithPosition pos $ check r
490 rethrowWithPosition pos $ check r
481 check ref@(ValueRef name) =
491 check ref@(ValueRef name) =
482 checkImportExists "value" values name >> return ref
492 checkImportExists "value" values name >> return ref
@@ -520,3 +530,19 @@ resolveImport currentModule importModule exps imps impQual =
520 if item `elem` exports
530 if item `elem` exports
521 then return item
531 then return item
522 else throwError $ mkErrorStack ("Cannot import unknown " ++ t ++ " '" ++ show item ++ "' from '" ++ show importModule ++ "'") Nothing
532 else throwError $ mkErrorStack ("Cannot import unknown " ++ t ++ " '" ++ show item ++ "' from '" ++ show importModule ++ "'") Nothing
533+
534+-- |
535+-- Raises an error for when there is more than one definition for something.
536+--
537+throwMultipleDefError :: (Show a) => String -> a -> Either ErrorStack b
538+throwMultipleDefError what name = throwError $
539+ mkErrorStack ("Multiple definitions for " ++ what ++ " '" ++ show name ++ "'") Nothing
540+
541+-- |
542+-- Raises an error for when there is a conflicting definition for something, for example, a type
543+-- class and data constructor of the same name.
544+--
545+throwConflictingDefError :: (Show a) => String -> String -> a -> Either ErrorStack b
546+throwConflictingDefError what1 what2 name = throwError $
547+ mkErrorStack (what1 ++ " '" ++ show name ++ "' cannot be defined in the same module as a " ++ what2 ++ " of the same name") Nothing
548+
src/Language/PureScript/Sugar/ObjectWildcards.hsnew file+61
@@ -0,0 +1,61 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Language.PureScript.Sugar.ObjectWildcards
4+-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- |
12+--
13+-----------------------------------------------------------------------------
14+
15+module Language.PureScript.Sugar.ObjectWildcards (
16+ desugarObjectConstructors
17+) where
18+
19+import Control.Applicative
20+import Control.Arrow (second)
21+
22+import Data.List (partition)
23+import Data.Maybe (isJust, fromJust, catMaybes)
24+
25+import Language.PureScript.AST
26+import Language.PureScript.Errors
27+import Language.PureScript.Names
28+import Language.PureScript.Supply
29+
30+desugarObjectConstructors :: Module -> SupplyT (Either ErrorStack) Module
31+desugarObjectConstructors (Module mn ds exts) = Module mn <$> mapM desugarDecl ds <*> pure exts
32+ where
33+
34+ desugarDecl :: Declaration -> SupplyT (Either ErrorStack) Declaration
35+ (desugarDecl, _, _) = everywhereOnValuesM return desugarExpr return
36+
37+ desugarExpr :: Expr -> SupplyT (Either ErrorStack) Expr
38+ desugarExpr (ObjectConstructor ps) = wrapLambda ObjectLiteral ps
39+ desugarExpr (ObjectUpdater (Just obj) ps) = wrapLambda (ObjectUpdate obj) ps
40+ desugarExpr (ObjectUpdater Nothing ps) = do
41+ obj <- Ident <$> freshName
42+ Abs (Left obj) <$> wrapLambda (ObjectUpdate (Var (Qualified Nothing obj))) ps
43+ desugarExpr (ObjectGetter prop) = do
44+ arg <- Ident <$> freshName
45+ return $ Abs (Left arg) (Accessor prop (Var (Qualified Nothing arg)))
46+ desugarExpr e = return e
47+
48+ wrapLambda :: ([(String, Expr)] -> Expr) -> [(String, Maybe Expr)] -> SupplyT (Either ErrorStack) Expr
49+ wrapLambda mkVal ps =
50+ let (props, args) = partition (isJust . snd) ps
51+ in if null args
52+ then return . mkVal $ second fromJust `map` props
53+ else do
54+ (args', ps') <- unzip <$> mapM mkProp ps
55+ return $ foldr (Abs . Left) (mkVal ps') (catMaybes args')
56+
57+ mkProp :: (String, Maybe Expr) -> SupplyT (Either ErrorStack) (Maybe Ident, (String, Expr))
58+ mkProp (name, Just e) = return (Nothing, (name, e))
59+ mkProp (name, Nothing) = do
60+ arg <- Ident <$> freshName
61+ return (Just arg, (name, Var (Qualified Nothing arg)))
src/Language/PureScript/Sugar/Operators.hs+28−16
@@ -21,18 +21,19 @@
21
21
22module Language.PureScript.Sugar.Operators (
22module Language.PureScript.Sugar.Operators (
23 rebracket,
23 rebracket,
24− removeSignedLiterals
24+ removeSignedLiterals,
25+ desugarOperatorSections
25) where
26) where
26
27
27−import Language.PureScript.Names
28import Language.PureScript.AST
28import Language.PureScript.AST
29import Language.PureScript.Errors
29import Language.PureScript.Errors
30+import Language.PureScript.Names
31+import Language.PureScript.Supply
30
32
31import Control.Applicative
33import Control.Applicative
32import Control.Monad.State
34import Control.Monad.State
33−import Control.Monad.Error.Class
35+import Control.Monad.Except
34
36
35−import Data.Monoid ((<>))
36import Data.Function (on)
37import Data.Function (on)
37import Data.Functor.Identity
38import Data.Functor.Identity
38import Data.List (groupBy, sortBy)
39import Data.List (groupBy, sortBy)
@@ -58,8 +59,6 @@ removeSignedLiterals (Module mn ds exts) = Module mn (map f' ds) exts
58 where
59 where
59 (f', _, _) = everywhereOnValues id go id
60 (f', _, _) = everywhereOnValues id go id
60
61
61− go (UnaryMinus (NumericLiteral (Left n))) = NumericLiteral (Left $ negate n)
62− go (UnaryMinus (NumericLiteral (Right n))) = NumericLiteral (Right $ negate n)
63 go (UnaryMinus val) = App (Var (Qualified (Just (ModuleName [ProperName C.prelude])) (Ident C.negate))) val
62 go (UnaryMinus val) = App (Var (Qualified (Just (ModuleName [ProperName C.prelude])) (Ident C.negate))) val
64 go other = other
63 go other = other
65
64
@@ -80,7 +79,7 @@ collectFixities :: Module -> [(Qualified Ident, SourceSpan, Fixity)]
80collectFixities (Module moduleName ds _) = concatMap collect ds
79collectFixities (Module moduleName ds _) = concatMap collect ds
81 where
80 where
82 collect :: Declaration -> [(Qualified Ident, SourceSpan, Fixity)]
81 collect :: Declaration -> [(Qualified Ident, SourceSpan, Fixity)]
83− collect (PositionedDeclaration pos (FixityDeclaration fixity name)) = [(Qualified (Just moduleName) (Op name), pos, fixity)]
82+ collect (PositionedDeclaration pos _ (FixityDeclaration fixity name)) = [(Qualified (Just moduleName) (Op name), pos, fixity)]
84 collect FixityDeclaration{} = error "Fixity without srcpos info"
83 collect FixityDeclaration{} = error "Fixity without srcpos info"
85 collect _ = []
84 collect _ = []
86
85
@@ -90,7 +89,7 @@ ensureNoDuplicates m = go $ sortBy (compare `on` fst) m
90 go [] = return ()
89 go [] = return ()
91 go [_] = return ()
90 go [_] = return ()
92 go ((x@(Qualified (Just mn) name), _) : (y, pos) : _) | x == y =
91 go ((x@(Qualified (Just mn) name), _) : (y, pos) : _) | x == y =
93− rethrow (strMsg ("Error in module " ++ show mn) <>) $
92+ rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $
94 rethrowWithPosition pos $
93 rethrowWithPosition pos $
95 throwError $ mkErrorStack ("Redefined fixity for " ++ show name) Nothing
94 throwError $ mkErrorStack ("Redefined fixity for " ++ show name) Nothing
96 go (_ : rest) = go rest
95 go (_ : rest) = go rest
@@ -105,7 +104,7 @@ customOperatorTable fixities =
105 in
104 in
106 map (map (\(name, f, _, a) -> (name, f, a))) groups
105 map (map (\(name, f, _, a) -> (name, f, a))) groups
107
106
108−type Chain = [Either Expr (Qualified Ident)]
107+type Chain = [Either Expr Expr]
109
108
110matchOperators :: [[(Qualified Ident, Expr -> Expr -> Expr, Associativity)]] -> Expr -> Either ErrorStack Expr
109matchOperators :: [[(Qualified Ident, Expr -> Expr -> Expr, Associativity)]] -> Expr -> Either ErrorStack Expr
111matchOperators ops = parseChains
110matchOperators ops = parseChains
@@ -114,11 +113,11 @@ matchOperators ops = parseChains
114 parseChains b@BinaryNoParens{} = bracketChain (extendChain b)
113 parseChains b@BinaryNoParens{} = bracketChain (extendChain b)
115 parseChains other = return other
114 parseChains other = return other
116 extendChain :: Expr -> Chain
115 extendChain :: Expr -> Chain
117− extendChain (BinaryNoParens name l r) = Left l : Right name : extendChain r
116+ extendChain (BinaryNoParens op l r) = Left l : Right op : extendChain r
118 extendChain other = [Left other]
117 extendChain other = [Left other]
119 bracketChain :: Chain -> Either ErrorStack Expr
118 bracketChain :: Chain -> Either ErrorStack Expr
120 bracketChain = either (Left . (`mkErrorStack` Nothing) . show) Right . P.parse (P.buildExpressionParser opTable parseValue <* P.eof) "operator expression"
119 bracketChain = either (Left . (`mkErrorStack` Nothing) . show) Right . P.parse (P.buildExpressionParser opTable parseValue <* P.eof) "operator expression"
121− opTable = [P.Infix (P.try (parseTicks >>= \ident -> return (\t1 t2 -> App (App (Var ident) t1) t2))) P.AssocLeft]
120+ opTable = [P.Infix (P.try (parseTicks >>= \op -> return (\t1 t2 -> App (App op t1) t2))) P.AssocLeft]
122 : map (map (\(name, f, a) -> P.Infix (P.try (matchOp name) >> return f) (toAssoc a))) ops
121 : map (map (\(name, f, a) -> P.Infix (P.try (matchOp name) >> return f) (toAssoc a))) ops
123 ++ [[ P.Infix (P.try (parseOp >>= \ident -> return (\t1 t2 -> App (App (Var ident) t1) t2))) P.AssocLeft ]]
122 ++ [[ P.Infix (P.try (parseOp >>= \ident -> return (\t1 t2 -> App (App (Var ident) t1) t2))) P.AssocLeft ]]
124
123
@@ -136,17 +135,30 @@ parseValue = token (either Just (const Nothing)) P.<?> "expression"
136parseOp :: P.Parsec Chain () (Qualified Ident)
135parseOp :: P.Parsec Chain () (Qualified Ident)
137parseOp = token (either (const Nothing) fromOp) P.<?> "operator"
136parseOp = token (either (const Nothing) fromOp) P.<?> "operator"
138 where
137 where
139− fromOp q@(Qualified _ (Op _)) = Just q
138+ fromOp (Var q@(Qualified _ (Op _))) = Just q
140 fromOp _ = Nothing
139 fromOp _ = Nothing
141
140
142−parseTicks :: P.Parsec Chain () (Qualified Ident)
141+parseTicks :: P.Parsec Chain () Expr
143−parseTicks = token (either (const Nothing) fromOp) P.<?> "infix function"
142+parseTicks = token (either (const Nothing) fromOther) P.<?> "infix function"
144 where
143 where
145− fromOp q@(Qualified _ (Ident _)) = Just q
144+ fromOther (Var (Qualified _ (Op _))) = Nothing
146− fromOp _ = Nothing
145+ fromOther v = Just v
147
146
148matchOp :: Qualified Ident -> P.Parsec Chain () ()
147matchOp :: Qualified Ident -> P.Parsec Chain () ()
149matchOp op = do
148matchOp op = do
150 ident <- parseOp
149 ident <- parseOp
151 guard $ ident == op
150 guard $ ident == op
152
151
152+desugarOperatorSections :: Module -> SupplyT (Either ErrorStack) Module
153+desugarOperatorSections (Module mn ds exts) = Module mn <$> mapM goDecl ds <*> pure exts
154+ where
155+
156+ goDecl :: Declaration -> SupplyT (Either ErrorStack) Declaration
157+ (goDecl, _, _) = everywhereOnValuesM return goExpr return
158+
159+ goExpr :: Expr -> SupplyT (Either ErrorStack) Expr
160+ goExpr (OperatorSection op (Left val)) = return $ App op val
161+ goExpr (OperatorSection op (Right val)) = do
162+ arg <- Ident <$> freshName
163+ return $ Abs (Left arg) $ App (App op (Var (Qualified Nothing arg))) val
164+ goExpr other = return other
src/Language/PureScript/Sugar/TypeClasses.hs+23−23
@@ -21,23 +21,22 @@ module Language.PureScript.Sugar.TypeClasses
21 ) where
21 ) where
22
22
23import Language.PureScript.AST hiding (isExported)
23import Language.PureScript.AST hiding (isExported)
24−import Language.PureScript.Names
25−import Language.PureScript.Types
26−import Language.PureScript.Kinds
27−import Language.PureScript.Sugar.CaseDeclarations
28import Language.PureScript.Environment
24import Language.PureScript.Environment
29import Language.PureScript.Errors
25import Language.PureScript.Errors
30−import Language.PureScript.Supply
26+import Language.PureScript.Kinds
27+import Language.PureScript.Names
31import Language.PureScript.Pretty.Types (prettyPrintTypeAtom)
28import Language.PureScript.Pretty.Types (prettyPrintTypeAtom)
29+import Language.PureScript.Sugar.CaseDeclarations
30+import Language.PureScript.Supply
31+import Language.PureScript.Types
32
32
33import qualified Language.PureScript.Constants as C
33import qualified Language.PureScript.Constants as C
34
34
35import Control.Applicative
35import Control.Applicative
36−import Control.Monad.Error
37−import Control.Monad.State
38import Control.Arrow (first, second)
36import Control.Arrow (first, second)
37+import Control.Monad.Except
38+import Control.Monad.State
39import Data.List ((\\), find)
39import Data.List ((\\), find)
40−import Data.Monoid ((<>))
41import Data.Maybe (catMaybes, mapMaybe, isJust)
40import Data.Maybe (catMaybes, mapMaybe, isJust)
42
41
43import qualified Data.Map as M
42import qualified Data.Map as M
@@ -158,15 +157,15 @@ desugarDecl mn exps = go
158 where
157 where
159 go d@(TypeClassDeclaration name args implies members) = do
158 go d@(TypeClassDeclaration name args implies members) = do
160 modify (M.insert (mn, name) d)
159 modify (M.insert (mn, name) d)
161− return $ (Nothing, d : typeClassDictionaryDeclaration name args implies members : map (typeClassMemberToDictionaryAccessor mn name args) members)
160+ return (Nothing, d : typeClassDictionaryDeclaration name args implies members : map (typeClassMemberToDictionaryAccessor mn name args) members)
162 go d@(ExternInstanceDeclaration name _ className tys) = return (expRef name className tys, [d])
161 go d@(ExternInstanceDeclaration name _ className tys) = return (expRef name className tys, [d])
163 go d@(TypeInstanceDeclaration name deps className tys members) = do
162 go d@(TypeInstanceDeclaration name deps className tys members) = do
164 desugared <- lift $ desugarCases members
163 desugared <- lift $ desugarCases members
165 dictDecl <- typeInstanceDictionaryDeclaration name mn deps className tys desugared
164 dictDecl <- typeInstanceDictionaryDeclaration name mn deps className tys desugared
166− return $ (expRef name className tys, [d, dictDecl])
165+ return (expRef name className tys, [d, dictDecl])
167− go (PositionedDeclaration pos d) = do
166+ go (PositionedDeclaration pos com d) = do
168 (dr, ds) <- rethrowWithPosition pos $ desugarDecl mn exps d
167 (dr, ds) <- rethrowWithPosition pos $ desugarDecl mn exps d
169− return (dr, map (PositionedDeclaration pos) ds)
168+ return (dr, map (PositionedDeclaration pos com) ds)
170 go other = return (Nothing, [other])
169 go other = return (Nothing, [other])
171
170
172 expRef :: Ident -> Qualified ProperName -> [Type] -> Maybe DeclarationRef
171 expRef :: Ident -> Qualified ProperName -> [Type] -> Maybe DeclarationRef
@@ -197,7 +196,7 @@ desugarDecl mn exps = go
197
196
198memberToNameAndType :: Declaration -> (Ident, Type)
197memberToNameAndType :: Declaration -> (Ident, Type)
199memberToNameAndType (TypeDeclaration ident ty) = (ident, ty)
198memberToNameAndType (TypeDeclaration ident ty) = (ident, ty)
200−memberToNameAndType (PositionedDeclaration _ d) = memberToNameAndType d
199+memberToNameAndType (PositionedDeclaration _ _ d) = memberToNameAndType d
201memberToNameAndType _ = error "Invalid declaration in type class definition"
200memberToNameAndType _ = error "Invalid declaration in type class definition"
202
201
203typeClassDictionaryDeclaration :: ProperName -> [(String, Maybe Kind)] -> [Constraint] -> [Declaration] -> Declaration
202typeClassDictionaryDeclaration :: ProperName -> [(String, Maybe Kind)] -> [Constraint] -> [Declaration] -> Declaration
@@ -212,11 +211,12 @@ typeClassDictionaryDeclaration name args implies members =
212
211
213typeClassMemberToDictionaryAccessor :: ModuleName -> ProperName -> [(String, Maybe Kind)] -> Declaration -> Declaration
212typeClassMemberToDictionaryAccessor :: ModuleName -> ProperName -> [(String, Maybe Kind)] -> Declaration -> Declaration
214typeClassMemberToDictionaryAccessor mn name args (TypeDeclaration ident ty) =
213typeClassMemberToDictionaryAccessor mn name args (TypeDeclaration ident ty) =
214+ let className = Qualified (Just mn) name
215− ValueDeclaration ident TypeClassAccessorImport [] $ Right $
215+ in ValueDeclaration ident TypeClassAccessorImport [] $ Right $
216− TypedValue False (Abs (Left $ Ident "dict") (Accessor (runIdent ident) (Var $ Qualified Nothing (Ident "dict")))) $
216+ TypedValue False (TypeClassDictionaryAccessor className ident) $
217− moveQuantifiersToFront (quantify (ConstrainedType [(Qualified (Just mn) name, map (TypeVar . fst) args)] ty))
217+ moveQuantifiersToFront (quantify (ConstrainedType [(className, map (TypeVar . fst) args)] ty))
218−typeClassMemberToDictionaryAccessor mn name args (PositionedDeclaration pos d) =
218+typeClassMemberToDictionaryAccessor mn name args (PositionedDeclaration pos com d) =
219− PositionedDeclaration pos $ typeClassMemberToDictionaryAccessor mn name args d
219+ PositionedDeclaration pos com $ typeClassMemberToDictionaryAccessor mn name args d
220typeClassMemberToDictionaryAccessor _ _ _ _ = error "Invalid declaration in type class definition"
220typeClassMemberToDictionaryAccessor _ _ _ _ = error "Invalid declaration in type class definition"
221
221
222unit :: Type
222unit :: Type
@@ -224,7 +224,7 @@ unit = TypeApp tyObject REmpty
224
224
225typeInstanceDictionaryDeclaration :: Ident -> ModuleName -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar Declaration
225typeInstanceDictionaryDeclaration :: Ident -> ModuleName -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar Declaration
226typeInstanceDictionaryDeclaration name mn deps className tys decls =
226typeInstanceDictionaryDeclaration name mn deps className tys decls =
227− rethrow (strMsg ("Error in type class instance " ++ show className ++ " " ++ unwords (map prettyPrintTypeAtom tys) ++ ":") <>) $ do
227+ rethrow (mkCompileError ("Error in type class instance " ++ show className ++ " " ++ unwords (map prettyPrintTypeAtom tys) ++ ":") Nothing `combineErrors`) $ do
228 m <- get
228 m <- get
229
229
230 -- Lookup the type arguments and member types for the type class
230 -- Lookup the type arguments and member types for the type class
@@ -263,7 +263,7 @@ typeInstanceDictionaryDeclaration name mn deps className tys decls =
263 where
263 where
264
264
265 declName :: Declaration -> Maybe Ident
265 declName :: Declaration -> Maybe Ident
266− declName (PositionedDeclaration _ d) = declName d
266+ declName (PositionedDeclaration _ _ d) = declName d
267 declName (ValueDeclaration ident _ _ _) = Just ident
267 declName (ValueDeclaration ident _ _ _) = Just ident
268 declName (TypeDeclaration ident _) = Just ident
268 declName (TypeDeclaration ident _) = Just ident
269 declName _ = Nothing
269 declName _ = Nothing
@@ -272,15 +272,15 @@ typeInstanceDictionaryDeclaration name mn deps className tys decls =
272 memberToValue tys' (ValueDeclaration ident _ [] (Right val)) = do
272 memberToValue tys' (ValueDeclaration ident _ [] (Right val)) = do
273 _ <- lift . lift . maybe (Left $ mkErrorStack ("Type class does not define member '" ++ show ident ++ "'") Nothing) Right $ lookup ident tys'
273 _ <- lift . lift . maybe (Left $ mkErrorStack ("Type class does not define member '" ++ show ident ++ "'") Nothing) Right $ lookup ident tys'
274 return val
274 return val
275− memberToValue tys' (PositionedDeclaration pos d) = rethrowWithPosition pos $ do
275+ memberToValue tys' (PositionedDeclaration pos com d) = rethrowWithPosition pos $ do
276 val <- memberToValue tys' d
276 val <- memberToValue tys' d
277− return (PositionedValue pos val)
277+ return (PositionedValue pos com val)
278 memberToValue _ _ = error "Invalid declaration in type instance definition"
278 memberToValue _ _ = error "Invalid declaration in type instance definition"
279
279
280typeClassMemberName :: Declaration -> String
280typeClassMemberName :: Declaration -> String
281typeClassMemberName (TypeDeclaration ident _) = runIdent ident
281typeClassMemberName (TypeDeclaration ident _) = runIdent ident
282typeClassMemberName (ValueDeclaration ident _ _ _) = runIdent ident
282typeClassMemberName (ValueDeclaration ident _ _ _) = runIdent ident
283−typeClassMemberName (PositionedDeclaration _ d) = typeClassMemberName d
283+typeClassMemberName (PositionedDeclaration _ _ d) = typeClassMemberName d
284typeClassMemberName d = error $ "Invalid declaration in type class definition: " ++ show d
284typeClassMemberName d = error $ "Invalid declaration in type class definition: " ++ show d
285
285
286superClassDictionaryNames :: [Constraint] -> [String]
286superClassDictionaryNames :: [Constraint] -> [String]
src/Language/PureScript/Sugar/TypeDeclarations.hs+6−8
@@ -19,11 +19,9 @@ module Language.PureScript.Sugar.TypeDeclarations (
19 desugarTypeDeclarationsModule
19 desugarTypeDeclarationsModule
20) where
20) where
21
21
22−import Data.Monoid ((<>))
23−
24import Control.Applicative
22import Control.Applicative
25−import Control.Monad.Error.Class
26import Control.Monad (forM)
23import Control.Monad (forM)
24+import Control.Monad.Except (throwError)
27
25
28import Language.PureScript.AST
26import Language.PureScript.AST
29import Language.PureScript.Names
27import Language.PureScript.Names
@@ -36,25 +34,25 @@ import Language.PureScript.Traversals
36--
34--
37desugarTypeDeclarationsModule :: [Module] -> Either ErrorStack [Module]
35desugarTypeDeclarationsModule :: [Module] -> Either ErrorStack [Module]
38desugarTypeDeclarationsModule ms = forM ms $ \(Module name ds exps) ->
36desugarTypeDeclarationsModule ms = forM ms $ \(Module name ds exps) ->
39− rethrow (strMsg ("Error in module " ++ show name) <>) $
37+ rethrow (mkCompileError ("Error in module " ++ show name) Nothing `combineErrors`) $
40 Module name <$> desugarTypeDeclarations ds <*> pure exps
38 Module name <$> desugarTypeDeclarations ds <*> pure exps
41
39
42-- |
40-- |
43-- Replace all top level type declarations with type annotations
41-- Replace all top level type declarations with type annotations
44--
42--
45desugarTypeDeclarations :: [Declaration] -> Either ErrorStack [Declaration]
43desugarTypeDeclarations :: [Declaration] -> Either ErrorStack [Declaration]
46−desugarTypeDeclarations (PositionedDeclaration pos d : ds) = do
44+desugarTypeDeclarations (PositionedDeclaration pos com d : ds) = do
47 (d' : ds') <- rethrowWithPosition pos $ desugarTypeDeclarations (d : ds)
45 (d' : ds') <- rethrowWithPosition pos $ desugarTypeDeclarations (d : ds)
48− return (PositionedDeclaration pos d' : ds')
46+ return (PositionedDeclaration pos com d' : ds')
49desugarTypeDeclarations (TypeDeclaration name ty : d : rest) = do
47desugarTypeDeclarations (TypeDeclaration name ty : d : rest) = do
50 (_, nameKind, val) <- fromValueDeclaration d
48 (_, nameKind, val) <- fromValueDeclaration d
51 desugarTypeDeclarations (ValueDeclaration name nameKind [] (Right (TypedValue True val ty)) : rest)
49 desugarTypeDeclarations (ValueDeclaration name nameKind [] (Right (TypedValue True val ty)) : rest)
52 where
50 where
53 fromValueDeclaration :: Declaration -> Either ErrorStack (Ident, NameKind, Expr)
51 fromValueDeclaration :: Declaration -> Either ErrorStack (Ident, NameKind, Expr)
54 fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
52 fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
55− fromValueDeclaration (PositionedDeclaration pos d') = do
53+ fromValueDeclaration (PositionedDeclaration pos com d') = do
56 (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
54 (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
57− return (ident, nameKind, PositionedValue pos val)
55+ return (ident, nameKind, PositionedValue pos com val)
58 fromValueDeclaration _ = throwError $ mkErrorStack ("Orphan type declaration for " ++ show name) Nothing
56 fromValueDeclaration _ = throwError $ mkErrorStack ("Orphan type declaration for " ++ show name) Nothing
59desugarTypeDeclarations (TypeDeclaration name _ : []) = throwError $ mkErrorStack ("Orphan type declaration for " ++ show name) Nothing
57desugarTypeDeclarations (TypeDeclaration name _ : []) = throwError $ mkErrorStack ("Orphan type declaration for " ++ show name) Nothing
60desugarTypeDeclarations (ValueDeclaration name nameKind bs val : rest) = do
58desugarTypeDeclarations (ValueDeclaration name nameKind bs val : rest) = do
src/Language/PureScript/Supply.hs+1−1
@@ -24,7 +24,7 @@ import Data.Functor.Identity
24
24
25import Control.Applicative
25import Control.Applicative
26import Control.Monad.State
26import Control.Monad.State
27−import Control.Monad.Error.Class
27+import Control.Monad.Except
28
28
29newtype SupplyT m a = SupplyT { unSupplyT :: StateT Integer m a } deriving (Functor, Applicative, Monad, MonadTrans)
29newtype SupplyT m a = SupplyT { unSupplyT :: StateT Integer m a } deriving (Functor, Applicative, Monad, MonadTrans)
30
30
src/Language/PureScript/TypeChecker.hs+19−19
@@ -27,12 +27,11 @@ import Language.PureScript.TypeChecker.Synonyms as T
27
27
28import Data.Maybe
28import Data.Maybe
29import Data.List (nub, (\\), find, intercalate)
29import Data.List (nub, (\\), find, intercalate)
30−import Data.Monoid ((<>))
31import Data.Foldable (for_)
30import Data.Foldable (for_)
32import qualified Data.Map as M
31import qualified Data.Map as M
33
32
34import Control.Monad.State
33import Control.Monad.State
35−import Control.Monad.Error
34+import Control.Monad.Except
36
35
37import Language.PureScript.Types
36import Language.PureScript.Types
38import Language.PureScript.Names
37import Language.PureScript.Names
@@ -47,7 +46,7 @@ addDataType moduleName dtype name args dctors ctorKind = do
47 env <- getEnv
46 env <- getEnv
48 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (ctorKind, DataType args dctors) (types env) }
47 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (ctorKind, DataType args dctors) (types env) }
49 forM_ dctors $ \(dctor, tys) ->
48 forM_ dctors $ \(dctor, tys) ->
50− rethrow (strMsg ("Error in data constructor " ++ show dctor) <>) $
49+ rethrow (mkCompileError ("Error in data constructor " ++ show dctor) Nothing `combineErrors`) $
51 addDataConstructor moduleName dtype name (map fst args) dctor tys
50 addDataConstructor moduleName dtype name (map fst args) dctor tys
52
51
53addDataConstructor :: ModuleName -> DataDeclType -> ProperName -> [String] -> ProperName -> [Type] -> Check ()
52addDataConstructor :: ModuleName -> DataDeclType -> ProperName -> [String] -> ProperName -> [Type] -> Check ()
@@ -57,7 +56,8 @@ addDataConstructor moduleName dtype name args dctor tys = do
57 let retTy = foldl TypeApp (TypeConstructor (Qualified (Just moduleName) name)) (map TypeVar args)
56 let retTy = foldl TypeApp (TypeConstructor (Qualified (Just moduleName) name)) (map TypeVar args)
58 let dctorTy = foldr function retTy tys
57 let dctorTy = foldr function retTy tys
59 let polyType = mkForAll args dctorTy
58 let polyType = mkForAll args dctorTy
59+ let fields = [Ident ("value" ++ show n) | n <- [0..(length tys - 1)]]
60− putEnv $ env { dataConstructors = M.insert (Qualified (Just moduleName) dctor) (dtype, name, polyType) (dataConstructors env) }
60+ putEnv $ env { dataConstructors = M.insert (Qualified (Just moduleName) dctor) (dtype, name, polyType, fields) (dataConstructors env) }
61
61
62addTypeSynonym :: ModuleName -> ProperName -> [(String, Maybe Kind)] -> Type -> Kind -> Check ()
62addTypeSynonym :: ModuleName -> ProperName -> [(String, Maybe Kind)] -> Type -> Kind -> Check ()
63addTypeSynonym moduleName name args ty kind = do
63addTypeSynonym moduleName name args ty kind = do
@@ -84,12 +84,12 @@ addTypeClass moduleName pn args implies ds =
84 modify $ \st -> st { checkEnv = (checkEnv st) { typeClasses = M.insert (Qualified (Just moduleName) pn) (args, members, implies) (typeClasses . checkEnv $ st) } }
84 modify $ \st -> st { checkEnv = (checkEnv st) { typeClasses = M.insert (Qualified (Just moduleName) pn) (args, members, implies) (typeClasses . checkEnv $ st) } }
85 where
85 where
86 toPair (TypeDeclaration ident ty) = (ident, ty)
86 toPair (TypeDeclaration ident ty) = (ident, ty)
87− toPair (PositionedDeclaration _ d) = toPair d
87+ toPair (PositionedDeclaration _ _ d) = toPair d
88 toPair _ = error "Invalid declaration in TypeClassDeclaration"
88 toPair _ = error "Invalid declaration in TypeClassDeclaration"
89
89
90addTypeClassDictionaries :: [TypeClassDictionaryInScope] -> Check ()
90addTypeClassDictionaries :: [TypeClassDictionaryInScope] -> Check ()
91addTypeClassDictionaries entries =
91addTypeClassDictionaries entries =
92− let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
92+ let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
93 in modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = (typeClassDictionaries . checkEnv $ st) `M.union` mentries } }
93 in modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = (typeClassDictionaries . checkEnv $ st) `M.union` mentries } }
94
94
95checkDuplicateTypeArguments :: [String] -> Check ()
95checkDuplicateTypeArguments :: [String] -> Check ()
@@ -133,7 +133,7 @@ typeCheckAll mainModuleName moduleName exps = go
133 go :: [Declaration] -> Check [Declaration]
133 go :: [Declaration] -> Check [Declaration]
134 go [] = return []
134 go [] = return []
135 go (DataDeclaration dtype name args dctors : rest) = do
135 go (DataDeclaration dtype name args dctors : rest) = do
136− rethrow (strMsg ("Error in type constructor " ++ show name) <>) $ do
136+ rethrow (mkCompileError ("Error in type constructor " ++ show name) Nothing `combineErrors`) $ do
137 when (dtype == Newtype) $ checkNewtype dctors
137 when (dtype == Newtype) $ checkNewtype dctors
138 checkDuplicateTypeArguments $ map fst args
138 checkDuplicateTypeArguments $ map fst args
139 ctorKind <- kindsOf True moduleName name args (concatMap snd dctors)
139 ctorKind <- kindsOf True moduleName name args (concatMap snd dctors)
@@ -147,7 +147,7 @@ typeCheckAll mainModuleName moduleName exps = go
147 checkNewtype [(_, _)] = throwError . strMsg $ "newtypes constructors must have a single argument"
147 checkNewtype [(_, _)] = throwError . strMsg $ "newtypes constructors must have a single argument"
148 checkNewtype _ = throwError . strMsg $ "newtypes must have a single constructor"
148 checkNewtype _ = throwError . strMsg $ "newtypes must have a single constructor"
149 go (d@(DataBindingGroupDeclaration tys) : rest) = do
149 go (d@(DataBindingGroupDeclaration tys) : rest) = do
150− rethrow (strMsg "Error in data binding group" <>) $ do
150+ rethrow (mkCompileError "Error in data binding group" Nothing `combineErrors`) $ do
151 let syns = mapMaybe toTypeSynonym tys
151 let syns = mapMaybe toTypeSynonym tys
152 let dataDecls = mapMaybe toDataDecl tys
152 let dataDecls = mapMaybe toDataDecl tys
153 (syn_ks, data_ks) <- kindsOfAll moduleName syns (map (\(_, name, args, dctors) -> (name, args, concatMap snd dctors)) dataDecls)
153 (syn_ks, data_ks) <- kindsOfAll moduleName syns (map (\(_, name, args, dctors) -> (name, args, concatMap snd dctors)) dataDecls)
@@ -163,13 +163,13 @@ typeCheckAll mainModuleName moduleName exps = go
163 return $ d : ds
163 return $ d : ds
164 where
164 where
165 toTypeSynonym (TypeSynonymDeclaration nm args ty) = Just (nm, args, ty)
165 toTypeSynonym (TypeSynonymDeclaration nm args ty) = Just (nm, args, ty)
166− toTypeSynonym (PositionedDeclaration _ d') = toTypeSynonym d'
166+ toTypeSynonym (PositionedDeclaration _ _ d') = toTypeSynonym d'
167 toTypeSynonym _ = Nothing
167 toTypeSynonym _ = Nothing
168 toDataDecl (DataDeclaration dtype nm args dctors) = Just (dtype, nm, args, dctors)
168 toDataDecl (DataDeclaration dtype nm args dctors) = Just (dtype, nm, args, dctors)
169− toDataDecl (PositionedDeclaration _ d') = toDataDecl d'
169+ toDataDecl (PositionedDeclaration _ _ d') = toDataDecl d'
170 toDataDecl _ = Nothing
170 toDataDecl _ = Nothing
171 go (TypeSynonymDeclaration name args ty : rest) = do
171 go (TypeSynonymDeclaration name args ty : rest) = do
172− rethrow (strMsg ("Error in type synonym " ++ show name) <>) $ do
172+ rethrow (mkCompileError ("Error in type synonym " ++ show name) Nothing `combineErrors`) $ do
173 checkDuplicateTypeArguments $ map fst args
173 checkDuplicateTypeArguments $ map fst args
174 kind <- kindsOf False moduleName name args [ty]
174 kind <- kindsOf False moduleName name args [ty]
175 let args' = args `withKinds` kind
175 let args' = args `withKinds` kind
@@ -178,7 +178,7 @@ typeCheckAll mainModuleName moduleName exps = go
178 return $ TypeSynonymDeclaration name args ty : ds
178 return $ TypeSynonymDeclaration name args ty : ds
179 go (TypeDeclaration _ _ : _) = error "Type declarations should have been removed"
179 go (TypeDeclaration _ _ : _) = error "Type declarations should have been removed"
180 go (ValueDeclaration name nameKind [] (Right val) : rest) = do
180 go (ValueDeclaration name nameKind [] (Right val) : rest) = do
181− d <- rethrow (strMsg ("Error in declaration " ++ show name) <>) $ do
181+ d <- rethrow (mkCompileError ("Error in declaration " ++ show name) Nothing `combineErrors`) $ do
182 valueIsNotDefined moduleName name
182 valueIsNotDefined moduleName name
183 [(_, (val', ty))] <- typesOf mainModuleName moduleName [(name, val)]
183 [(_, (val', ty))] <- typesOf mainModuleName moduleName [(name, val)]
184 addValue moduleName name ty nameKind
184 addValue moduleName name ty nameKind
@@ -187,7 +187,7 @@ typeCheckAll mainModuleName moduleName exps = go
187 return $ d : ds
187 return $ d : ds
188 go (ValueDeclaration{} : _) = error "Binders were not desugared"
188 go (ValueDeclaration{} : _) = error "Binders were not desugared"
189 go (BindingGroupDeclaration vals : rest) = do
189 go (BindingGroupDeclaration vals : rest) = do
190− d <- rethrow (strMsg ("Error in binding group " ++ show (map (\(ident, _, _) -> ident) vals)) <>) $ do
190+ d <- rethrow (mkCompileError ("Error in binding group " ++ show (map (\(ident, _, _) -> ident) vals)) Nothing `combineErrors`) $ do
191 forM_ (map (\(ident, _, _) -> ident) vals) $ \name ->
191 forM_ (map (\(ident, _, _) -> ident) vals) $ \name ->
192 valueIsNotDefined moduleName name
192 valueIsNotDefined moduleName name
193 tys <- typesOf mainModuleName moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals
193 tys <- typesOf mainModuleName moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals
@@ -207,7 +207,7 @@ typeCheckAll mainModuleName moduleName exps = go
207 ds <- go rest
207 ds <- go rest
208 return $ d : ds
208 return $ d : ds
209 go (d@(ExternDeclaration importTy name _ ty) : rest) = do
209 go (d@(ExternDeclaration importTy name _ ty) : rest) = do
210− rethrow (strMsg ("Error in foreign import declaration " ++ show name) <>) $ do
210+ rethrow (mkCompileError ("Error in foreign import declaration " ++ show name) Nothing `combineErrors`) $ do
211 env <- getEnv
211 env <- getEnv
212 kind <- kindOf moduleName ty
212 kind <- kindOf moduleName ty
213 guardWith (strMsg "Expected kind *") $ kind == Star
213 guardWith (strMsg "Expected kind *") $ kind == Star
@@ -239,10 +239,10 @@ typeCheckAll mainModuleName moduleName exps = go
239 goInstance d dictName deps className tys rest
239 goInstance d dictName deps className tys rest
240 go (d@(ExternInstanceDeclaration dictName deps className tys) : rest) = do
240 go (d@(ExternInstanceDeclaration dictName deps className tys) : rest) = do
241 goInstance d dictName deps className tys rest
241 goInstance d dictName deps className tys rest
242− go (PositionedDeclaration pos d : rest) =
242+ go (PositionedDeclaration pos com d : rest) =
243 rethrowWithPosition pos $ do
243 rethrowWithPosition pos $ do
244 (d' : rest') <- go (d : rest)
244 (d' : rest') <- go (d : rest)
245− return (PositionedDeclaration pos d' : rest')
245+ return (PositionedDeclaration pos com d' : rest')
246 goInstance :: Declaration -> Ident -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Check [Declaration]
246 goInstance :: Declaration -> Ident -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Check [Declaration]
247 goInstance d dictName deps className tys rest = do
247 goInstance d dictName deps className tys rest = do
248 mapM_ (checkTypeClassInstance moduleName) tys
248 mapM_ (checkTypeClassInstance moduleName) tys
@@ -258,7 +258,7 @@ typeCheckAll mainModuleName moduleName exps = go
258
258
259 exportsInstance :: DeclarationRef -> Bool
259 exportsInstance :: DeclarationRef -> Bool
260 exportsInstance (TypeInstanceRef name) | name == dictName = True
260 exportsInstance (TypeInstanceRef name) | name == dictName = True
261− exportsInstance (PositionedDeclarationRef _ r) = exportsInstance r
261+ exportsInstance (PositionedDeclarationRef _ _ r) = exportsInstance r
262 exportsInstance _ = False
262 exportsInstance _ = False
263
263
264 -- |
264 -- |
@@ -346,10 +346,10 @@ typeCheckModule mainModuleName (Module mn decls (Just exps)) = do
346 runValueRef _ = error "non-ValueRef passed to runValueRef"
346 runValueRef _ = error "non-ValueRef passed to runValueRef"
347 findClassMembers :: Declaration -> Maybe [Ident]
347 findClassMembers :: Declaration -> Maybe [Ident]
348 findClassMembers (TypeClassDeclaration name' _ _ ds) | name == name' = Just $ map extractMemberName ds
348 findClassMembers (TypeClassDeclaration name' _ _ ds) | name == name' = Just $ map extractMemberName ds
349− findClassMembers (PositionedDeclaration _ d) = findClassMembers d
349+ findClassMembers (PositionedDeclaration _ _ d) = findClassMembers d
350 findClassMembers _ = Nothing
350 findClassMembers _ = Nothing
351 extractMemberName :: Declaration -> Ident
351 extractMemberName :: Declaration -> Ident
352− extractMemberName (PositionedDeclaration _ d) = extractMemberName d
352+ extractMemberName (PositionedDeclaration _ _ d) = extractMemberName d
353 extractMemberName (TypeDeclaration memberName _) = memberName
353 extractMemberName (TypeDeclaration memberName _) = memberName
354 extractMemberName _ = error "Unexpected declaration in typeclass member list"
354 extractMemberName _ = error "Unexpected declaration in typeclass member list"
355 checkClassMembersAreExported _ = return ()
355 checkClassMembersAreExported _ = return ()
src/Language/PureScript/TypeChecker/Entailment.hs+25−4
@@ -20,13 +20,15 @@ module Language.PureScript.TypeChecker.Entailment (
20import Data.Function (on)
20import Data.Function (on)
21import Data.List
21import Data.List
22import Data.Maybe (maybeToList)
22import Data.Maybe (maybeToList)
23+import Data.Foldable (foldMap)
23import qualified Data.Map as M
24import qualified Data.Map as M
24
25
25import Control.Applicative
26import Control.Applicative
26import Control.Arrow (Arrow(..))
27import Control.Arrow (Arrow(..))
27−import Control.Monad.Error
28+import Control.Monad.Except
28
29
29import Language.PureScript.AST
30import Language.PureScript.AST
31+import Language.PureScript.Errors
30import Language.PureScript.Environment
32import Language.PureScript.Environment
31import Language.PureScript.Names
33import Language.PureScript.Names
32import Language.PureScript.Pretty
34import Language.PureScript.Pretty
@@ -199,13 +201,32 @@ entails env moduleName context = solve (sortedNubBy canonicalizeDictionary (filt
199-- and return a substitution from type variables to types which makes the type heads unify.
201-- and return a substitution from type variables to types which makes the type heads unify.
200--
202--
201typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]
203typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]
202−typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
204+typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
203−typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
205+typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
204typeHeadsAreEqual _ _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
206typeHeadsAreEqual _ _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
205−typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2 <*> typeHeadsAreEqual m e t1 t2
207+typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2
208+ <*> typeHeadsAreEqual m e t1 t2
206typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e name args of
209typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e name args of
207 Left _ -> Nothing
210 Left _ -> Nothing
208 Right t1 -> typeHeadsAreEqual m e t1 t2
211 Right t1 -> typeHeadsAreEqual m e t1 t2
212+typeHeadsAreEqual _ _ REmpty REmpty = Just []
213+typeHeadsAreEqual m e r1@(RCons _ _ _) r2@(RCons _ _ _) =
214+ let (s1, r1') = rowToList r1
215+ (s2, r2') = rowToList r2
216+
217+ int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
218+ sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
219+ sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
220+ in (++) <$> foldMap (\(t1, t2) -> typeHeadsAreEqual m e t1 t2) int
221+ <*> go sd1 r1' sd2 r2'
222+ where
223+ go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Maybe [(String, Type)]
224+ go [] REmpty [] REmpty = Just []
225+ go [] (TUnknown _) _ _ = Just []
226+ go [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = Just []
227+ go [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = Just []
228+ go sd r [] (TypeVar v) = Just [(v, rowFromList (sd, r))]
229+ go _ _ _ _ = Nothing
209typeHeadsAreEqual _ _ _ _ = Nothing
230typeHeadsAreEqual _ _ _ _ = Nothing
210
231
211-- |
232-- |
src/Language/PureScript/TypeChecker/Kinds.hs+72−46
@@ -14,21 +14,23 @@
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16{-# OPTIONS_GHC -fno-warn-orphans #-}
16{-# OPTIONS_GHC -fno-warn-orphans #-}
17−{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
17+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TupleSections #-}
18
18
19module Language.PureScript.TypeChecker.Kinds (
19module Language.PureScript.TypeChecker.Kinds (
20 kindOf,
20 kindOf,
21+ kindOfWithScopedVars,
21 kindsOf,
22 kindsOf,
22 kindsOfAll
23 kindsOfAll
23) where
24) where
24
25
25import Data.Maybe (fromMaybe)
26import Data.Maybe (fromMaybe)
26−import Data.Monoid ((<>))
27+
27import qualified Data.HashMap.Strict as H
28import qualified Data.HashMap.Strict as H
28import qualified Data.Map as M
29import qualified Data.Map as M
29
30
31+import Control.Arrow (second)
30import Control.Applicative
32import Control.Applicative
31−import Control.Monad.Error
33+import Control.Monad.Except
32import Control.Monad.State
34import Control.Monad.State
33import Control.Monad.Unify
35import Control.Monad.Unify
34
36
@@ -69,11 +71,19 @@ instance Unifiable Check Kind where
69-- Infer the kind of a single type
71-- Infer the kind of a single type
70--
72--
71kindOf :: ModuleName -> Type -> Check Kind
73kindOf :: ModuleName -> Type -> Check Kind
72−kindOf _ ty =
74+kindOf _ ty = fst <$> kindOfWithScopedVars ty
75+
76+-- |
77+-- Infer the kind of a single type, returning the kinds of any scoped type variables
78+--
79+kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])
80+kindOfWithScopedVars ty =
73− rethrow (mkErrorStack "Error checking kind" (Just (TypeError ty)) <>) $
81+ rethrow (mkCompileError "Error checking kind" (Just (TypeError ty)) `combineErrors`) $
74− fmap (starIfUnknown . tidyUp) . liftUnify $ infer ty
82+ fmap tidyUp . liftUnify $ infer ty
75 where
83 where
76− tidyUp (k, sub) = sub $? k
84+ tidyUp ((k, args), sub) = ( starIfUnknown (sub $? k)
85+ , map (second (starIfUnknown . (sub $?))) args
86+ )
77
87
78-- |
88-- |
79-- Infer the kind of a type constructor with a collection of arguments and a collection of associated data constructors
89-- Infer the kind of a type constructor with a collection of arguments and a collection of associated data constructors
@@ -125,7 +135,7 @@ kindsOfAll moduleName syns tys = fmap tidyUp . liftUnify $ do
125--
135--
126solveTypes :: Bool -> [Type] -> [Kind] -> Kind -> UnifyT Kind Check Kind
136solveTypes :: Bool -> [Type] -> [Kind] -> Kind -> UnifyT Kind Check Kind
127solveTypes isData ts kargs tyCon = do
137solveTypes isData ts kargs tyCon = do
128− ks <- mapM infer ts
138+ ks <- mapM (fmap fst . infer) ts
129 when isData $ do
139 when isData $ do
130 tyCon =?= foldr FunKind Star kargs
140 tyCon =?= foldr FunKind Star kargs
131 forM_ ks $ \k -> k =?= Star
141 forM_ ks $ \k -> k =?= Star
@@ -145,48 +155,64 @@ starIfUnknown k = k
145-- |
155-- |
146-- Infer a kind for a type
156-- Infer a kind for a type
147--
157--
148−infer :: Type -> UnifyT Kind Check Kind
158+infer :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
149−infer ty = rethrow (mkErrorStack "Error inferring type of value" (Just (TypeError ty)) <>) $ infer' ty
159+infer ty = rethrow (mkCompileError "Error inferring type of value" (Just (TypeError ty)) `combineErrors`) $ infer' ty
150
160
151−infer' :: Type -> UnifyT Kind Check Kind
161+infer' :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
152−infer' TypeWildcard = fresh
153−infer' (TypeVar v) = do
154− Just moduleName <- checkCurrentModule <$> get
155− UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
156−infer' c@(TypeConstructor v) = do
157− env <- liftCheck getEnv
158− case M.lookup v (types env) of
159− Nothing -> UnifyT . lift . throwError $ mkErrorStack "Unknown type constructor" (Just (TypeError c))
160− Just (kind, _) -> return kind
161−infer' (TypeApp t1 t2) = do
162− k0 <- fresh
163− k1 <- infer t1
164− k2 <- infer t2
165− k1 =?= FunKind k2 k0
166− return k0
167infer' (ForAll ident ty _) = do
162infer' (ForAll ident ty _) = do
168 k1 <- fresh
163 k1 <- fresh
169 Just moduleName <- checkCurrentModule <$> get
164 Just moduleName <- checkCurrentModule <$> get
170− k2 <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ infer ty
165+ (k2, args) <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ infer ty
171 k2 =?= Star
166 k2 =?= Star
172− return Star
167+ return (Star, (ident, k1) : args)
173−infer' REmpty = do
174− k <- fresh
175− return $ Row k
176−infer' (RCons _ ty row) = do
177− k1 <- infer ty
178− k2 <- infer row
179− k2 =?= Row k1
180− return $ Row k1
181−infer' (ConstrainedType deps ty) = do
182− forM_ deps $ \(className, tys) -> do
183− _ <- infer $ foldl TypeApp (TypeConstructor className) tys
184− return ()
185− k <- infer ty
186− k =?= Star
187− return Star
188infer' (KindedType ty k) = do
168infer' (KindedType ty k) = do
189− k' <- infer ty
169+ (k', args) <- infer ty
190 k =?= k'
170 k =?= k'
191− return k'
171+ return (k', args)
172+infer' other = (, []) <$> go other
173+ where
174+ go :: Type -> UnifyT Kind Check Kind
175+ go (ForAll ident ty _) = do
176+ k1 <- fresh
177+ Just moduleName <- checkCurrentModule <$> get
178+ k2 <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ go ty
179+ k2 =?= Star
180+ return Star
181+ go (KindedType ty k) = do
182+ k' <- go ty
183+ k =?= k'
184+ return k'
185+ go TypeWildcard = fresh
186+ go (TypeVar v) = do
187+ Just moduleName <- checkCurrentModule <$> get
188+ UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
189+ go (Skolem v _ _) = do
190+ Just moduleName <- checkCurrentModule <$> get
191+ UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
192+ go c@(TypeConstructor v) = do
193+ env <- liftCheck getEnv
194+ case M.lookup v (types env) of
195+ Nothing -> UnifyT . lift . throwError $ mkErrorStack "Unknown type constructor" (Just (TypeError c))
196+ Just (kind, _) -> return kind
197+ go (TypeApp t1 t2) = do
198+ k0 <- fresh
199+ k1 <- go t1
200+ k2 <- go t2
201+ k1 =?= FunKind k2 k0
202+ return k0
203+ go REmpty = do
204+ k <- fresh
205+ return $ Row k
206+ go (RCons _ ty row) = do
207+ k1 <- go ty
208+ k2 <- go row
209+ k2 =?= Row k1
210+ return $ Row k1
211+ go (ConstrainedType deps ty) = do
212+ forM_ deps $ \(className, tys) -> do
213+ _ <- go $ foldl TypeApp (TypeConstructor className) tys
214+ return ()
215+ k <- go ty
216+ k =?= Star
217+ return Star
192−infer' _ = error "Invalid argument to infer"
218+ go _ = error "Invalid argument to infer"
src/Language/PureScript/TypeChecker/Monad.hs+20−11
@@ -14,7 +14,7 @@
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, RankNTypes,
16{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, RankNTypes,
17− MultiParamTypeClasses, FlexibleContexts #-}
17+ MultiParamTypeClasses, FlexibleContexts, GADTs #-}
18
18
19module Language.PureScript.TypeChecker.Monad where
19module Language.PureScript.TypeChecker.Monad where
20
20
@@ -22,7 +22,8 @@ import Data.Maybe
22import qualified Data.Map as M
22import qualified Data.Map as M
23
23
24import Control.Applicative
24import Control.Applicative
25−import Control.Monad.Error
25+import Control.Monad.Except
26+import Control.Monad.Reader.Class
26import Control.Monad.State
27import Control.Monad.State
27import Control.Monad.Unify
28import Control.Monad.Unify
28
29
@@ -56,6 +57,12 @@ bindTypes newNames action = do
56 modify $ \st -> st { checkEnv = (checkEnv st) { types = types . checkEnv $ orig } }
57 modify $ \st -> st { checkEnv = (checkEnv st) { types = types . checkEnv $ orig } }
57 return a
58 return a
58
59
60+-- |
61+-- Temporarily bind a collection of names to types
62+--
63+withScopedTypeVars :: (Functor m, MonadState CheckState m) => ModuleName -> [(String, Kind)] -> m a -> m a
64+withScopedTypeVars mn ks = bindTypes (M.fromList (map (\(name, k) -> (Qualified (Just mn) (ProperName name), (k, ScopedTypeVar))) ks))
65+
59-- |
66-- |
60-- Temporarily make a collection of type class dictionaries available
67-- Temporarily make a collection of type class dictionaries available
61--
68--
@@ -102,7 +109,7 @@ makeBindingGroupVisible action = do
102-- |
109-- |
103-- Lookup the type of a value by name in the @Environment@
110-- Lookup the type of a value by name in the @Environment@
104--
111--
105−lookupVariable :: (Error e, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m Type
112+lookupVariable :: (e ~ ErrorStack, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m Type
106lookupVariable currentModule (Qualified moduleName var) = do
113lookupVariable currentModule (Qualified moduleName var) = do
107 env <- getEnv
114 env <- getEnv
108 case M.lookup (fromMaybe currentModule moduleName, var) (names env) of
115 case M.lookup (fromMaybe currentModule moduleName, var) (names env) of
@@ -112,7 +119,7 @@ lookupVariable currentModule (Qualified moduleName var) = do
112-- |
119-- |
113-- Lookup the visibility of a value by name in the @Environment@
120-- Lookup the visibility of a value by name in the @Environment@
114--
121--
115−getVisibility :: (Error e, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m NameVisibility
122+getVisibility :: (e ~ ErrorStack, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m NameVisibility
116getVisibility currentModule (Qualified moduleName var) = do
123getVisibility currentModule (Qualified moduleName var) = do
117 env <- getEnv
124 env <- getEnv
118 case M.lookup (fromMaybe currentModule moduleName, var) (names env) of
125 case M.lookup (fromMaybe currentModule moduleName, var) (names env) of
@@ -122,7 +129,7 @@ getVisibility currentModule (Qualified moduleName var) = do
122-- |
129-- |
123-- Assert that a name is visible
130-- Assert that a name is visible
124--
131--
125−checkVisibility :: (Error e, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m ()
132+checkVisibility :: (e ~ ErrorStack, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m ()
126checkVisibility currentModule name@(Qualified _ var) = do
133checkVisibility currentModule name@(Qualified _ var) = do
127 vis <- getVisibility currentModule name
134 vis <- getVisibility currentModule name
128 case vis of
135 case vis of
@@ -132,7 +139,7 @@ checkVisibility currentModule name@(Qualified _ var) = do
132-- |
139-- |
133-- Lookup the kind of a type by name in the @Environment@
140-- Lookup the kind of a type by name in the @Environment@
134--
141--
135−lookupTypeVariable :: (Error e, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified ProperName -> m Kind
142+lookupTypeVariable :: (e ~ ErrorStack, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified ProperName -> m Kind
136lookupTypeVariable currentModule (Qualified moduleName name) = do
143lookupTypeVariable currentModule (Qualified moduleName name) = do
137 env <- getEnv
144 env <- getEnv
138 case M.lookup (Qualified (Just $ fromMaybe currentModule moduleName) name) (types env) of
145 case M.lookup (Qualified (Just $ fromMaybe currentModule moduleName) name) (types env) of
@@ -165,7 +172,7 @@ data CheckState = CheckState {
165-- The type checking monad, which provides the state of the type checker, and error reporting capabilities
172-- The type checking monad, which provides the state of the type checker, and error reporting capabilities
166--
173--
167newtype Check a = Check { unCheck :: StateT CheckState (Either ErrorStack) a }
174newtype Check a = Check { unCheck :: StateT CheckState (Either ErrorStack) a }
168− deriving (Functor, Monad, Applicative, Alternative, MonadPlus, MonadState CheckState, MonadError ErrorStack)
175+ deriving (Functor, Monad, Applicative, MonadState CheckState, MonadError ErrorStack)
169
176
170-- |
177-- |
171-- Get the current @Environment@
178-- Get the current @Environment@
@@ -188,14 +195,16 @@ modifyEnv f = modify (\s -> s { checkEnv = f (checkEnv s) })
188-- |
195-- |
189-- Run a computation in the Check monad, starting with an empty @Environment@
196-- Run a computation in the Check monad, starting with an empty @Environment@
190--
197--
191−runCheck :: Options mode -> Check a -> Either String (a, Environment)
198+runCheck :: (MonadReader (Options mode) m, MonadError String m) => Check a -> m (a, Environment)
192−runCheck opts = runCheck' opts initEnvironment
199+runCheck = runCheck' initEnvironment
193
200
194-- |
201-- |
195-- Run a computation in the Check monad, failing with an error, or succeeding with a return value and the final @Environment@.
202-- Run a computation in the Check monad, failing with an error, or succeeding with a return value and the final @Environment@.
196--
203--
197−runCheck' :: Options mode -> Environment -> Check a -> Either String (a, Environment)
204+runCheck' :: (MonadReader (Options mode) m, MonadError String m) => Environment -> Check a -> m (a, Environment)
205+runCheck' env c = do
206+ verbose <- asks optionsVerboseErrors
198−runCheck' opts env c = stringifyErrorStack (optionsVerboseErrors opts) $ do
207+ stringifyErrorStack verbose $ do
199 (a, s) <- flip runStateT (CheckState env 0 0 Nothing) $ unCheck c
208 (a, s) <- flip runStateT (CheckState env 0 0 Nothing) $ unCheck c
200 return (a, checkEnv s)
209 return (a, checkEnv s)
201
210
src/Language/PureScript/TypeChecker/Rows.hs+1−1
@@ -19,7 +19,7 @@ module Language.PureScript.TypeChecker.Rows (
19
19
20import Data.List
20import Data.List
21
21
22−import Control.Monad.Error
22+import Control.Monad.Except
23
23
24import Language.PureScript.AST
24import Language.PureScript.AST
25import Language.PureScript.Errors
25import Language.PureScript.Errors
src/Language/PureScript/TypeChecker/Skolems.hs+2−1
@@ -26,7 +26,7 @@ import Data.List (nub, (\\))
26import Data.Monoid
26import Data.Monoid
27
27
28import Control.Applicative
28import Control.Applicative
29−import Control.Monad.Error
29+import Control.Monad.Except
30import Control.Monad.Unify
30import Control.Monad.Unify
31
31
32import Language.PureScript.AST
32import Language.PureScript.AST
@@ -71,6 +71,7 @@ skolemizeTypesInValue :: String -> Int -> SkolemScope -> Expr -> Expr
71skolemizeTypesInValue ident sko scope = let (_, f, _) = everywhereOnValues id go id in f
71skolemizeTypesInValue ident sko scope = let (_, f, _) = everywhereOnValues id go id in f
72 where
72 where
73 go (SuperClassDictionary c ts) = SuperClassDictionary c (map (skolemize ident sko scope) ts)
73 go (SuperClassDictionary c ts) = SuperClassDictionary c (map (skolemize ident sko scope) ts)
74+ go (TypedValue check val ty) = TypedValue check val (skolemize ident sko scope ty)
74 go other = other
75 go other = other
75
76
76-- |
77-- |
src/Language/PureScript/TypeChecker/Subsumption.hs+2−3
@@ -18,11 +18,10 @@ module Language.PureScript.TypeChecker.Subsumption (
18) where
18) where
19
19
20import Data.List (sortBy)
20import Data.List (sortBy)
21−import Data.Monoid
22import Data.Ord (comparing)
21import Data.Ord (comparing)
23
22
24import Control.Applicative
23import Control.Applicative
25−import Control.Monad.Error
24+import Control.Monad.Except
26import Control.Monad.Unify
25import Control.Monad.Unify
27
26
28import Language.PureScript.AST
27import Language.PureScript.AST
@@ -39,7 +38,7 @@ import Language.PureScript.Types
39-- Check whether one type subsumes another, rethrowing errors to provide a better error message
38-- Check whether one type subsumes another, rethrowing errors to provide a better error message
40--
39--
41subsumes :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)
40subsumes :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)
42−subsumes val ty1 ty2 = rethrow (mkErrorStack errorMessage (ExprError <$> val) <>) $ subsumes' val ty1 ty2
41+subsumes val ty1 ty2 = rethrow (mkCompileError errorMessage (ExprError <$> val) `combineErrors`) $ subsumes' val ty1 ty2
43 where
42 where
44 errorMessage = "Error checking that type "
43 errorMessage = "Error checking that type "
45 ++ prettyPrintType ty1
44 ++ prettyPrintType ty1
src/Language/PureScript/TypeChecker/Synonyms.hs+6−5
@@ -13,7 +13,7 @@
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16−{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses #-}
16+{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, GADTs #-}
17
17
18module Language.PureScript.TypeChecker.Synonyms (
18module Language.PureScript.TypeChecker.Synonyms (
19 saturateAllTypeSynonyms,
19 saturateAllTypeSynonyms,
@@ -28,10 +28,11 @@ import Data.Maybe (fromMaybe)
28import qualified Data.Map as M
28import qualified Data.Map as M
29
29
30import Control.Applicative
30import Control.Applicative
31−import Control.Monad.Error
31+import Control.Monad.Except
32import Control.Monad.State
32import Control.Monad.State
33
33
34import Language.PureScript.Environment
34import Language.PureScript.Environment
35+import Language.PureScript.Errors
35import Language.PureScript.Names
36import Language.PureScript.Names
36import Language.PureScript.TypeChecker.Monad
37import Language.PureScript.TypeChecker.Monad
37import Language.PureScript.Types
38import Language.PureScript.Types
@@ -82,7 +83,7 @@ replaceAllTypeSynonyms' env d =
82 in
83 in
83 saturateAllTypeSynonyms syns d
84 saturateAllTypeSynonyms syns d
84
85
85−replaceAllTypeSynonyms :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
86+replaceAllTypeSynonyms :: (e ~ ErrorStack, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
86replaceAllTypeSynonyms d = do
87replaceAllTypeSynonyms d = do
87 env <- getEnv
88 env <- getEnv
88 either (throwError . strMsg) return $ replaceAllTypeSynonyms' env d
89 either (throwError . strMsg) return $ replaceAllTypeSynonyms' env d
@@ -98,12 +99,12 @@ expandTypeSynonym' env name args =
98 replaceAllTypeSynonyms' env repl
99 replaceAllTypeSynonyms' env repl
99 Nothing -> error "Type synonym was not defined"
100 Nothing -> error "Type synonym was not defined"
100
101
101−expandTypeSynonym :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Qualified ProperName -> [Type] -> m Type
102+expandTypeSynonym :: (e ~ ErrorStack, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Qualified ProperName -> [Type] -> m Type
102expandTypeSynonym name args = do
103expandTypeSynonym name args = do
103 env <- getEnv
104 env <- getEnv
104 either (throwError . strMsg) return $ expandTypeSynonym' env name args
105 either (throwError . strMsg) return $ expandTypeSynonym' env name args
105
106
106−expandAllTypeSynonyms :: (Error e, Functor m, Applicative m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
107+expandAllTypeSynonyms :: (e ~ ErrorStack, Functor m, Applicative m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
107expandAllTypeSynonyms = everywhereOnTypesTopDownM go
108expandAllTypeSynonyms = everywhereOnTypesTopDownM go
108 where
109 where
109 go (SaturatedTypeSynonym name args) = expandTypeSynonym name args
110 go (SaturatedTypeSynonym name args) = expandTypeSynonym name args
src/Language/PureScript/TypeChecker/Types.hs+41−42
@@ -13,7 +13,7 @@
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16−{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses #-}
16+{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, OverloadedStrings #-}
17
17
18module Language.PureScript.TypeChecker.Types (
18module Language.PureScript.TypeChecker.Types (
19 typesOf
19 typesOf
@@ -38,11 +38,11 @@ module Language.PureScript.TypeChecker.Types (
38import Data.Either (lefts, rights)
38import Data.Either (lefts, rights)
39import Data.List
39import Data.List
40import Data.Maybe (fromMaybe)
40import Data.Maybe (fromMaybe)
41−import Data.Monoid
42import qualified Data.Map as M
41import qualified Data.Map as M
42+import Data.String (IsString)
43
43
44import Control.Applicative
44import Control.Applicative
45−import Control.Monad.Error
45+import Control.Monad.Except
46import Control.Monad.State
46import Control.Monad.State
47import Control.Monad.Unify
47import Control.Monad.Unify
48
48
@@ -52,6 +52,7 @@ import Language.PureScript.Errors
52import Language.PureScript.Kinds
52import Language.PureScript.Kinds
53import Language.PureScript.Names
53import Language.PureScript.Names
54import Language.PureScript.Pretty
54import Language.PureScript.Pretty
55+import Language.PureScript.Traversals
55import Language.PureScript.TypeChecker.Entailment
56import Language.PureScript.TypeChecker.Entailment
56import Language.PureScript.TypeChecker.Kinds
57import Language.PureScript.TypeChecker.Kinds
57import Language.PureScript.TypeChecker.Monad
58import Language.PureScript.TypeChecker.Monad
@@ -128,16 +129,16 @@ typeDictionaryForBindingGroup moduleName vals = do
128 return (untyped, typed, dict, untypedDict)
129 return (untyped, typed, dict, untypedDict)
129
130
130checkTypedBindingGroupElement :: ModuleName -> (Ident, (Expr, Type, Bool)) -> TypeData -> UnifyT Type Check (Ident, (Expr, Type))
131checkTypedBindingGroupElement :: ModuleName -> (Ident, (Expr, Type, Bool)) -> TypeData -> UnifyT Type Check (Ident, (Expr, Type))
131−checkTypedBindingGroupElement moduleName (ident, (val', ty, checkType)) dict = do
132+checkTypedBindingGroupElement mn (ident, (val', ty, checkType)) dict = do
132 -- Replace type wildcards
133 -- Replace type wildcards
133 ty' <- replaceTypeWildcards ty
134 ty' <- replaceTypeWildcards ty
134 -- Kind check
135 -- Kind check
135− kind <- liftCheck $ kindOf moduleName ty
136+ (kind, args) <- liftCheck $ kindOfWithScopedVars ty
136− guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
137+ checkTypeKind kind
137 -- Check the type with the new names in scope
138 -- Check the type with the new names in scope
138 ty'' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty'
139 ty'' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty'
139 val'' <- if checkType
140 val'' <- if checkType
140− then bindNames dict $ TypedValue True <$> check val' ty'' <*> pure ty''
141+ then withScopedTypeVars mn args $ bindNames dict $ TypedValue True <$> check val' ty'' <*> pure ty''
141 else return (TypedValue False val' ty'')
142 else return (TypedValue False val' ty'')
142 return (ident, (val'', ty''))
143 return (ident, (val'', ty''))
143
144
@@ -182,10 +183,8 @@ replaceTypeClassDictionaries mn =
182-- |
183-- |
183-- Check the kind of a type, failing if it is not of kind *.
184-- Check the kind of a type, failing if it is not of kind *.
184--
185--
185−checkTypeKind :: ModuleName -> Type -> UnifyT t Check ()
186+checkTypeKind :: Kind -> UnifyT t Check ()
186−checkTypeKind moduleName ty = do
187− kind <- liftCheck $ kindOf moduleName ty
188− guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
187+checkTypeKind kind = guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
189
188
190-- |
189-- |
191-- Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns
190-- Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns
@@ -208,7 +207,7 @@ instantiatePolyTypeWithUnknowns val ty = return (val, ty)
208-- Infer a type for a value, rethrowing any error to provide a more useful error message
207-- Infer a type for a value, rethrowing any error to provide a more useful error message
209--
208--
210infer :: Expr -> UnifyT Type Check Expr
209infer :: Expr -> UnifyT Type Check Expr
211−infer val = rethrow (mkErrorStack "Error inferring type of value" (Just (ExprError val)) <>) $ infer' val
210+infer val = rethrow (mkCompileError "Error inferring type of value" (Just (ExprError val)) `combineErrors`) $ infer' val
212
211
213-- |
212-- |
214-- Infer a type for a value
213-- Infer a type for a value
@@ -271,8 +270,8 @@ infer' v@(Constructor c) = do
271 env <- getEnv
270 env <- getEnv
272 case M.lookup c (dataConstructors env) of
271 case M.lookup c (dataConstructors env) of
273 Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
272 Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
274− Just (_, _, ty) -> do ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty
273+ Just (_, _, ty, _) -> do (v', ty') <- sndM (introduceSkolemScope <=< replaceAllTypeSynonyms) <=< instantiatePolyTypeWithUnknowns v $ ty
275− return $ TypedValue True v ty'
274+ return $ TypedValue True v' ty'
276infer' (Case vals binders) = do
275infer' (Case vals binders) = do
277 ts <- mapM infer vals
276 ts <- mapM infer vals
278 ret <- fresh
277 ret <- fresh
@@ -292,21 +291,23 @@ infer' (SuperClassDictionary className tys) = do
292 return $ TypeClassDictionary False (className, tys) dicts
291 return $ TypeClassDictionary False (className, tys) dicts
293infer' (TypedValue checkType val ty) = do
292infer' (TypedValue checkType val ty) = do
294 Just moduleName <- checkCurrentModule <$> get
293 Just moduleName <- checkCurrentModule <$> get
295− checkTypeKind moduleName ty
294+ (kind, args) <- liftCheck $ kindOfWithScopedVars ty
295+ checkTypeKind kind
296 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
296 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
297− val' <- if checkType then check val ty' else return val
297+ val' <- if checkType then withScopedTypeVars moduleName args (check val ty') else return val
298 return $ TypedValue True val' ty'
298 return $ TypedValue True val' ty'
299−infer' (PositionedValue pos val) = rethrowWithPosition pos $ infer' val
299+infer' (PositionedValue pos _ val) = rethrowWithPosition pos $ infer' val
300infer' _ = error "Invalid argument to infer"
300infer' _ = error "Invalid argument to infer"
301
301
302inferLetBinding :: [Declaration] -> [Declaration] -> Expr -> (Expr -> UnifyT Type Check Expr) -> UnifyT Type Check ([Declaration], Expr)
302inferLetBinding :: [Declaration] -> [Declaration] -> Expr -> (Expr -> UnifyT Type Check Expr) -> UnifyT Type Check ([Declaration], Expr)
303inferLetBinding seen [] ret j = (,) seen <$> makeBindingGroupVisible (j ret)
303inferLetBinding seen [] ret j = (,) seen <$> makeBindingGroupVisible (j ret)
304inferLetBinding seen (ValueDeclaration ident nameKind [] (Right (tv@(TypedValue checkType val ty))) : rest) ret j = do
304inferLetBinding seen (ValueDeclaration ident nameKind [] (Right (tv@(TypedValue checkType val ty))) : rest) ret j = do
305 Just moduleName <- checkCurrentModule <$> get
305 Just moduleName <- checkCurrentModule <$> get
306− checkTypeKind moduleName ty
306+ (kind, args) <- liftCheck $ kindOfWithScopedVars ty
307+ checkTypeKind kind
307 let dict = M.singleton (moduleName, ident) (ty, nameKind, Undefined)
308 let dict = M.singleton (moduleName, ident) (ty, nameKind, Undefined)
308 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
309 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
309− TypedValue _ val' ty'' <- if checkType then bindNames dict (check val ty') else return tv
310+ TypedValue _ val' ty'' <- if checkType then withScopedTypeVars moduleName args (bindNames dict (check val ty')) else return tv
310 bindNames (M.singleton (moduleName, ident) (ty'', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right (TypedValue checkType val' ty''))]) rest ret j
311 bindNames (M.singleton (moduleName, ident) (ty'', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right (TypedValue checkType val' ty''))]) rest ret j
311inferLetBinding seen (ValueDeclaration ident nameKind [] (Right val) : rest) ret j = do
312inferLetBinding seen (ValueDeclaration ident nameKind [] (Right val) : rest) ret j = do
312 valTy <- fresh
313 valTy <- fresh
@@ -322,9 +323,9 @@ inferLetBinding seen (BindingGroupDeclaration ds : rest) ret j = do
322 ds2' <- forM untyped $ \e -> typeForBindingGroupElement e dict untypedDict
323 ds2' <- forM untyped $ \e -> typeForBindingGroupElement e dict untypedDict
323 let ds' = [(ident, LocalVariable, val') | (ident, (val', _)) <- ds1' ++ ds2']
324 let ds' = [(ident, LocalVariable, val') | (ident, (val', _)) <- ds1' ++ ds2']
324 makeBindingGroupVisible $ bindNames dict $ inferLetBinding (seen ++ [BindingGroupDeclaration ds']) rest ret j
325 makeBindingGroupVisible $ bindNames dict $ inferLetBinding (seen ++ [BindingGroupDeclaration ds']) rest ret j
325−inferLetBinding seen (PositionedDeclaration pos d : ds) ret j = rethrowWithPosition pos $ do
326+inferLetBinding seen (PositionedDeclaration pos com d : ds) ret j = rethrowWithPosition pos $ do
326 (d' : ds', val') <- inferLetBinding seen (d : ds) ret j
327 (d' : ds', val') <- inferLetBinding seen (d : ds) ret j
327− return (PositionedDeclaration pos d' : ds', val')
328+ return (PositionedDeclaration pos com d' : ds', val')
328inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding"
329inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding"
329
330
330-- |
331-- |
@@ -354,7 +355,7 @@ inferBinder val (VarBinder name) = return $ M.singleton name val
354inferBinder val (ConstructorBinder ctor binders) = do
355inferBinder val (ConstructorBinder ctor binders) = do
355 env <- getEnv
356 env <- getEnv
356 case M.lookup ctor (dataConstructors env) of
357 case M.lookup ctor (dataConstructors env) of
357− Just (_, _, ty) -> do
358+ Just (_, _, ty, _) -> do
358 (_, fn) <- instantiatePolyTypeWithUnknowns (error "Data constructor types cannot contain constraints") ty
359 (_, fn) <- instantiatePolyTypeWithUnknowns (error "Data constructor types cannot contain constraints") ty
359 fn' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ fn
360 fn' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ fn
360 go binders fn'
361 go binders fn'
@@ -394,7 +395,7 @@ inferBinder val (ConsBinder headBinder tailBinder) = do
394inferBinder val (NamedBinder name binder) = do
395inferBinder val (NamedBinder name binder) = do
395 m <- inferBinder val binder
396 m <- inferBinder val binder
396 return $ M.insert name val m
397 return $ M.insert name val m
397−inferBinder val (PositionedBinder pos binder) =
398+inferBinder val (PositionedBinder pos _ binder) =
398 rethrowWithPosition pos $ inferBinder val binder
399 rethrowWithPosition pos $ inferBinder val binder
399
400
400-- |
401-- |
@@ -426,7 +427,7 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
426-- Check the type of a value, rethrowing errors to provide a better error message
427-- Check the type of a value, rethrowing errors to provide a better error message
427--
428--
428check :: Expr -> Type -> UnifyT Type Check Expr
429check :: Expr -> Type -> UnifyT Type Check Expr
429−check val ty = rethrow (mkErrorStack errorMessage (Just (ExprError val)) <>) $ check' val ty
430+check val ty = rethrow (mkCompileError errorMessage (Just (ExprError val)) `combineErrors`) $ check' val ty
430 where
431 where
431 errorMessage =
432 errorMessage =
432 "Error checking type of term " ++
433 "Error checking type of term " ++
@@ -472,7 +473,8 @@ check' (ArrayLiteral vals) t@(TypeApp a ty) = do
472 a =?= tyArray
473 a =?= tyArray
473 array <- ArrayLiteral <$> forM vals (`check` ty)
474 array <- ArrayLiteral <$> forM vals (`check` ty)
474 return $ TypedValue True array t
475 return $ TypedValue True array t
475−check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) | t == tyFunction = do
476+check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) = do
477+ t =?= tyFunction
476 Just moduleName <- checkCurrentModule <$> get
478 Just moduleName <- checkCurrentModule <$> get
477 ret' <- makeBindingGroupVisible $ bindLocalVariables moduleName [(arg, argTy, Defined)] $ check ret retTy
479 ret' <- makeBindingGroupVisible $ bindLocalVariables moduleName [(arg, argTy, Defined)] $ check ret retTy
478 return $ TypedValue True (Abs (Left arg) ret') ty
480 return $ TypedValue True (Abs (Left arg) ret') ty
@@ -505,14 +507,15 @@ check' (SuperClassDictionary className tys) _ = do
505 return $ TypeClassDictionary False (className, tys) dicts
507 return $ TypeClassDictionary False (className, tys) dicts
506check' (TypedValue checkType val ty1) ty2 = do
508check' (TypedValue checkType val ty1) ty2 = do
507 Just moduleName <- checkCurrentModule <$> get
509 Just moduleName <- checkCurrentModule <$> get
508− checkTypeKind moduleName ty1
510+ (kind, args) <- liftCheck $ kindOfWithScopedVars ty1
511+ checkTypeKind kind
509 ty1' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty1
512 ty1' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty1
510 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
513 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
511 val' <- subsumes (Just val) ty1' ty2'
514 val' <- subsumes (Just val) ty1' ty2'
512 case val' of
515 case val' of
513 Nothing -> throwError . strMsg $ "Unable to check type subsumption"
516 Nothing -> throwError . strMsg $ "Unable to check type subsumption"
514 Just val'' -> do
517 Just val'' -> do
515− val''' <- if checkType then check val'' ty2' else return val''
518+ val''' <- if checkType then withScopedTypeVars moduleName args (check val'' ty2') else return val''
516 return $ TypedValue checkType (TypedValue True val''' ty1') ty2'
519 return $ TypedValue checkType (TypedValue True val''' ty1') ty2'
517check' (Case vals binders) ret = do
520check' (Case vals binders) ret = do
518 vals' <- mapM infer vals
521 vals' <- mapM infer vals
@@ -549,7 +552,7 @@ check' (Constructor c) ty = do
549 env <- getEnv
552 env <- getEnv
550 case M.lookup c (dataConstructors env) of
553 case M.lookup c (dataConstructors env) of
551 Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
554 Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
552− Just (_, _, ty1) -> do
555+ Just (_, _, ty1, _) -> do
553 repl <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty1
556 repl <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty1
554 _ <- subsumes Nothing repl ty
557 _ <- subsumes Nothing repl ty
555 return $ TypedValue True (Constructor c) ty
558 return $ TypedValue True (Constructor c) ty
@@ -560,11 +563,11 @@ check' val ty | containsTypeSynonyms ty = do
560 ty' <- introduceSkolemScope <=< expandAllTypeSynonyms <=< replaceTypeWildcards $ ty
563 ty' <- introduceSkolemScope <=< expandAllTypeSynonyms <=< replaceTypeWildcards $ ty
561 check val ty'
564 check val ty'
562check' val kt@(KindedType ty kind) = do
565check' val kt@(KindedType ty kind) = do
563− guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
566+ checkTypeKind kind
564 val' <- check' val ty
567 val' <- check' val ty
565 return $ TypedValue True val' kt
568 return $ TypedValue True val' kt
566−check' (PositionedValue pos val) ty =
569+check' (PositionedValue pos _ val) ty =
567− rethrowWithPosition pos $ check val ty
570+ rethrowWithPosition pos $ check' val ty
568check' val ty = throwError $ mkErrorStack ("Expr does not have type " ++ prettyPrintType ty) (Just (ExprError val))
571check' val ty = throwError $ mkErrorStack ("Expr does not have type " ++ prettyPrintType ty) (Just (ExprError val))
569
572
570containsTypeSynonyms :: Type -> Bool
573containsTypeSynonyms :: Type -> Bool
@@ -580,18 +583,14 @@ containsTypeSynonyms = everythingOnTypes (||) go where
580checkProperties :: [(String, Expr)] -> Type -> Bool -> UnifyT Type Check [(String, Expr)]
583checkProperties :: [(String, Expr)] -> Type -> Bool -> UnifyT Type Check [(String, Expr)]
581checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
584checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
582 go [] [] REmpty = return []
585 go [] [] REmpty = return []
583− go [] [] u@(TUnknown _) = do u =?= REmpty
586+ go [] [] u@(TUnknown _)
587+ | lax = return []
588+ | otherwise = do u =?= REmpty
584− return []
589+ return []
585 go [] [] Skolem{} | lax = return []
590 go [] [] Skolem{} | lax = return []
586 go [] ((p, _): _) _ | lax = return []
591 go [] ((p, _): _) _ | lax = return []
587 | otherwise = throwError $ mkErrorStack ("Object does not have property " ++ p) (Just (ExprError (ObjectLiteral ps)))
592 | otherwise = throwError $ mkErrorStack ("Object does not have property " ++ p) (Just (ExprError (ObjectLiteral ps)))
588 go ((p,_):_) [] REmpty = throwError $ mkErrorStack ("Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row) (Just (ExprError (ObjectLiteral ps)))
593 go ((p,_):_) [] REmpty = throwError $ mkErrorStack ("Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row) (Just (ExprError (ObjectLiteral ps)))
589− go ((p,v):ps') [] u@(TUnknown _) = do
590− v'@(TypedValue _ _ ty) <- infer v
591− rest <- fresh
592− u =?= RCons p ty rest
593− ps'' <- go ps' [] rest
594− return $ (p, v') : ps''
595 go ((p,v):ps') ts r =
594 go ((p,v):ps') ts r =
596 case lookup p ts of
595 case lookup p ts of
597 Nothing -> do
596 Nothing -> do
@@ -610,7 +609,7 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
610-- Check the type of a function application, rethrowing errors to provide a better error message
609-- Check the type of a function application, rethrowing errors to provide a better error message
611--
610--
612checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
611checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
613−checkFunctionApplication fn fnTy arg ret = rethrow (mkErrorStack errorMessage (Just (ExprError fn)) <>) $ do
612+checkFunctionApplication fn fnTy arg ret = rethrow (mkCompileError errorMessage (Just (ExprError fn)) `combineErrors`) $ do
614 subst <- unifyCurrentSubstitution <$> UnifyT get
613 subst <- unifyCurrentSubstitution <$> UnifyT get
615 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
614 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
616 where
615 where
@@ -674,5 +673,5 @@ meet e1 e2 t1 t2 = do
674-- |
673-- |
675-- Ensure a set of property names and value does not contain duplicate labels
674-- Ensure a set of property names and value does not contain duplicate labels
676--
675--
677−ensureNoDuplicateProperties :: (Error e, MonadError e m) => [(String, Expr)] -> m ()
676+ensureNoDuplicateProperties :: (IsString e, MonadError e m) => [(String, Expr)] -> m ()
678−ensureNoDuplicateProperties ps = guardWith (strMsg "Duplicate property names") $ length (nub . map fst $ ps) == length ps
677+ensureNoDuplicateProperties ps = guardWith "Duplicate property names" $ length (nub . map fst $ ps) == length ps
src/Language/PureScript/TypeChecker/Unify.hs+24−4
@@ -27,10 +27,9 @@ module Language.PureScript.TypeChecker.Unify (
27
27
28import Data.List (nub, sort)
28import Data.List (nub, sort)
29import Data.Maybe (fromMaybe)
29import Data.Maybe (fromMaybe)
30−import Data.Monoid
31import qualified Data.HashMap.Strict as H
30import qualified Data.HashMap.Strict as H
32
31
33−import Control.Monad.Error
32+import Control.Monad.Except
34import Control.Monad.Unify
33import Control.Monad.Unify
35
34
36import Language.PureScript.Environment
35import Language.PureScript.Environment
@@ -61,7 +60,7 @@ instance Unifiable Check Type where
61-- Unify two types, updating the current substitution
60-- Unify two types, updating the current substitution
62--
61--
63unifyTypes :: Type -> Type -> UnifyT Type Check ()
62unifyTypes :: Type -> Type -> UnifyT Type Check ()
64−unifyTypes t1 t2 = rethrow (mkErrorStack ("Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2) Nothing <>) $
63+unifyTypes t1 t2 = rethrow (mkCompileError ("Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2) Nothing `combineErrors`) $
65 unifyTypes' t1 t2
64 unifyTypes' t1 t2
66 where
65 where
67 unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()
66 unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()
@@ -130,6 +129,10 @@ unifyRows r1 r2 =
130 rest <- fresh
129 rest <- fresh
131 u1 =:= rowFromList (sd2, rest)
130 u1 =:= rowFromList (sd2, rest)
132 u2 =:= rowFromList (sd1, rest)
131 u2 =:= rowFromList (sd1, rest)
132+ unifyRows' sd1 (SaturatedTypeSynonym name args) sd2 r2' = do
133+ r1' <- expandTypeSynonym name $ args
134+ unifyRows (rowFromList (sd1, r1')) (rowFromList (sd2, r2'))
135+ unifyRows' sd1 r1' sd2 r2'@(SaturatedTypeSynonym _ _) = unifyRows' sd2 r2' sd1 r1'
133 unifyRows' [] REmpty [] REmpty = return ()
136 unifyRows' [] REmpty [] REmpty = return ()
134 unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
137 unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
135 unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()
138 unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()
@@ -149,6 +152,23 @@ unifiesWith e (SaturatedTypeSynonym name args) t2 =
149 Left _ -> False
152 Left _ -> False
150 Right t1 -> unifiesWith e t1 t2
153 Right t1 -> unifiesWith e t1 t2
151unifiesWith e t1 t2@(SaturatedTypeSynonym _ _) = unifiesWith e t2 t1
154unifiesWith e t1 t2@(SaturatedTypeSynonym _ _) = unifiesWith e t2 t1
155+unifiesWith _ REmpty REmpty = True
156+unifiesWith e r1@(RCons _ _ _) r2@(RCons _ _ _) =
157+ let (s1, r1') = rowToList r1
158+ (s2, r2') = rowToList r2
159+
160+ int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
161+ sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
162+ sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
163+ in all (\(t1, t2) -> unifiesWith e t1 t2) int && go sd1 r1' sd2 r2'
164+ where
165+ go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Bool
166+ go [] REmpty [] REmpty = True
167+ go [] (TypeVar v1) [] (TypeVar v2) = v1 == v2
168+ go [] (Skolem _ s1 _) [] (Skolem _ s2 _) = s1 == s2
169+ go _ (TUnknown _) _ _ = True
170+ go _ _ _ (TUnknown _) = True
171+ go _ _ _ _ = False
152unifiesWith _ _ _ = False
172unifiesWith _ _ _ = False
153
173
154-- |
174-- |
@@ -158,7 +178,7 @@ replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type
158replaceVarWithUnknown ident ty = do
178replaceVarWithUnknown ident ty = do
159 tu <- fresh
179 tu <- fresh
160 return $ replaceTypeVars ident tu ty
180 return $ replaceTypeVars ident tu ty
161−
181+
162-- |
182-- |
163-- Replace type wildcards with unknowns
183-- Replace type wildcards with unknowns
164--
184--
tests/Main.hs+6−6
@@ -22,24 +22,24 @@ import Data.List (isSuffixOf)
22import Data.Traversable (traverse)
22import Data.Traversable (traverse)
23import Control.Monad
23import Control.Monad
24import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
24import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
25+import Control.Monad.Reader (runReaderT)
25import Control.Applicative
26import Control.Applicative
26import System.Exit
27import System.Exit
27import System.Process
28import System.Process
28import System.FilePath (pathSeparator)
29import System.FilePath (pathSeparator)
29import System.Directory (getCurrentDirectory, getTemporaryDirectory, getDirectoryContents, findExecutable)
30import System.Directory (getCurrentDirectory, getTemporaryDirectory, getDirectoryContents, findExecutable)
30import Text.Parsec (ParseError)
31import Text.Parsec (ParseError)
31−import qualified System.IO.UTF8 as U
32
32
33readInput :: [FilePath] -> IO [(FilePath, String)]
33readInput :: [FilePath] -> IO [(FilePath, String)]
34readInput inputFiles = forM inputFiles $ \inputFile -> do
34readInput inputFiles = forM inputFiles $ \inputFile -> do
35− text <- U.readFile inputFile
35+ text <- readFile inputFile
36 return (inputFile, text)
36 return (inputFile, text)
37
37
38loadPrelude :: Either String (String, String, P.Environment)
38loadPrelude :: Either String (String, String, P.Environment)
39−loadPrelude =
39+loadPrelude =
40 case P.parseModulesFromFiles id [("", P.prelude)] of
40 case P.parseModulesFromFiles id [("", P.prelude)] of
41 Left parseError -> Left (show parseError)
41 Left parseError -> Left (show parseError)
42− Right ms -> P.compile (P.defaultCompileOptions { P.optionsAdditional = P.CompileOptions "Tests" [] [] }) (map snd ms) []
42+ Right ms -> runReaderT (P.compile (map snd ms) []) $ P.defaultCompileOptions { P.optionsAdditional = P.CompileOptions "Tests" [] [] }
43
43
44compile :: P.Options P.Compile -> [FilePath] -> IO (Either String (String, String, P.Environment))
44compile :: P.Options P.Compile -> [FilePath] -> IO (Either String (String, String, P.Environment))
45compile opts inputFiles = do
45compile opts inputFiles = do
@@ -47,7 +47,7 @@ compile opts inputFiles = do
47 case modules of
47 case modules of
48 Left parseError ->
48 Left parseError ->
49 return (Left $ show parseError)
49 return (Left $ show parseError)
50− Right ms -> return $ P.compile opts (map snd ms) []
50+ Right ms -> return $ runReaderT (P.compile (map snd ms) []) opts
51
51
52assert :: FilePath -> P.Options P.Compile -> FilePath -> (Either String (String, String, P.Environment) -> IO (Maybe String)) -> IO ()
52assert :: FilePath -> P.Options P.Compile -> FilePath -> (Either String (String, String, P.Environment) -> IO (Maybe String)) -> IO ()
53assert preludeExterns opts inputFile f = do
53assert preludeExterns opts inputFile f = do
@@ -86,7 +86,7 @@ findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
86
86
87main :: IO ()
87main :: IO ()
88main = do
88main = do
89− putStrLn "Compiling Prelude"
89+ putStrLn "Compiling Prelude"
90 case loadPrelude of
90 case loadPrelude of
91 Left err -> putStrLn err >> exitFailure
91 Left err -> putStrLn err >> exitFailure
92 Right (preludeJs, exts, _) -> do
92 Right (preludeJs, exts, _) -> do