disco 0.1.4 → 0.1.5
raw patch · 9 files changed
+83/−6 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +7/−0
- disco.cabal +7/−1
- src/Disco/Parser.hs +27/−5
- test/error-parse-RHS/expected +14/−0
- test/error-parse-RHS/input +5/−0
- test/error-unbound/expected +1/−0
- test/error-unbound/input +2/−0
- test/types-306/expected +13/−0
- test/types-306/input +7/−0
CHANGELOG.md view
@@ -1,3 +1,10 @@+* 0.1.5 (12 March 2022)++ - Syntax errors in function definitions now result in much more+ helpful error messages. Before, it would just complain about+ something being wrong with the '=' sign.+ ([#346](https://github.com/disco-lang/disco/issues/346))+ * 0.1.4 (10 March 2022) - New features or syntax
disco.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: disco-version: 0.1.4+version: 0.1.5 synopsis: Functional programming language for teaching discrete math. description: Disco is a simple functional programming language for use in teaching discrete math. Its syntax is designed to be close@@ -98,6 +98,8 @@ test/error-numpatterns/expected test/error-numpatterns/input test/error-numpatterns/numpatterns.disco+ test/error-parse-RHS/expected+ test/error-parse-RHS/input test/error-pattype/expected test/error-pattype/input test/error-polyrec/expected@@ -109,6 +111,8 @@ test/error-tyargs/error-tyargs.disco test/error-tyargs/expected test/error-tyargs/input+ test/error-unbound/expected+ test/error-unbound/input test/error-unboundtyvar/expected test/error-unboundtyvar/input test/error-unboundtyvar/unboundtyvar.disco@@ -309,6 +313,8 @@ test/syntax-types/input test/types-192/expected test/types-192/input+ test/types-306/expected+ test/types-306/input test/types-bind/expected test/types-bind/input test/types-char-string/expected
src/Disco/Parser.hs view
@@ -461,9 +461,26 @@ parseTopLevel :: Parser TopLevel parseTopLevel = L.nonIndented sc $ TLDoc <$> parseDocThing- <|> TLDecl <$> try parseDecl+ <|> TLDecl <$> parseDecl -- See Note [Parsing definitions and top-level expressions] <|> TLExpr <$> thenIndented parseTerm + -- ~~~~ Note [Parsing definitions and top-level expressions]+ --+ -- The beginning of a definition might look the same as an+ -- expression. e.g. is f(x,y) the start of a definition of f, or an+ -- expression with a function call? We used to therefore wrap+ -- 'parseDecl' in 'try'. The problem is that if a definition has a+ -- syntax error on the RHS, it would fail, backtrack, then try+ -- parsing a top-level expression and fail when it got to the =+ -- sign, giving an uninformative parse error message.+ -- See https://github.com/disco-lang/disco/issues/346.+ --+ -- The solution is that we now do more careful backtracking within+ -- parseDecl itself: when parsing a definition, we only backtrack if+ -- we don't get a complete LHS + '=' sign; once we start parsing the+ -- RHS of a definition we no longer backtrack, since it can't+ -- possibly be a valid top-level expression.+ -- | Parse a documentation item: either a group of lines beginning -- with @|||@ (text documentation), or a group beginning with @!!!@ -- (checked examples/properties).@@ -507,10 +524,15 @@ -- | Parse a definition of the form @x pat1 .. patn = t@. parseDefn :: Parser TermDefn parseDefn = label "definition" $- TermDefn- <$> ident- <*> indented ((:[]) <$> (bind <$> many parseAtomicPattern <*> (symbol "=" *> parseTerm)))+ (\(x, ps) body -> TermDefn x [bind ps body]) + -- Only backtrack if we don't get a complete 'LHS ='. Once we see+ -- an = sign, commit to parsing a definition, because it can't be a+ -- valid standalone expression anymore. If the RHS fails, we don't+ -- want to backtrack, we just want to display the parse error.+ <$> try ((,) <$> ident <*> indented (many parseAtomicPattern) <* reservedOp "=")+ <*> indented parseTerm+ -- | Parse the definition of a user-defined algebraic data type. parseTyDefn :: Parser TypeDefn parseTyDefn = label "type defintion" $ do@@ -518,7 +540,7 @@ indented $ do name <- parseTyDef args <- fromMaybe [] <$> optional (parens $ parseTyVarName `sepBy1` comma)- _ <- symbol "="+ _ <- reservedOp "=" TypeDefn name args <$> parseType -- | Parse the entire input as a term (with leading whitespace and
+ test/error-parse-RHS/expected view
@@ -0,0 +1,14 @@+1:11:+ |+1 | f(x) = x ++ | ^+unexpected end of input+expecting expression or operator++1:18:+ |+1 | g(x) = {? 5 if x =< 5, 6 otherwise ?}+ | ^^+unexpected "=<"+expecting "?}", "if", "let", "when", ',', expression, operator, or type annotation+
+ test/error-parse-RHS/input view
@@ -0,0 +1,5 @@+f : N -> N+f(x) = x +++g : N -> N+g(x) = {? 5 if x =< 5, 6 otherwise ?}
+ test/error-unbound/expected view
@@ -0,0 +1,1 @@+Error: encountered undefined name REPL.even. Maybe you haven't defined it yet?
+ test/error-unbound/input view
@@ -0,0 +1,2 @@+even : Z -> Bool+even(2)
+ test/types-306/expected view
@@ -0,0 +1,13 @@+Error: the shape of two types does not match.+https://disco-lang.readthedocs.io/en/latest/reference/shape-mismatch.html+Error: the shape of two types does not match.+https://disco-lang.readthedocs.io/en/latest/reference/shape-mismatch.html+Error: values of type Bool → Bool cannot be compared.+https://disco-lang.readthedocs.io/en/latest/reference/not-qual.html+Error: values of type a5 → a6 cannot be compared.+https://disco-lang.readthedocs.io/en/latest/reference/not-qual.html+Error: the shape of two types does not match.+https://disco-lang.readthedocs.io/en/latest/reference/shape-mismatch.html+Error: the shape of two types does not match.+https://disco-lang.readthedocs.io/en/latest/reference/shape-mismatch.html+{}
+ test/types-306/input view
@@ -0,0 +1,7 @@+set [\x.x : Bool -> Bool, \x. not x]+{\x.x : Bool -> Bool, \x. not x}+{\x.x, \x. not x} : Set (Bool -> Bool)+{\x.x, \x. not x}+bag [\x.x : Bool -> Bool, \x. not x]+[\x.x : Bool -> Bool, \x. not x]+{} : Set (Bool -> Bool)