Permalink
Browse files

Disallow `(` and `)` characters in path

The original reason for permitting `(` and `)` in paths was due to
Dhall's origins as a fork of Morte/Annah.  Morte had no built-in
operators and often imported them via the Prelude, like this:

    http://sigil.place/prelude/annah/1.0/List/(++)

Morte also adopted the Haskell convention of using parentheses for
unapplied operators, so paths required parentheses.

However, this came at a price, which was really confusing parsing errors
if the user did something like this:

    λ(x : ./type) → x

This is because the `./type)` would be parsed as a single path token and
then you'd get a downstream error due to a missing parenthesis.

Dhall, on the other hand, does not benefit much from parentheses in
paths.  Dhall already has several built-in operators and doesn't support
operator names for bound variables.  Therefore, this change eliminates
support for parentheses in paths to improve error messages and reduce
the need for explicit whitespace after paths.
  • Loading branch information...
Gabriel439 committed Apr 16, 2017
1 parent 649acf3 commit dc1773f1af3949bf5cbf130d6de0ea666e56a727
Showing with 10 additions and 7 deletions.
  1. +10 −7 src/Dhall/Parser.hs
View
@@ -738,6 +738,9 @@ import_ = do
pathMode <- rawText <|> pure Code
return (Path {..})
pathChar :: Char -> Bool
pathChar c = not (Data.Char.isSpace c || c == '(' || c == ')')
file :: Parser PathType
file = try (token file0)
<|> token file1
@@ -746,7 +749,7 @@ file = try (token file0)
where
file0 = do
a <- Text.Parser.Char.string "/"
b <- many (Text.Parser.Char.satisfy (not . Data.Char.isSpace))
b <- many (Text.Parser.Char.satisfy pathChar)
case b of
'\\':_ -> empty -- So that "/\" parses as the operator and not a path
'/' :_ -> empty -- So that "//" parses as the operator and not a path
@@ -755,18 +758,18 @@ file = try (token file0)
file1 = do
a <- Text.Parser.Char.string "./"
b <- many (Text.Parser.Char.satisfy (not . Data.Char.isSpace))
b <- many (Text.Parser.Char.satisfy pathChar)
return (File Homeless (Filesystem.Path.CurrentOS.decodeString (a <> b)))
file2 = do
a <- Text.Parser.Char.string "../"
b <- many (Text.Parser.Char.satisfy (not . Data.Char.isSpace))
b <- many (Text.Parser.Char.satisfy pathChar)
return (File Homeless (Filesystem.Path.CurrentOS.decodeString (a <> b)))
file3 = do
_ <- Text.Parser.Char.string "~"
_ <- some (Text.Parser.Char.string "/")
b <- many (Text.Parser.Char.satisfy (not . Data.Char.isSpace))
b <- many (Text.Parser.Char.satisfy pathChar)
return (File Home (Filesystem.Path.CurrentOS.decodeString b))
url :: Parser PathType
@@ -775,18 +778,18 @@ url = try url0
where
url0 = do
a <- Text.Parser.Char.string "https://"
b <- many (Text.Parser.Char.satisfy (not . Data.Char.isSpace))
b <- many (Text.Parser.Char.satisfy pathChar)
return (URL (Data.Text.Lazy.pack (a <> b)))
url1 = do
a <- Text.Parser.Char.string "http://"
b <- many (Text.Parser.Char.satisfy (not . Data.Char.isSpace))
b <- many (Text.Parser.Char.satisfy pathChar)
return (URL (Data.Text.Lazy.pack (a <> b)))
env :: Parser PathType
env = do
_ <- Text.Parser.Char.string "env:"
a <- many (Text.Parser.Char.satisfy (not . Data.Char.isSpace))
a <- many (Text.Parser.Char.satisfy pathChar)
return (Env (Data.Text.Lazy.pack a))
-- | A parsing error

0 comments on commit dc1773f

Please sign in to comment.