on master help sign in
Mess with colors / add `let` messages / add pattern messages
63ce4a0Evan Czaplicki
compiler/src/Parse/Pattern.hs+18−15
@@ -68,7 +68,10 @@ termHelp start =
68
68
69 Number.Float float ->
69 Number.Float float ->
70 P.Parser $ \(P.State _ _ _ row col) _ _ cerr _ ->
70 P.Parser $ \(P.State _ _ _ row col) _ _ cerr _ ->
71+ let
72+ width = fromIntegral (Utf8.size float)
73+ in
71− cerr row col (E.PFloat (Utf8.size float))
74+ cerr row (col - width) (E.PFloat width)
72 ,
75 ,
73 do str <- Utf8.string E.PStart E.PString
76 do str <- Utf8.string E.PStart E.PString
74 addEnd start (Src.PStr str)
77 addEnd start (Src.PStr str)
@@ -93,8 +96,8 @@ wildcard =
93 !newCol = col + 1
96 !newCol = col + 1
94 in
97 in
95 if Var.getInnerWidth newPos end > 0 then
98 if Var.getInnerWidth newPos end > 0 then
96− let (# _, badCol #) = Var.chompInnerChars newPos end newCol in
99+ let (# badPos, badCol #) = Var.chompInnerChars newPos end newCol in
97− cerr row col (E.PWildcardNotVar (fromIntegral (badCol - col)))
100+ cerr row col (E.PWildcardNotVar (Name.fromPtr pos badPos) (fromIntegral (badCol - col)))
98 else
101 else
99 let !newState = P.State newPos end indent row newCol in
102 let !newState = P.State newPos end indent row newCol in
100 cok () newState
103 cok () newState
@@ -137,7 +140,7 @@ recordHelp start vars =
137tuple :: A.Position -> Parser E.Pattern Src.Pattern
140tuple :: A.Position -> Parser E.Pattern Src.Pattern
138tuple start =
141tuple start =
139 inContext E.PTuple (word1 0x28 {-(-} E.PStart) $
142 inContext E.PTuple (word1 0x28 {-(-} E.PStart) $
140− do Space.chompAndCheckIndent E.PTupleSpace E.PTupleIndentOpen
143+ do Space.chompAndCheckIndent E.PTupleSpace E.PTupleIndentExpr1
141 oneOf E.PTupleOpen
144 oneOf E.PTupleOpen
142 [ do (pattern, end) <- P.specialize E.PTupleExpr expression
145 [ do (pattern, end) <- P.specialize E.PTupleExpr expression
143 Space.checkIndent end E.PTupleIndentEnd
146 Space.checkIndent end E.PTupleIndentEnd
@@ -151,7 +154,7 @@ tupleHelp :: A.Position -> Src.Pattern -> [Src.Pattern] -> Parser E.PTuple Src.P
151tupleHelp start firstPattern revPatterns =
154tupleHelp start firstPattern revPatterns =
152 oneOf E.PTupleEnd
155 oneOf E.PTupleEnd
153 [ do word1 0x2C {-,-} E.PTupleEnd
156 [ do word1 0x2C {-,-} E.PTupleEnd
154− Space.chompAndCheckIndent E.PTupleSpace E.PTupleIndentExpr
157+ Space.chompAndCheckIndent E.PTupleSpace E.PTupleIndentExprN
155 (pattern, end) <- P.specialize E.PTupleExpr expression
158 (pattern, end) <- P.specialize E.PTupleExpr expression
156 Space.checkIndent end E.PTupleIndentEnd
159 Space.checkIndent end E.PTupleIndentEnd
157 tupleHelp start firstPattern (pattern : revPatterns)
160 tupleHelp start firstPattern (pattern : revPatterns)
@@ -202,18 +205,18 @@ listHelp start patterns =
202expression :: Space.Parser E.Pattern Src.Pattern
205expression :: Space.Parser E.Pattern Src.Pattern
203expression =
206expression =
204 do start <- getPosition
207 do start <- getPosition
205− cTerm <- exprTerm
208+ ePart <- exprPart
206− exprHelp start [] cTerm
209+ exprHelp start [] ePart
207
210
208
211
209exprHelp :: A.Position -> [Src.Pattern] -> (Src.Pattern, A.Position) -> Space.Parser E.Pattern Src.Pattern
212exprHelp :: A.Position -> [Src.Pattern] -> (Src.Pattern, A.Position) -> Space.Parser E.Pattern Src.Pattern
210−exprHelp start patterns (pattern, end) =
213+exprHelp start revPatterns (pattern, end) =
211 oneOfWithFallback
214 oneOfWithFallback
212 [ do Space.checkIndent end E.PIndentStart
215 [ do Space.checkIndent end E.PIndentStart
213 word2 0x3A 0x3A {-::-} E.PStart
216 word2 0x3A 0x3A {-::-} E.PStart
214 Space.chompAndCheckIndent E.PSpace E.PIndentStart
217 Space.chompAndCheckIndent E.PSpace E.PIndentStart
215− cTerm <- exprTerm
218+ ePart <- exprPart
216− exprHelp start (pattern:patterns) cTerm
219+ exprHelp start (pattern:revPatterns) ePart
217 , do Space.checkIndent end E.PIndentStart
220 , do Space.checkIndent end E.PIndentStart
218 Keyword.as_ E.PStart
221 Keyword.as_ E.PStart
219 Space.chompAndCheckIndent E.PSpace E.PIndentAlias
222 Space.chompAndCheckIndent E.PSpace E.PIndentAlias
@@ -223,11 +226,11 @@ exprHelp start patterns (pattern, end) =
223 Space.chomp E.PSpace
226 Space.chomp E.PSpace
224 let alias = A.at nameStart newEnd name
227 let alias = A.at nameStart newEnd name
225 return
228 return
226− ( A.at start newEnd (Src.PAlias (List.foldl' cons pattern patterns) alias)
229+ ( A.at start newEnd (Src.PAlias (List.foldl' cons pattern revPatterns) alias)
227 , newEnd
230 , newEnd
228 )
231 )
229 ]
232 ]
230− ( List.foldl' cons pattern patterns
233+ ( List.foldl' cons pattern revPatterns
231 , end
234 , end
232 )
235 )
233
236
@@ -238,11 +241,11 @@ cons tl hd =
238
241
239
242
240
243
241−-- EXPRESSION TERM
244+-- EXPRESSION PART
242
245
243
246
244−exprTerm :: Space.Parser E.Pattern Src.Pattern
247+exprPart :: Space.Parser E.Pattern Src.Pattern
245−exprTerm =
248+exprPart =
246 oneOf E.PStart
249 oneOf E.PStart
247 [
250 [
248 do start <- getPosition
251 do start <- getPosition
compiler/src/Reporting/Error/Syntax.hs+612−71
@@ -368,9 +368,9 @@ data Pattern
368 | PChar Char Row Col
368 | PChar Char Row Col
369 | PString String Row Col
369 | PString String Row Col
370 | PNumber Number Row Col
370 | PNumber Number Row Col
371− | PFloat Int Row Col
371+ | PFloat Word16 Row Col
372 | PAlias Row Col
372 | PAlias Row Col
373− | PWildcardNotVar Int Row Col
373+ | PWildcardNotVar Name.Name Int Row Col
374 | PSpace Space Row Col
374 | PSpace Space Row Col
375 --
375 --
376 | PIndentStart Row Col
376 | PIndentStart Row Col
@@ -394,9 +394,9 @@ data PTuple
394 | PTupleExpr Pattern Row Col
394 | PTupleExpr Pattern Row Col
395 | PTupleSpace Space Row Col
395 | PTupleSpace Space Row Col
396 --
396 --
397− | PTupleIndentOpen Row Col
398 | PTupleIndentEnd Row Col
397 | PTupleIndentEnd Row Col
399− | PTupleIndentExpr Row Col
398+ | PTupleIndentExpr1 Row Col
399+ | PTupleIndentExprN Row Col
400
400
401
401
402data PList
402data PList
@@ -508,8 +508,8 @@ toReport source err =
508 D.stack
508 D.stack
509 [ D.reflow $
509 [ D.reflow $
510 "I need the module name to be declared at the top of this file, like this:"
510 "I need the module name to be declared at the top of this file, like this:"
511− , D.indent 4 $ D.green $ D.fromChars $
511+ , D.indent 4 $ D.fillSep $
512− "module " ++ ModuleName.toChars name ++ " exposing (..)"
512+ [ D.cyan "module", D.fromName name, D.cyan "exposing", "(..)" ]
513 , D.reflow $
513 , D.reflow $
514 "Try adding that as the first line of your file!"
514 "Try adding that as the first line of your file!"
515 , D.toSimpleNote $
515 , D.toSimpleNote $
@@ -550,7 +550,7 @@ toReport source err =
550 ,
550 ,
551 D.stack
551 D.stack
552 [ D.fillSep
552 [ D.fillSep
553− ["Switch","this","to","say",D.green "port module","instead,"
553+ ["Switch","this","to","say",D.cyan "port module","instead,"
554 ,"marking","that","this","module","contains","port","declarations."
554 ,"marking","that","this","module","contains","port","declarations."
555 ]
555 ]
556 , D.link "Note"
556 , D.link "Note"
@@ -568,7 +568,7 @@ toReport source err =
568 "This module does not declare any ports, but it says it will:"
568 "This module does not declare any ports, but it says it will:"
569 ,
569 ,
570 D.fillSep
570 D.fillSep
571− ["Switch","this","to",D.green "module"
571+ ["Switch","this","to",D.cyan "module"
572 ,"and","you","should","be","all","set!"
572 ,"and","you","should","be","all","set!"
573 ]
573 ]
574 )
574 )
@@ -989,13 +989,77 @@ toDeclDefReport source name declDef startRow startCol =
989 toSpaceReport source space row col
989 toSpaceReport source space row col
990
990
991 DeclDefEquals row col ->
991 DeclDefEquals row col ->
992− error "TODO DeclDefEquals" row col
992+ case Code.whatIsNext source row col of
993+ Code.Keyword keyword ->
994+ let
995+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
996+ region = toWiderRegion row col (fromIntegral (length keyword))
997+ in
998+ Report.Report "RESERVED WORD" region [] $
999+ Code.toSnippet source surroundings (Just region)
1000+ (
1001+ D.reflow $
1002+ "It looks like you are trying to use `" ++ keyword ++ "` as an argument:"
1003+ ,
1004+ D.reflow $
1005+ "This is a reserved word! Try using some other name?"
1006+ )
1007+
1008+ Code.Operator op ->
1009+ let
1010+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1011+ region = toWiderRegion row col (fromIntegral (length op))
1012+ in
1013+ Report.Report "UNEXPECTED SYMBOL" region [] $
1014+ Code.toSnippet source surroundings (Just region)
1015+ (
1016+ D.reflow $
1017+ "I was not expecting to see this symbol here:"
1018+ ,
1019+ D.stack
1020+ [ D.reflow $
1021+ "I am not sure what is going wrong exactly, so here is a valid\
1022+ \ definition (with an optional type annotation) for reference:"
1023+ , D.vcat
1024+ [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1025+ , D.fillSep [D.green "add","x","y","="]
1026+ , D.fillSep [" ","x","+","y"]
1027+ ]
1028+ , D.reflow $
1029+ "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
1030+ ]
1031+ )
1032+
1033+ _ ->
1034+ let
1035+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1036+ region = toRegion row col
1037+ in
1038+ Report.Report "PROBLEM IN DEFINITION" region [] $
1039+ Code.toSnippet source surroundings (Just region)
1040+ (
1041+ D.reflow $
1042+ "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
1043+ ,
1044+ D.stack
1045+ [ D.reflow $
1046+ "I am not sure what is going wrong exactly, so here is a valid\
1047+ \ definition (with an optional type annotation) for reference:"
1048+ , D.vcat
1049+ [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1050+ , D.fillSep [D.green "add","x","y","="]
1051+ , D.fillSep [" ","x","+","y"]
1052+ ]
1053+ , D.reflow $
1054+ "Try to use that format!"
1055+ ]
1056+ )
993
1057
994 DeclDefType tipe row col ->
1058 DeclDefType tipe row col ->
995− error "TODO DeclDefType" tipe row col
1059+ error "TODO DeclDefType" toTypeReport tipe row col
996
1060
997 DeclDefArg pattern row col ->
1061 DeclDefArg pattern row col ->
998− error "TODO DeclDefArg" pattern row col
1062+ toPatternReport source PArg pattern row col
999
1063
1000 DeclDefBody expr row col ->
1064 DeclDefBody expr row col ->
1001 toExprReport source (InDef name startRow startCol) expr row col
1065 toExprReport source (InDef name startRow startCol) expr row col
@@ -1092,8 +1156,8 @@ isWithin desiredNode context =
1092toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
1156toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
1093toExprReport source context expr startRow startCol =
1157toExprReport source context expr startRow startCol =
1094 case expr of
1158 case expr of
1095− Let _ _ _ ->
1159+ Let let_ row col ->
1096− error "TODO Let"
1160+ toLetReport source context let_ row col
1097
1161
1098 Case case_ row col ->
1162 Case case_ row col ->
1099 toCaseReport source context case_ row col
1163 toCaseReport source context case_ row col
@@ -1692,6 +1756,145 @@ toOperatorReport source context operator row col =
1692
1756
1693
1757
1694
1758
1759+-- CASE
1760+
1761+
1762+toLetReport :: Code.Source -> Context -> Let -> Row -> Col -> Report.Report
1763+toLetReport source context let_ startRow startCol =
1764+ case let_ of
1765+ LetSpace space row col ->
1766+ toSpaceReport source space row col
1767+
1768+ LetIn row col ->
1769+ let
1770+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1771+ region = toRegion row col
1772+ in
1773+ Report.Report "LET PROBLEM" region [] $
1774+ Code.toSnippet source surroundings (Just region)
1775+ (
1776+ D.reflow $
1777+ "I was partway through parsing a `let` expression, but I got stuck here:"
1778+ ,
1779+ D.stack
1780+ [ D.fillSep $
1781+ ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
1782+ ,"keyword","next.","Is","there","a","typo?"
1783+ ]
1784+ , D.toSimpleNote $
1785+ "This can also happen if you are trying to define another value within the `let` but\
1786+ \ it is not indented enough. Make sure each definition has exactly the same amount of\
1787+ \ spaces before it. They should line up exactly!"
1788+ ]
1789+ )
1790+
1791+ LetDefAlignment _ row col ->
1792+ let
1793+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1794+ region = toRegion row col
1795+ in
1796+ Report.Report "LET PROBLEM" region [] $
1797+ Code.toSnippet source surroundings (Just region)
1798+ (
1799+ D.reflow $
1800+ "I was partway through parsing a `let` expression, but I got stuck here:"
1801+ ,
1802+ D.stack
1803+ [ D.fillSep $
1804+ ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
1805+ ,"keyword","next.","Is","there","a","typo?"
1806+ ]
1807+ , D.toSimpleNote $
1808+ "This can also happen if you are trying to define another value within the `let` but\
1809+ \ it is not indented enough. Make sure each definition has exactly the same amount of\
1810+ \ spaces before it. The should line up exactly!"
1811+ ]
1812+ )
1813+
1814+ LetDefName row col ->
1815+ case Code.whatIsNext source row col of
1816+ Code.Keyword keyword ->
1817+ let
1818+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1819+ region = toWiderRegion row col (fromIntegral (length keyword))
1820+ in
1821+ Report.Report "RESERVED WORD" region [] $
1822+ Code.toSnippet source surroundings (Just region)
1823+ (
1824+ D.reflow $
1825+ "I was partway through parsing a `let` expression, but I got stuck here:"
1826+ ,
1827+ D.reflow $
1828+ "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but\
1829+ \ it is a reserved word! Try using a different name instead."
1830+ )
1831+
1832+ _ ->
1833+ toUnfinishLetReport source row col startRow startCol $
1834+ D.reflow $
1835+ "I was expecting the name of a definition next."
1836+
1837+ LetDef name def row col ->
1838+ error "TODO LetDef" name def row col
1839+
1840+ LetDestruct destruct row col ->
1841+ error "TODO LetDestruct" destruct row col
1842+
1843+ LetBody expr row col ->
1844+ toExprReport source context expr row col
1845+
1846+ LetIndentDef row col ->
1847+ toUnfinishLetReport source row col startRow startCol $
1848+ D.reflow $
1849+ "I was expecting a value to be defined here."
1850+
1851+ LetIndentIn row col ->
1852+ toUnfinishLetReport source row col startRow startCol $
1853+ D.fillSep $
1854+ ["I","was","expecting","to","see","the",D.cyan "in","keyword","next."
1855+ ,"Or","maybe","more","of","that","expression?"
1856+ ]
1857+
1858+ LetIndentBody row col ->
1859+ toUnfinishLetReport source row col startRow startCol $
1860+ D.reflow $
1861+ "I was expecting an expression next. Tell me what should happen with the value you just defined!"
1862+
1863+
1864+toUnfinishLetReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
1865+toUnfinishLetReport source row col startRow startCol message =
1866+ let
1867+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1868+ region = toRegion row col
1869+ in
1870+ Report.Report "UNFINISHED LET" region [] $
1871+ Code.toSnippet source surroundings (Just region)
1872+ (
1873+ D.reflow $
1874+ "I was partway through parsing a `let` expression, but I got stuck here:"
1875+ ,
1876+ D.stack
1877+ [ message
1878+ , D.toSimpleNote $
1879+ "Here is an example with a valid `let` expression for reference:"
1880+ , D.vcat $
1881+ [ D.indent 0 $ D.fillSep [D.green "viewPerson","person","="]
1882+ , D.indent 2 $ D.fillSep [D.cyan "let"]
1883+ , D.indent 4 $ D.fillSep ["fullName","="]
1884+ , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
1885+ , D.indent 2 $ D.fillSep [D.cyan "in"]
1886+ , D.indent 2 $ D.fillSep ["div","[]","[","text","fullName","]"]
1887+ ]
1888+ , D.reflow $
1889+ "Here we defined a `viewPerson` function that turns a person into some HTML. We use\
1890+ \ a `let` expression to define the `fullName` we want to show. Notice the indentation! The\
1891+ \ `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is\
1892+ \ indented a bit more than that. That is important!"
1893+ ]
1894+ )
1895+
1896+
1897+
1695-- CASE
1898-- CASE
1696
1899
1697
1900
@@ -1706,7 +1909,7 @@ toCaseReport source context case_ startRow startCol =
1706 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
1909 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
1707
1910
1708 CasePattern pattern row col ->
1911 CasePattern pattern row col ->
1709− error "TODO CasePattern" pattern row col
1912+ toPatternReport source PCase pattern row col
1710
1913
1711 CaseArrow row col ->
1914 CaseArrow row col ->
1712 let
1915 let
@@ -1819,10 +2022,10 @@ toUnfinishCaseReport source row col startRow startCol message =
1819 , D.vcat $
2022 , D.vcat $
1820 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
2023 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1821 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
2024 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
1822− , D.indent 8 $ D.fillSep ["width","+",D.yellow "200"]
2025+ , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
1823 , ""
2026 , ""
1824 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
2027 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
1825− , D.indent 8 $ D.fillSep [D.yellow "400"]
2028+ , D.indent 8 $ D.fillSep [D.dullyellow "400"]
1826 ]
2029 ]
1827 , D.reflow $
2030 , D.reflow $
1828 "Notice the indentation. Each pattern is aligned, and each branch is indented\
2031 "Notice the indentation. Each pattern is aligned, and each branch is indented\
@@ -1842,10 +2045,10 @@ addNoteForCaseIndentError message =
1842 , D.vcat $
2045 , D.vcat $
1843 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
2046 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1844 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
2047 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
1845− , D.indent 8 $ D.fillSep ["width","+",D.yellow "200"]
2048+ , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
1846 , ""
2049 , ""
1847 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
2050 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
1848− , D.indent 8 $ D.fillSep [D.yellow "400"]
2051+ , D.indent 8 $ D.fillSep [D.dullyellow "400"]
1849 ]
2052 ]
1850 , D.reflow $
2053 , D.reflow $
1851 "Notice the indentation! Each pattern is aligned, and each branch is indented\
2054 "Notice the indentation! Each pattern is aligned, and each branch is indented\
@@ -1875,7 +2078,7 @@ toIfReport source context if_ startRow startCol =
1875 "I was expecting to see more of this `if` expression, but I got stuck here:"
2078 "I was expecting to see more of this `if` expression, but I got stuck here:"
1876 ,
2079 ,
1877 D.fillSep $
2080 D.fillSep $
1878− ["I","was","expecting","to","see","the",D.green "then","keyword","next."
2081+ ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
1879 ]
2082 ]
1880 )
2083 )
1881
2084
@@ -1891,7 +2094,7 @@ toIfReport source context if_ startRow startCol =
1891 "I was expecting to see more of this `if` expression, but I got stuck here:"
2094 "I was expecting to see more of this `if` expression, but I got stuck here:"
1892 ,
2095 ,
1893 D.fillSep $
2096 D.fillSep $
1894− ["I","was","expecting","to","see","the",D.green "else","keyword","next."
2097+ ["I","was","expecting","to","see","the",D.cyan "else","keyword","next."
1895 ]
2098 ]
1896 )
2099 )
1897
2100
@@ -1953,7 +2156,7 @@ toIfReport source context if_ startRow startCol =
1953 ,
2156 ,
1954 D.stack
2157 D.stack
1955 [ D.fillSep $
2158 [ D.fillSep $
1956− ["I","was","expecting","to","see","the",D.green "then","keyword","next."
2159+ ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
1957 ]
2160 ]
1958 , D.toSimpleNote $
2161 , D.toSimpleNote $
1959 "I can be confused by indentation. Maybe something is not indented enough?"
2162 "I can be confused by indentation. Maybe something is not indented enough?"
@@ -2015,7 +2218,7 @@ toIfReport source context if_ startRow startCol =
2015 [ D.reflow $
2218 [ D.reflow $
2016 "I know what to do when the condition is `True`, but not when it is `False`."
2219 "I know what to do when the condition is `True`, but not when it is `False`."
2017 , D.fillSep
2220 , D.fillSep
2018− ["Add","an",D.green "else","branch","to","handle","that","scenario!"]
2221+ ["Add","an",D.cyan "else","branch","to","handle","that","scenario!"]
2019 ]
2222 ]
2020 )
2223 )
2021
2224
@@ -2594,7 +2797,7 @@ toFuncReport source context func startRow startCol =
2594 toSpaceReport source space row col
2797 toSpaceReport source space row col
2595
2798
2596 FuncArg pattern row col ->
2799 FuncArg pattern row col ->
2597− error "TODO FuncArg" pattern row col
2800+ toPatternReport source PArg pattern row col
2598
2801
2599 FuncBody expr row col ->
2802 FuncBody expr row col ->
2600 toExprReport source (InNode NFunc startRow startCol context) expr row col
2803 toExprReport source (InNode NFunc startRow startCol context) expr row col
@@ -2706,80 +2909,418 @@ toFuncReport source context func startRow startCol =
2706
2909
2707
2910
2708
2911
2912+-- PATTERN
2709
2913
2710−{-
2914+
2915+data PContext
2916+ = PCase
2917+ | PArg
2918+
2919+
2920+toPatternReport :: Code.Source -> PContext -> Pattern -> Row -> Col -> Report.Report
2921+toPatternReport source context pattern startRow startCol =
2711− case err of
2922+ case pattern of
2712− CommentOnNothing region ->
2923+ PRecord record row col ->
2924+ toPRecordReport source record row col
2925+
2926+ PTuple tuple row col ->
2927+ toPTupleReport source context tuple row col
2928+
2929+ PList list row col ->
2930+ toPListReport source context list row col
2931+
2932+ PStart row col ->
2933+ case Code.whatIsNext source row col of
2934+ Code.Keyword keyword ->
2935+ let
2936+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2937+ region = toWiderRegion row col (fromIntegral (length keyword))
2938+ aThing =
2939+ case context of
2940+ PArg -> "an argument"
2941+ PCase -> "a pattern"
2942+ in
2943+ Report.Report "RESERVED WORD" region [] $
2944+ Code.toSnippet source surroundings (Just region)
2945+ (
2946+ D.reflow $
2947+ "It looks like you are trying to use `" ++ keyword ++ "` as " ++ aThing ++ ":"
2948+ ,
2949+ D.reflow $
2950+ "This is a reserved word! Try using some other name?"
2951+ )
2952+
2953+ _ ->
2954+ error "TODO PStart"
2955+
2956+ PChar char row col ->
2957+ toCharReport source char row col
2958+
2959+ PString string row col ->
2960+ toStringReport source string row col
2961+
2962+ PNumber number row col ->
2963+ toNumberReport source number row col
2964+
2965+ PFloat width row col ->
2966+ let
2967+ region = toWiderRegion row col width
2968+ in
2713− Report.Report "STRAY COMMENT" region [] $
2969+ Report.Report "UNEXPECTED PATTERN" region [] $
2714 Code.toSnippet source region Nothing
2970 Code.toSnippet source region Nothing
2715 (
2971 (
2716− "This documentation comment is not followed by anything."
2717− ,
2718 D.reflow $
2972 D.reflow $
2719− "All documentation comments need to be right above the declaration they\
2973+ "I cannot pattern match with floating point numbers:"
2720− \ describe. Maybe some code got deleted or commented out by accident? Or\
2974+ ,
2721− \ maybe this comment is here by accident?"
2975+ D.fillSep $
2976+ ["Equality","on","floats","can","be","unreliable,","so","you","usually","want"
2977+ ,"to","check","that","they","are","nearby","with","some","sort","of"
2978+ ,D.dullyellow "(abs (actual - expected) < 0.001)","check."
2979+ ]
2722 )
2980 )
2723
2981
2724− ParseError row col context expectation ->
2982+ PAlias row col ->
2983+ error "TODO PAlias" row col
2984+
2985+ PWildcardNotVar name width row col ->
2725 let
2986 let
2726− pos = A.Position row col
2987+ region = toWiderRegion row col (fromIntegral width)
2727− region = A.Region pos pos
2988+ examples =
2989+ case dropWhile (=='_') (Name.toChars name) of
2990+ [] -> [D.dullyellow "x","or",D.dullyellow "age"]
2991+ c:cs -> [D.dullyellow (D.fromChars (Char.toLower c : cs))]
2728 in
2992 in
2729− case expectation of
2993+ Report.Report "UNEXPECTED NAME" region [] $
2994+ Code.toSnippet source region Nothing $
2995+ (
2996+ D.reflow $
2997+ "Variable names cannot start with underscores like this:"
2998+ ,
2999+ D.fillSep $
3000+ ["You","can","either","have","an","underscore","like",D.dullyellow "_","to"
3001+ ,"ignore","the","value,","or","you","can","have","a","name","like"
3002+ ] ++ examples ++ ["to","use","the","matched","value." ]
3003+ )
2730
3004
2731− DocComment ->
3005+ PSpace space row col ->
2732− Report.Report "EXPECTING DOC COMMENT" region [] $
3006+ toSpaceReport source space row col
2733− Code.toSnippet source region Nothing
2734− (
2735− D.reflow $
2736− "I was expecting a doc comment here:"
2737− ,
2738− D.reflowLink
2739− "Check out" "TODO" "for examples of doc comments."
2740− )
2741
3007
2742− -- Parse.Number
3008+ PIndentStart row col ->
3009+ error "TODO PIndentStart" row col
2743
3010
2744− Wildcard ->
3011+ PIndentAlias row col ->
2745− Report.Report "EXPECTING A WILDCARD" region [] $
3012+ error "TODO PIndentAlias" row col
3013+
3014+
3015+toPRecordReport :: Code.Source -> PRecord -> Row -> Col -> Report.Report
3016+toPRecordReport source record startRow startCol =
3017+ case record of
3018+ PRecordOpen row col ->
3019+ toUnfinishRecordPatternReport source row col startRow startCol $
3020+ D.reflow "I was expecting to see a field name next."
3021+
3022+ PRecordEnd row col ->
3023+ toUnfinishRecordPatternReport source row col startRow startCol $
3024+ D.fillSep
3025+ ["I","was","expecting","to","see","a","closing","curly","brace","next."
3026+ ,"Try","adding","a",D.dullyellow "}","here?"
3027+ ]
3028+
3029+ PRecordField row col ->
3030+ case Code.whatIsNext source row col of
3031+ Code.Keyword keyword ->
3032+ let
3033+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3034+ region = toWiderRegion row col (fromIntegral (length keyword))
3035+ in
3036+ Report.Report "RESERVED WORD" region [] $
2746− Code.toSnippet source region Nothing
3037+ Code.toSnippet source surroundings (Just region)
2747 (
3038 (
2748 D.reflow $
3039 D.reflow $
2749− "I was expecting a _ here:"
3040+ "I was not expecting to see `" ++ keyword ++ "` as a record field name:"
2750 ,
3041 ,
2751 D.reflow $
3042 D.reflow $
2752− "An underscore indicates that “I do not care about this value” and is\
3043+ "This is a reserved word, not available for variable names. Try another name!"
2753− \ called a wildcard pattern because it will match with any type of values."
2754 )
3044 )
2755
3045
2756− WildcardNotVar startCol endCol ->
3046+ _ ->
3047+ toUnfinishRecordPatternReport source row col startRow startCol $
3048+ D.reflow "I was expecting to see a field name next."
3049+
3050+ PRecordSpace space row col ->
3051+ toSpaceReport source space row col
3052+
3053+ PRecordIndentOpen row col ->
3054+ toUnfinishRecordPatternReport source row col startRow startCol $
3055+ D.reflow "I was expecting to see a field name next."
3056+
3057+ PRecordIndentEnd row col ->
3058+ toUnfinishRecordPatternReport source row col startRow startCol $
3059+ D.fillSep
3060+ ["I","was","expecting","to","see","a","closing","curly","brace","next."
3061+ ,"Try","adding","a",D.dullyellow "}","here?"
3062+ ]
3063+
3064+ PRecordIndentField row col ->
3065+ toUnfinishRecordPatternReport source row col startRow startCol $
3066+ D.reflow "I was expecting to see a field name next."
3067+
3068+
3069+toUnfinishRecordPatternReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3070+toUnfinishRecordPatternReport source row col startRow startCol message =
3071+ let
3072+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3073+ region = toRegion row col
3074+ in
3075+ Report.Report "UNFINISHED RECORD PATTERN" region [] $
3076+ Code.toSnippet source surroundings (Just region)
3077+ (
3078+ D.reflow $
3079+ "I was partway through parsing a record pattern, but I got stuck here:"
3080+ ,
3081+ D.stack
3082+ [ message
3083+ , D.toFancyHint $
3084+ ["A","record","pattern","looks","like",D.dullyellow "{x,y}","or",D.dullyellow "{name,age}"
3085+ ,"where","you","list","the","field","names","you","want","to","access."
3086+ ]
3087+ ]
3088+ )
3089+
3090+
3091+
3092+toPTupleReport :: Code.Source -> PContext -> PTuple -> Row -> Col -> Report.Report
3093+toPTupleReport source context tuple startRow startCol =
3094+ case tuple of
3095+ PTupleOpen row col ->
3096+ case Code.whatIsNext source row col of
3097+ Code.Keyword keyword ->
2757 let
3098 let
2758− badRegion =
2759− A.Region (A.Position row startCol) (A.Position row endCol)
3099+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3100+ region = toWiderRegion row col (fromIntegral (length keyword))
2760 in
3101 in
2761− Report.Report "INVALID PATTERN" badRegion [] $
3102+ Report.Report "RESERVED WORD" region [] $
2762− Code.toSnippet source badRegion Nothing
3103+ Code.toSnippet source surroundings (Just region)
2763 (
3104 (
2764 D.reflow $
3105 D.reflow $
2765− "I was expecting to see an underscore without any additional characters:"
3106+ "It looks like you are trying to use `" ++ keyword ++ "` as a variable name:"
2766 ,
3107 ,
2767 D.reflow $
3108 D.reflow $
2768− "There are two options. Either (1) remove the extra characters and ignore the\
3109+ "This is a reserved word! Try using some other name?"
2769− \ value or (2) remove the starting underscore to give the value a normal name."
2770 )
3110 )
2771
3111
2772− -- Parse.Pattern
3112+ _ ->
2773−
3113+ let
2774− FloatInPattern ->
3114+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3115+ region = toRegion row col
3116+ in
2775− Report.Report "INVALID PATTERN" region [] $
3117+ Report.Report "UNFINISHED PARENTHESES" region [] $
2776− Code.toSnippet source region Nothing
3118+ Code.toSnippet source surroundings (Just region)
2777 (
3119 (
2778 D.reflow $
3120 D.reflow $
2779− "I cannot pattern match with floating point numbers:"
3121+ "I just saw an open parenthesis, but I got stuck here:"
2780 ,
3122 ,
2781− D.reflow $
3123+ D.fillSep
2782− "Equality on floats can be unreliable, so you usually want to check that they\
3124+ ["I","was","expecting","so","see","a","pattern","next."
2783− \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
3125+ ,"Maybe","it","will","end","up","being","something"
3126+ ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
3127+ ]
2784 )
3128 )
2785−-}
3129+
3130+ PTupleEnd row col ->
3131+ let
3132+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3133+ region = toRegion row col
3134+ in
3135+ Report.Report "UNFINISHED PARENTHESES" region [] $
3136+ Code.toSnippet source surroundings (Just region) $
3137+ (
3138+ D.reflow $
3139+ "I was expecting a closing parenthesis next:"
3140+ ,
3141+ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3142+ )
3143+
3144+ PTupleExpr pattern row col ->
3145+ toPatternReport source context pattern row col
3146+
3147+ PTupleSpace space row col ->
3148+ toSpaceReport source space row col
3149+
3150+ PTupleIndentEnd row col ->
3151+ let
3152+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3153+ region = toRegion row col
3154+ in
3155+ Report.Report "UNFINISHED PARENTHESES" region [] $
3156+ Code.toSnippet source surroundings (Just region) $
3157+ (
3158+ D.reflow $
3159+ "I was expecting a closing parenthesis next:"
3160+ ,
3161+ D.stack
3162+ [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3163+ , D.toSimpleNote $
3164+ "I can get confused by indentation in cases like this, so\
3165+ \ maybe you have a closing parenthesis but it is not indented enough?"
3166+ ]
3167+ )
3168+
3169+ PTupleIndentExpr1 row col ->
3170+ let
3171+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3172+ region = toRegion row col
3173+ in
3174+ Report.Report "UNFINISHED PARENTHESES" region [] $
3175+ Code.toSnippet source surroundings (Just region) $
3176+ (
3177+ D.reflow $
3178+ "I just saw an open parenthesis, but then I got stuck here:"
3179+ ,
3180+ D.fillSep
3181+ ["I","was","expecting","so","see","a","pattern","next."
3182+ ,"Maybe","it","will","end","up","being","something"
3183+ ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
3184+ ]
3185+ )
3186+
3187+ PTupleIndentExprN row col ->
3188+ let
3189+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3190+ region = toRegion row col
3191+ in
3192+ Report.Report "UNFINISHED TUPLE" region [] $
3193+ Code.toSnippet source surroundings (Just region) $
3194+ (
3195+ D.reflow $
3196+ "I am partway through parsing a tuple pattern, but I got stuck here:"
3197+ ,
3198+ D.stack
3199+ [ D.fillSep
3200+ ["I","was","expecting","so","see","a","pattern","next."
3201+ ,"I","am","expecting","the","final","result","to","be","something"
3202+ ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "."
3203+ ]
3204+ , D.toSimpleNote $
3205+ "I can get confused by indentation in cases like this, so the problem\
3206+ \ may be that the next part is not indented enough?"
3207+ ]
3208+ )
3209+
3210+
3211+toPListReport :: Code.Source -> PContext -> PList -> Row -> Col -> Report.Report
3212+toPListReport source context list startRow startCol =
3213+ case list of
3214+ PListOpen row col ->
3215+ error "TODO PListOpen" row col startRow startCol
3216+
3217+ PListEnd row col ->
3218+ error "TODO PListEnd" row col
3219+
3220+ PListExpr pattern row col ->
3221+ toPatternReport source context pattern row col
3222+
3223+ PListSpace space row col ->
3224+ toSpaceReport source space row col
3225+
3226+ PListIndentOpen row col ->
3227+ error "TODO PListIndentOpen" row col
3228+
3229+ PListIndentEnd row col ->
3230+ error "TODO PListIndentEnd" row col
3231+
3232+ PListIndentExpr row col ->
3233+ error "TODO PListIndentExpr" row col
3234+
3235+
3236+
3237+-- TYPES
3238+
3239+
3240+toTypeReport :: Code.Source -> Type -> Row -> Col -> Report.Report
3241+toTypeReport source tipe startRow startCol =
3242+ case tipe of
3243+ TRecord record row col ->
3244+ toTRecordReport source record row col
3245+
3246+ TTuple tuple row col ->
3247+ toTTupleReport source tuple row col
3248+
3249+ TVariant row col ->
3250+ error "TODO TVariant" row col startRow startCol
3251+
3252+ TArrow row col ->
3253+ error "TODO TArrow" row col
3254+
3255+ TStart row col ->
3256+ error "TODO TStart" row col
3257+
3258+ TSpace space row col ->
3259+ toSpaceReport source space row col
3260+
3261+ TIndentStart row col ->
3262+ error "TODO TIndentStart" row col
3263+
3264+
3265+
3266+toTRecordReport :: Code.Source -> TRecord -> Row -> Col -> Report.Report
3267+toTRecordReport source record startRow startCol =
3268+ case record of
3269+ TRecordOpen row col ->
3270+ error "TODO TRecordOpen" row col startRow startCol
3271+
3272+ TRecordEnd row col ->
3273+ error "TODO TRecordEnd" row col
3274+
3275+ TRecordField row col ->
3276+ error "TODO TRecordField" row col
3277+
3278+ TRecordColon row col ->
3279+ error "TODO TRecordColon" row col
3280+
3281+ TRecordType tipe row col ->
3282+ error "TODO TRecordType" tipe row col
3283+
3284+ TRecordSpace space row col ->
3285+ toSpaceReport source space row col
3286+
3287+ TRecordIndentOpen row col ->
3288+ error "TODO TRecordIndentOpen" row col
3289+
3290+ TRecordIndentField row col ->
3291+ error "TODO TRecordIndentField" row col
3292+
3293+ TRecordIndentColon row col ->
3294+ error "TODO TRecordIndentColon" row col
3295+
3296+ TRecordIndentType row col ->
3297+ error "TODO TRecordIndentType" row col
3298+
3299+ TRecordIndentEnd row col ->
3300+ error "TODO TRecordIndentEnd" row col
3301+
3302+
3303+
3304+toTTupleReport :: Code.Source -> TTuple -> Row -> Col -> Report.Report
3305+toTTupleReport source tuple startRow startCol =
3306+ case tuple of
3307+ TTupleOpen row col ->
3308+ error "TODO TTupleOpen" row col startRow startCol
3309+
3310+ TTupleEnd row col ->
3311+ error "TODO TTupleEnd" row col
3312+
3313+ TTupleType tipe row col ->
3314+ error "TODO TTupleType" tipe row col
3315+
3316+ TTupleSpace space row col ->
3317+ toSpaceReport source space row col
3318+
3319+ TTupleIndentOpen row col ->
3320+ error "TODO TTupleIndentOpen" row col
3321+
3322+ TTupleIndentType row col ->
3323+ error "TODO TTupleIndentType" row col
3324+
3325+ TTupleIndentEnd row col ->
3326+ error "TODO TTupleIndentEnd" row col