@@ -649,9 +649,156 @@ toParseErrorReport source modul =
649649 toSpaceReport source space row col
650650
651651 ModuleBadEnd row col ->
652− if col == 1
653− then toDeclStartReport source row col
654− else toWeirdEndReport source row col
652+ case Code.whatIsNext source row col of
653+ Code.Keyword keyword ->
654+ let
655+ region = toKeywordRegion row col keyword
656+ in
657+ Report.Report "RESERVED WORD" region [] $
658+ Code.toSnippet source region Nothing
659+ (
660+ D.reflow $
661+ "I got stuck on this reserved word:"
662+ ,
663+ D.reflow $
664+ "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
665+ )
666+
667+ Code.Operator op ->
668+ let
669+ region = toKeywordRegion row col op
670+ in
671+ Report.Report "UNEXPECTED SYMBOL" region [] $
672+ Code.toSnippet source region Nothing
673+ (
674+ D.reflow $
675+ "I ran into an unexpected symbol:"
676+ ,
677+ D.reflow $
678+ "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
679+ \ I can give a better hint from there?"
680+ )
681+
682+ Code.Close term bracket ->
683+ let
684+ region = toRegion row col
685+ in
686+ Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
687+ Code.toSnippet source region Nothing
688+ (
689+ D.reflow $
690+ "I ran into an unexpected " ++ term ++ ":"
691+ ,
692+ D.reflow $
693+ "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
694+ )
695+
696+ Code.Other maybeChar ->
697+ let
698+ region = toRegion row col
699+ in
700+ case maybeChar of
701+ Just ';' ->
702+ Report.Report "UNEXPECTED SEMICOLON" region [] $
703+ Code.toSnippet source region Nothing
704+ (
705+ D.reflow $
706+ "I got stuck on this semicolon:"
707+ ,
708+ D.stack
709+ [ D.reflow $ "Try removing it?"
710+ , D.toSimpleNote $
711+ "Some languages require semicolons at the end of each statement. These are\
712+ \ often called C-like languages, and they usually share a lot of language design\
713+ \ choices. (E.g. side-effects, for loops, etc.) Elm manages effects with commands\
714+ \ and subscriptions instead, so there is no special syntax for \"statements\" and\
715+ \ therefore no need to use semicolons to separate them. I think this will make\
716+ \ more sense as you work through <https://guide.elm-lang.org> though!"
717+ ]
718+ )
719+
720+ Just ',' ->
721+ Report.Report "UNEXPECTED COMMA" region [] $
722+ Code.toSnippet source region Nothing
723+ (
724+ D.reflow $
725+ "I got stuck on this comma:"
726+ ,
727+ D.stack
728+ [ D.reflow $
729+ "I do not think I am parsing a list or tuple right now. Try deleting the comma?"
730+ , D.toSimpleNote $
731+ "If this is supposed to be part of a list, the problem may be a bit earlier.\
732+ \ Perhaps the opening [ is missing? Or perhaps some value in the list has an extra\
733+ \ closing ] that is making me think the list ended earlier? The same kinds of\
734+ \ things could be going wrong if this is supposed to be a tuple."
735+ ]
736+ )
737+
738+ Just '`' ->
739+ Report.Report "UNEXPECTED CHARACTER" region [] $
740+ Code.toSnippet source region Nothing
741+ (
742+ D.reflow $
743+ "I got stuck on this character:"
744+ ,
745+ D.stack
746+ [ D.reflow $
747+ "It is not used for anything in Elm syntax. It is used for multi-line strings in\
748+ \ some languages though, so if you want a string that spans multiple lines, you\
749+ \ can use Elm's multi-line string syntax like this:"
750+ , D.vcat
751+ [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
752+ , mempty
753+ , D.dullyellow "# Multi-line Strings"
754+ , mempty
755+ , D.dullyellow "- start with triple double quotes"
756+ , D.dullyellow "- write whatever you want"
757+ , D.dullyellow "- no need to escape newlines or double quotes"
758+ , D.dullyellow "- end with triple double quotes"
759+ , mempty
760+ , D.dullyellow "\"\"\""
761+ ]
762+ , D.reflow $
763+ "Otherwise I do not know what is going on! Try removing the character?"
764+ ]
765+ )
766+
767+ Just '$' ->
768+ Report.Report "UNEXPECTED SYMBOL" region [] $
769+ Code.toSnippet source region Nothing
770+ (
771+ D.reflow $
772+ "I got stuck on this dollar sign:"
773+ ,
774+ D.reflow $
775+ "It is not used for anything in Elm syntax. Are you coming from a language where\
776+ \ dollar signs can be used in variable names? If so, try a name that (1) starts\
777+ \ with a letter and (2) only contains letters, numbers, and underscores."
778+ )
779+
780+ Just c | elem c ['#','@','!','%','~'] ->
781+ Report.Report "UNEXPECTED SYMBOL" region [] $
782+ Code.toSnippet source region Nothing
783+ (
784+ D.reflow $
785+ "I got stuck on this symbol:"
786+ ,
787+ D.reflow $
788+ "It is not used for anything in Elm syntax. Try removing it?"
789+ )
790+
791+ _ ->
792+ Report.Report "SYNTAX PROBLEM" region [] $
793+ Code.toSnippet source region Nothing
794+ (
795+ D.reflow $
796+ "I got stuck here:"
797+ ,
798+ D.reflow $
799+ "Whatever I am running into is confusing me a lot! Normally I can give fairly\
800+ \ specific hints, but something is really tripping me up this time."
801+ )
655802
656803 ModuleProblem row col ->
657804 let
@@ -797,11 +944,11 @@ toParseErrorReport source modul =
797944 [ D.reflow $
798945 "I am not sure what is going on, but I recommend starting an Elm\
799946 \ file with the following lines:"
800− , D.indent 4 $ D.vcat $
947+ , D.vcat
801948 [ D.fillSep [D.cyan "import","Html"]
802949 , ""
803− , "main ="
804− , " Html.text " <> D.dullyellow "\"Hello!\""
950+ , D.fillSep [D.green "main","="]
951+ , D.indent 2 $ D.fillSep [D.cyan "Html" <> ".text",D.dullyellow "\"Hello!\""]
805952 ]
806953 , D.reflow $
807954 "You should be able to copy those lines directly into your file. Check out the\
@@ -830,12 +977,11 @@ toParseErrorReport source modul =
830977 , D.indent 4 $ D.vcat $
831978 [ D.fillSep [D.cyan "import","Dict"]
832979 , D.fillSep [D.cyan "import","Maybe"]
833− , D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","A"]
834− , D.fillSep [D.cyan "import","Json.Decode",D.cyan "exposing","(..)"]
980+ , D.fillSep [D.cyan "import","Html.Attributes"]
981+ , D.fillSep [D.cyan "import","Json.Decode"]
835982 ]
836983 , D.reflow $
837984 "Notice that the module names all start with capital letters. That is required!"
838− , D.reflowLink "Read" "imports" "to learn more."
839985 ]
840986 )
841987
@@ -862,7 +1008,6 @@ toParseErrorReport source modul =
8621008 ]
8631009 , D.reflow $
8641010 "Notice that the alias always starts with a capital letter. That is required!"
865− , D.reflowLink "Read" "imports" "to learn more."
8661011 ]
8671012 )
8681013
@@ -925,192 +1070,6 @@ toParseErrorReport source modul =
9251070
9261071
9271072
928−-- WEIRD END
929−
930−
931−toWeirdEndReport :: Code.Source -> Row -> Col -> Report.Report
932−toWeirdEndReport source row col =
933− case Code.whatIsNext source row col of
934− Code.Keyword keyword ->
935− let
936− region = toKeywordRegion row col keyword
937− in
938− Report.Report "RESERVED WORD" region [] $
939− Code.toSnippet source region Nothing
940− (
941− D.reflow $
942− "I got stuck on this reserved word:"
943− ,
944− D.reflow $
945− "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
946− )
947−
948− Code.Operator op ->
949− let
950− region = toKeywordRegion row col op
951− in
952− Report.Report "UNEXPECTED SYMBOL" region [] $
953− Code.toSnippet source region Nothing
954− (
955− D.reflow $
956− "I ran into an unexpected symbol:"
957− ,
958− D.reflow $
959− "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
960− \ I can give a better hint from there?"
961− )
962−
963− Code.Close term bracket ->
964− let
965− region = toRegion row col
966− in
967− Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
968− Code.toSnippet source region Nothing
969− (
970− D.reflow $
971− "I ran into an unexpected " ++ term ++ ":"
972− ,
973− D.reflow $
974− "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
975− )
976−
977− Code.Lower c cs ->
978− let
979− region = toKeywordRegion row col (c:cs)
980− in
981− Report.Report "UNEXPECTED NAME" region [] $
982− Code.toSnippet source region Nothing
983− (
984− D.reflow $
985− "I got stuck on this name:"
986− ,
987− D.reflow $
988− "It is confusing me a lot! Normally I can give fairly specific hints, but\
989− \ something is really tripping me up this time."
990− )
991−
992− Code.Upper c cs ->
993− let
994− region = toKeywordRegion row col (c:cs)
995− in
996− Report.Report "UNEXPECTED NAME" region [] $
997− Code.toSnippet source region Nothing
998− (
999− D.reflow $
1000− "I got stuck on this name:"
1001− ,
1002− D.reflow $
1003− "It is confusing me a lot! Normally I can give fairly specific hints, but\
1004− \ something is really tripping me up this time."
1005− )
1006−
1007− Code.Other maybeChar ->
1008− let
1009− region = toRegion row col
1010− in
1011− case maybeChar of
1012− Just ';' ->
1013− Report.Report "UNEXPECTED SEMICOLON" region [] $
1014− Code.toSnippet source region Nothing
1015− (
1016− D.reflow $
1017− "I got stuck on this semicolon:"
1018− ,
1019− D.stack
1020− [ D.reflow $ "Try removing it?"
1021− , D.toSimpleNote $
1022− "Some languages require semicolons at the end of each statement. These are\
1023− \ often called C-like languages, and they usually share a lot of language design\
1024− \ choices. (E.g. side-effects, for loops, etc.) Elm manages effects with commands\
1025− \ and subscriptions instead, so there is no special syntax for \"statements\" and\
1026− \ therefore no need to use semicolons to separate them. I think this will make\
1027− \ more sense as you work through <https://guide.elm-lang.org> though!"
1028− ]
1029− )
1030−
1031− Just ',' ->
1032− Report.Report "UNEXPECTED COMMA" region [] $
1033− Code.toSnippet source region Nothing
1034− (
1035− D.reflow $
1036− "I got stuck on this comma:"
1037− ,
1038− D.stack
1039− [ D.reflow $
1040− "I do not think I am parsing a list or tuple right now. Try deleting the comma?"
1041− , D.toSimpleNote $
1042− "If this is supposed to be part of a list, the problem may be a bit earlier.\
1043− \ Perhaps the opening [ is missing? Or perhaps some value in the list has an extra\
1044− \ closing ] that is making me think the list ended earlier? The same kinds of\
1045− \ things could be going wrong if this is supposed to be a tuple."
1046− ]
1047− )
1048−
1049− Just '`' ->
1050− Report.Report "UNEXPECTED CHARACTER" region [] $
1051− Code.toSnippet source region Nothing
1052− (
1053− D.reflow $
1054− "I got stuck on this character:"
1055− ,
1056− D.stack
1057− [ D.reflow $
1058− "It is not used for anything in Elm syntax. It is used for multi-line strings in\
1059− \ some languages though, so if you want a string that spans multiple lines, you\
1060− \ can use Elm's multi-line string syntax like this:"
1061− , D.dullyellow $ D.indent 4 $ D.vcat $
1062− [ "\"\"\""
1063− , "# Multi-line Strings"
1064− , ""
1065− , "- start with triple double quotes"
1066− , "- write whatever you want"
1067− , "- no need to escape newlines or double quotes"
1068− , "- end with triple double quotes"
1069− , "\"\"\""
1070− ]
1071− , D.reflow $
1072− "Otherwise I do not know what is going on! Try removing the character?"
1073− ]
1074− )
1075−
1076− Just '$' ->
1077− Report.Report "UNEXPECTED SYMBOL" region [] $
1078− Code.toSnippet source region Nothing
1079− (
1080− D.reflow $
1081− "I got stuck on this dollar sign:"
1082− ,
1083− D.reflow $
1084− "It is not used for anything in Elm syntax. Are you coming from a language where\
1085− \ dollar signs can be used in variable names? If so, try a name that (1) starts\
1086− \ with a letter and (2) only contains letters, numbers, and underscores."
1087− )
1088−
1089− Just c | elem c ['#','@','!','%','~'] ->
1090− Report.Report "UNEXPECTED SYMBOL" region [] $
1091− Code.toSnippet source region Nothing
1092− (
1093− D.reflow $
1094− "I got stuck on this symbol:"
1095− ,
1096− D.reflow $
1097− "It is not used for anything in Elm syntax. Try removing it?"
1098− )
1099−
1100− _ ->
1101− Report.Report "SYNTAX PROBLEM" region [] $
1102− Code.toSnippet source region Nothing
1103− (
1104− D.reflow $
1105− "I got stuck here:"
1106− ,
1107− D.reflow $
1108− "Whatever I am running into is confusing me a lot! Normally I can give fairly\
1109− \ specific hints, but something is really tripping me up this time."
1110− )
1111−
1112−
1113−
11141073-- IMPORTS
11151074
11161075
@@ -1136,7 +1095,6 @@ toImportReport source row col =
11361095 ]
11371096 , D.reflow $
11381097 "You are probably trying to import a different module, but try to make it look like one of these examples!"
1139− , D.reflowLink "Read" "imports" "to learn more."
11401098 ]
11411099 )
11421100
@@ -1443,7 +1401,114 @@ toDeclarationsReport :: Code.Source -> Decl -> Report.Report
14431401toDeclarationsReport source decl =
14441402 case decl of
14451403 DeclStart row col ->
1446− toDeclStartReport source row col
1404+ case Code.whatIsNext source row col of
1405+ Code.Close term bracket ->
1406+ let
1407+ region = toRegion row col
1408+ in
1409+ Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
1410+ Code.toSnippet source region Nothing
1411+ (
1412+ D.reflow $
1413+ "I was not expecting to see a " ++ term ++ " here:"
1414+ , D.reflow $
1415+ "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
1416+ )
1417+
1418+ Code.Keyword keyword ->
1419+ let
1420+ region = toKeywordRegion row col keyword
1421+ in
1422+ Report.Report "RESERVED WORD" region [] $
1423+ Code.toSnippet source region Nothing
1424+ (
1425+ D.reflow $
1426+ "I was not expecting to run into the `" ++ keyword ++ "` keyword here:"
1427+ ,
1428+ case keyword of
1429+ "import" ->
1430+ D.reflow $
1431+ "It is reserved for declaring imports at the top of your module. If you want\
1432+ \ another import, try moving it up top with the other imports. If you want to\
1433+ \ define a value or function, try changing the name to something else!"
1434+
1435+ "case" ->
1436+ D.stack
1437+ [ D.reflow $
1438+ "It is reserved for writing `case` expressions. Try using a different name?"
1439+ , D.toSimpleNote $
1440+ "If you are trying to write a `case` expression, it needs to be part of a\
1441+ \ definition. So you could write something like this instead:"
1442+ , D.vcat $
1443+ [ D.indent 0 $ D.fillSep [D.green "getWidth","maybeWidth","="]
1444+ , D.indent 2 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1445+ , D.indent 4 $ D.fillSep [D.blue "Just","width","->"]
1446+ , D.indent 6 $ D.fillSep ["width","+",D.dullyellow "200"]
1447+ , ""
1448+ , D.indent 4 $ D.fillSep [D.blue "Nothing","->"]
1449+ , D.indent 6 $ D.fillSep [D.dullyellow "400"]
1450+ ]
1451+ , D.reflow $
1452+ "This defines a `getWidth` function that we can use elsewhere in our program."
1453+ ]
1454+
1455+ "if" ->
1456+ D.stack
1457+ [ D.reflow $
1458+ "It is reserved for writing `if` expressions. Try using a different name?"
1459+ , D.toSimpleNote $
1460+ "If you are trying to write an `if` expression, it needs to be part of a\
1461+ \ definition. So you could write something like this instead:"
1462+ , D.vcat $
1463+ [ D.indent 0 $ D.fillSep [D.green "reviewPowerLevel","powerLevel","="]
1464+ , D.indent 2 $ D.fillSep $
1465+ [D.cyan "if","powerLevel",">",D.dullyellow "9000"
1466+ ,D.cyan "then",D.dullyellow "\"OVER 9000!!!\""
1467+ ,D.cyan "else",D.dullyellow "\"not bad\""
1468+ ]
1469+ ]
1470+ , D.reflow $
1471+ "This defines a `reviewPowerLevel` function that we can use elsewhere in our program."
1472+ ]
1473+
1474+ _ ->
1475+ D.reflow $
1476+ "It is a reserved word. Try changing the name to something else?"
1477+ )
1478+
1479+ _ ->
1480+ let
1481+ region = toRegion row col
1482+ in
1483+ Report.Report "SYNTAX PROBLEM" region [] $
1484+ Code.toSnippet source region Nothing
1485+ (
1486+ D.reflow $
1487+ "I was expecting to see a declaration, but I am getting stuck here:"
1488+ ,
1489+ D.stack
1490+ [ case Code.whatIsNext source row col of
1491+ Code.Other (Just char) | Char.isUpper char ->
1492+ D.reflow $
1493+ "All declarations start with lower-case letters in Elm, so maybe this letter can\
1494+ \ be changed to lower-case?"
1495+
1496+ _ ->
1497+ D.reflow $
1498+ "Declarations normally start with a lower-case name or the `type` keyword."
1499+ , D.toSimpleHint $
1500+ "Here are a couple valid declarations for reference:"
1501+ , D.vcat
1502+ [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1503+ , D.fillSep [D.green "add","x","y","="]
1504+ , D.fillSep [" ","x","+","y"]
1505+ ]
1506+ , D.fillSep [D.cyan "type",D.green "User","=","Anonymous","|","LoggedIn String"]
1507+ , D.reflow $
1508+ "Notice that these declarations start with lower-case letters. Capitalization\
1509+ \ makes a difference in Elm!"
1510+ ]
1511+ )
14471512
14481513 DeclSpace space row col ->
14491514 toSpaceReport source space row col
@@ -1473,165 +1538,6 @@ toDeclarationsReport source decl =
14731538 )
14741539
14751540
1476−toDeclStartReport :: Code.Source -> Row -> Col -> Report.Report
1477−toDeclStartReport source row col =
1478− case Code.whatIsNext source row col of
1479− Code.Close term bracket ->
1480− let
1481− region = toRegion row col
1482− in
1483− Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
1484− Code.toSnippet source region Nothing
1485− (
1486− D.reflow $
1487− "I was not expecting to see a " ++ term ++ " here:"
1488− , D.reflow $
1489− "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
1490− )
1491−
1492− Code.Keyword keyword ->
1493− let
1494− region = toKeywordRegion row col keyword
1495− in
1496− Report.Report "RESERVED WORD" region [] $
1497− Code.toSnippet source region Nothing
1498− (
1499− D.reflow $
1500− "I was not expecting to run into the `" ++ keyword ++ "` keyword here:"
1501− ,
1502− case keyword of
1503− "import" ->
1504− D.reflow $
1505− "It is reserved for declaring imports at the top of your module. If you want\
1506− \ another import, try moving it up top with the other imports. If you want to\
1507− \ define a value or function, try changing the name to something else!"
1508−
1509− "case" ->
1510− D.stack
1511− [ D.reflow $
1512− "It is reserved for writing `case` expressions. Try using a different name?"
1513− , D.toSimpleNote $
1514− "If you are trying to write a `case` expression, it needs to be part of a\
1515− \ definition. So you could write something like this instead:"
1516− , D.indent 4 $ D.vcat $
1517− [ D.indent 0 $ D.fillSep ["getWidth","maybeWidth","="]
1518− , D.indent 2 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1519− , D.indent 4 $ D.fillSep [D.blue "Just","width","->"]
1520− , D.indent 6 $ D.fillSep ["width","+",D.dullyellow "200"]
1521− , ""
1522− , D.indent 4 $ D.fillSep [D.blue "Nothing","->"]
1523− , D.indent 6 $ D.fillSep [D.dullyellow "400"]
1524− ]
1525− , D.reflow $
1526− "This defines a `getWidth` function that you can use elsewhere in your program."
1527− ]
1528−
1529− "if" ->
1530− D.stack
1531− [ D.reflow $
1532− "It is reserved for writing `if` expressions. Try using a different name?"
1533− , D.toSimpleNote $
1534− "If you are trying to write an `if` expression, it needs to be part of a\
1535− \ definition. So you could write something like this instead:"
1536− , D.indent 4 $ D.vcat $
1537− [ "greet name ="
1538− , D.fillSep $
1539− [" "
1540− ,D.cyan "if","name","==",D.dullyellow "\"Abraham Lincoln\""
1541− ,D.cyan "then",D.dullyellow "\"Greetings Mr. President.\""
1542− ,D.cyan "else",D.dullyellow "\"Hey!\""
1543− ]
1544− ]
1545− , D.reflow $
1546− "This defines a `reviewPowerLevel` function that you can use elsewhere in your program."
1547− ]
1548−
1549− _ ->
1550− D.reflow $
1551− "It is a reserved word. Try changing the name to something else?"
1552− )
1553−
1554− Code.Upper c cs ->
1555− let
1556− region = toRegion row col
1557− in
1558− Report.Report "UNEXPECTED CAPITAL LETTER" region [] $
1559− Code.toSnippet source region Nothing
1560− (
1561− D.reflow $
1562− "Declarations always start with a lower-case letter, so I am getting stuck here:"
1563− ,
1564− D.stack
1565− [ D.fillSep $
1566− ["Try","a","name","like"
1567− ,D.green (D.fromChars (Char.toLower c : cs))
1568− ,"instead?"
1569− ]
1570− , D.toSimpleNote $
1571− "Here are a couple valid declarations for reference:"
1572− , D.indent 4 $ D.vcat $
1573− [ "greet : String -> String"
1574− , "greet name ="
1575− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1576− , ""
1577− , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1578− ]
1579− , D.reflow $
1580− "Notice that they always start with a lower-case letter. Capitalization matters!"
1581− ]
1582− )
1583−
1584− Code.Other (Just char) | elem char ['(', '{', '[', '+', '-', '*', '/', '^', '&', '|', '"', '\'', '!', '@', '#', '$', '%'] ->
1585− let
1586− region = toRegion row col
1587− in
1588− Report.Report "UNEXPECTED SYMBOL" region [] $
1589− Code.toSnippet source region Nothing
1590− (
1591− D.reflow $
1592− "I am getting stuck because this line starts with the " ++ [char] ++ " symbol:"
1593− ,
1594− D.stack
1595− [ D.reflow $
1596− "When a line has no spaces at the beginning, I expect it to be a declaration like one of these:"
1597− , D.indent 4 $ D.vcat $
1598− [ "greet : String -> String"
1599− , "greet name ="
1600− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1601− , ""
1602− , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1603− ]
1604− , D.reflow $
1605− "If this is not supposed to be a declaration, try adding some spaces before it?"
1606− ]
1607− )
1608−
1609− _ ->
1610− let
1611− region = toRegion row col
1612− in
1613− Report.Report "WEIRD DECLARATION" region [] $
1614− Code.toSnippet source region Nothing
1615− (
1616− D.reflow $
1617− "I am trying to parse a declaration, but I am getting stuck here:"
1618− ,
1619− D.stack
1620− [ D.reflow $
1621− "When a line has no spaces at the beginning, I expect it to be a declaration like one of these:"
1622− , D.indent 4 $ D.vcat $
1623− [ "greet : String -> String"
1624− , "greet name ="
1625− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1626− , ""
1627− , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1628− ]
1629− , D.reflow $
1630− "Try to make your declaration look like one of those? Or if this is not\
1631− \ supposed to be a declaration, try adding some spaces before it?"
1632− ]
1633− )
1634−
16351541
16361542-- PORT
16371543
@@ -1758,7 +1664,7 @@ toPortReport source port_ startRow startCol =
17581664 [ D.reflow $
17591665 "I was expecting to see a type next. Here are examples of outgoing and\
17601666 \ incoming ports for reference:"
1761− , D.indent 4 $ D.vcat $
1667+ , D.vcat
17621668 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
17631669 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
17641670 ]
@@ -1777,7 +1683,7 @@ portNote =
17771683 D.stack
17781684 [ D.toSimpleNote $
17791685 "Here are some example `port` declarations for reference:"
1780− , D.indent 4 $ D.vcat $
1686+ , D.vcat
17811687 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
17821688 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
17831689 ]
@@ -1960,8 +1866,8 @@ typeAliasNote =
19601866 [ D.toSimpleNote $
19611867 "Here is an example of a valid `type alias` for reference:"
19621868 , D.vcat $
1963− [ D.indent 4 $ D.fillSep [D.cyan "type",D.cyan "alias","Person","="]
1964− , D.indent 6 $ D.vcat $
1869+ [ D.indent 0 $ D.fillSep [D.cyan "type",D.cyan "alias",D.green "Person","="]
1870+ , D.indent 2 $ D.vcat $
19651871 ["{ name : String"
19661872 ,", age : Int"
19671873 ,", height : Float"
@@ -2161,10 +2067,10 @@ customTypeNote =
21612067 [ D.toSimpleNote $
21622068 "Here is an example of a valid `type` declaration for reference:"
21632069 , D.vcat $
2164− [ D.indent 4 $ D.fillSep [D.cyan "type","Status"]
2165− , D.indent 6 $ D.fillSep ["=","Failure"]
2166− , D.indent 6 $ D.fillSep ["|","Waiting"]
2167− , D.indent 6 $ D.fillSep ["|","Success","String"]
2070+ [ D.indent 0 $ D.fillSep [D.cyan "type",D.green "Status"]
2071+ , D.indent 2 $ D.fillSep ["=","Failure"]
2072+ , D.indent 2 $ D.fillSep ["|","Waiting"]
2073+ , D.indent 2 $ D.fillSep ["|","Success","String"]
21682074 ]
21692075 , D.reflow $
21702076 "This defines a new `Status` type with three variants. This could be useful if\
@@ -2236,10 +2142,10 @@ toDeclDefReport source name declDef startRow startCol =
22362142 ,"a","type","annotation.","It","could","be","something","else","though,","so"
22372143 ,"here","is","a","valid","definition","for","reference:"
22382144 ]
2239− , D.indent 4 $ D.vcat $
2240− [ "greet : String -> String"
2241− , "greet name ="
2242− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2145+ , D.vcat
2146+ [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2147+ , D.fillSep [D.green "add","x","y","="]
2148+ , D.fillSep [" ","x","+","y"]
22432149 ]
22442150 , D.reflow $
22452151 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
@@ -2261,10 +2167,10 @@ toDeclDefReport source name declDef startRow startCol =
22612167 [ D.reflow $
22622168 "I am not sure what is going wrong exactly, so here is a valid\
22632169 \ definition (with an optional type annotation) for reference:"
2264− , D.indent 4 $ D.vcat $
2265− [ "greet : String -> String"
2266− , "greet name ="
2267− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2170+ , D.vcat
2171+ [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2172+ , D.fillSep [D.green "add","x","y","="]
2173+ , D.fillSep [" ","x","+","y"]
22682174 ]
22692175 , D.reflow $
22702176 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
@@ -2286,10 +2192,10 @@ toDeclDefReport source name declDef startRow startCol =
22862192 [ D.reflow $
22872193 "I am not sure what is going wrong exactly, so here is a valid\
22882194 \ definition (with an optional type annotation) for reference:"
2289− , D.indent 4 $ D.vcat $
2290− [ "greet : String -> String"
2291− , "greet name ="
2292− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2195+ , D.vcat
2196+ [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2197+ , D.fillSep [D.green "add","x","y","="]
2198+ , D.fillSep [" ","x","+","y"]
22932199 ]
22942200 , D.reflow $
22952201 "Try to use that format!"
@@ -2404,10 +2310,10 @@ declDefNote =
24042310 D.stack
24052311 [ D.reflow $
24062312 "Here is a valid definition (with a type annotation) for reference:"
2407− , D.indent 4 $ D.vcat $
2408− [ "greet : String -> String"
2409− , "greet name ="
2410− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2313+ , D.vcat
2314+ [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2315+ , D.fillSep [D.green "add","x","y","="]
2316+ , D.fillSep [" ","x","+","y"]
24112317 ]
24122318 , D.reflow $
24132319 "The top line (called a \"type annotation\") is optional. You can leave it off\
@@ -2591,7 +2497,7 @@ toExprReport source context expr startRow startCol =
25912497 ,"give","a","more","specific","hint!"
25922498 ]
25932499 , D.toSimpleNote $
2594− "This can also happen if I run into reserved words like `let` or `as` unexpectedly.\
2500+ "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
25952501 \ Or if I run into operators in unexpected spots. Point is, there are a\
25962502 \ couple ways I can get confused and give sort of weird advice!"
25972503 ]
@@ -2740,15 +2646,17 @@ toStringReport source string row col =
27402646 , D.toSimpleNote $
27412647 "For a string that spans multiple lines, you can use the multi-line string\
27422648 \ syntax like this:"
2743− , D.dullyellow $ D.indent 4 $ D.vcat $
2744− [ "\"\"\""
2745− , "# Multi-line Strings"
2746− , ""
2747− , "- start with triple double quotes"
2748− , "- write whatever you want"
2749− , "- no need to escape newlines or double quotes"
2750− , "- end with triple double quotes"
2751− , "\"\"\""
2649+ , D.vcat
2650+ [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
2651+ , mempty
2652+ , D.dullyellow "# Multi-line Strings"
2653+ , mempty
2654+ , D.dullyellow "- start with triple double quotes"
2655+ , D.dullyellow "- write whatever you want"
2656+ , D.dullyellow "- no need to escape newlines or double quotes"
2657+ , D.dullyellow "- end with triple double quotes"
2658+ , mempty
2659+ , D.dullyellow "\"\"\""
27522660 ]
27532661 ]
27542662 )
@@ -2767,15 +2675,17 @@ toStringReport source string row col =
27672675 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
27682676 , D.toSimpleNote $
27692677 "Here is a valid multi-line string for reference:"
2770− , D.dullyellow $ D.indent 4 $ D.vcat $
2771− [ "\"\"\""
2772− , "# Multi-line Strings"
2773− , ""
2774− , "- start with triple double quotes"
2775− , "- write whatever you want"
2776− , "- no need to escape newlines or double quotes"
2777− , "- end with triple double quotes"
2778− , "\"\"\""
2678+ , D.vcat
2679+ [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
2680+ , mempty
2681+ , D.dullyellow "# Multi-line Strings"
2682+ , mempty
2683+ , D.dullyellow "- start with triple double quotes"
2684+ , D.dullyellow "- write whatever you want"
2685+ , D.dullyellow "- no need to escape newlines or double quotes"
2686+ , D.dullyellow "- end with triple double quotes"
2687+ , mempty
2688+ , D.dullyellow "\"\"\""
27792689 ]
27802690 ]
27812691 )
@@ -3240,8 +3150,8 @@ toUnfinishLetReport source row col startRow startCol message =
32403150 [ message
32413151 , D.toSimpleNote $
32423152 "Here is an example with a valid `let` expression for reference:"
3243− , D.indent 4 $ D.vcat $
3244− [ D.indent 0 $ D.fillSep ["viewPerson","person","="]
3153+ , D.vcat $
3154+ [ D.indent 0 $ D.fillSep [D.green "viewPerson","person","="]
32453155 , D.indent 2 $ D.fillSep [D.cyan "let"]
32463156 , D.indent 4 $ D.fillSep ["fullName","="]
32473157 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
@@ -3359,10 +3269,10 @@ toLetDefReport source name def startRow startCol =
33593269 ,"a","type","annotation.","It","could","be","something","else","though,","so"
33603270 ,"here","is","a","valid","definition","for","reference:"
33613271 ]
3362− , D.indent 4 $ D.vcat $
3363− [ "greet : String -> String"
3364− , "greet name ="
3365− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3272+ , D.vcat
3273+ [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3274+ , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3275+ , D.indent 6 $ D.fillSep ["x","+","y"]
33663276 ]
33673277 , D.reflow $
33683278 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
@@ -3384,10 +3294,10 @@ toLetDefReport source name def startRow startCol =
33843294 [ D.reflow $
33853295 "I am not sure what is going wrong exactly, so here is a valid\
33863296 \ definition (with an optional type annotation) for reference:"
3387− , D.indent 4 $ D.vcat $
3388− [ "greet : String -> String"
3389− , "greet name ="
3390− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3297+ , D.vcat
3298+ [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3299+ , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3300+ , D.indent 6 $ D.fillSep ["x","+","y"]
33913301 ]
33923302 , D.reflow $
33933303 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
@@ -3409,10 +3319,10 @@ toLetDefReport source name def startRow startCol =
34093319 [ D.reflow $
34103320 "I am not sure what is going wrong exactly, so here is a valid\
34113321 \ definition (with an optional type annotation) for reference:"
3412− , D.indent 4 $ D.vcat $
3413− [ "greet : String -> String"
3414− , "greet name ="
3415− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3322+ , D.vcat
3323+ [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3324+ , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3325+ , D.indent 4 $ D.fillSep ["x","+","y"]
34163326 ]
34173327 , D.reflow $
34183328 "Try to use that format!"
@@ -3502,10 +3412,10 @@ defNote =
35023412 D.stack
35033413 [ D.reflow $
35043414 "Here is a valid definition (with a type annotation) for reference:"
3505− , D.indent 4 $ D.vcat $
3506− [ "greet : String -> String"
3507− , "greet name ="
3508− , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3415+ , D.vcat
3416+ [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3417+ , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3418+ , D.indent 6 $ D.fillSep ["x","+","y"]
35093419 ]
35103420 , D.reflow $
35113421 "The top line (called a \"type annotation\") is optional. You can leave it off\
@@ -4146,13 +4056,11 @@ toRecordReport source context record startRow startCol =
41464056 D.reflow $
41474057 "I just saw the opening curly brace of a record, but then I got stuck here:"
41484058 ,
4149− D.stack
4150− [ D.fillSep $
4151− ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
4152− ,"Try","defining","some","fields","of","your","own?"
4153− ]
4154− , noteForRecordIndentError
4155− ]
4059+ addNoteForRecordIndentError $
4060+ D.fillSep $
4061+ ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
4062+ ,"Try","defining","some","fields","of","your","own?"
4063+ ]
41564064 )
41574065
41584066 RecordIndentEnd row col ->
@@ -4186,13 +4094,11 @@ toRecordReport source context record startRow startCol =
41864094 D.reflow $
41874095 "I was partway through parsing a record, but I got stuck here:"
41884096 ,
4189− D.stack
4190− [ D.fillSep $
4191− ["I","was","expecting","to","see","a","closing","curly","brace","next."
4192− ,"Try","putting","a",D.green "}","next","and","see","if","that","helps?"
4193− ]
4194− , noteForRecordIndentError
4195− ]
4097+ addNoteForRecordIndentError $
4098+ D.fillSep $
4099+ ["I","was","expecting","to","see","a","closing","curly","brace","next."
4100+ ,"Try","putting","a",D.green "}","next","and","see","if","that","helps?"
4101+ ]
41964102 )
41974103
41984104 RecordIndentField row col ->
@@ -4227,12 +4133,10 @@ toRecordReport source context record startRow startCol =
42274133 "I am partway through parsing a record. I just saw a record\
42284134 \ field, so I was expecting to see an equals sign next:"
42294135 ,
4230− D.stack
4231− [ D.fillSep $
4232− ["Try","putting","an",D.green "=","followed","by","an","expression?"
4233− ]
4234− , noteForRecordIndentError
4235− ]
4136+ addNoteForRecordIndentError $
4137+ D.fillSep $
4138+ ["Try","putting","an",D.green "=","followed","by","an","expression?"
4139+ ]
42364140 )
42374141
42384142 RecordIndentExpr row col ->
@@ -4246,13 +4150,11 @@ toRecordReport source context record startRow startCol =
42464150 D.reflow $
42474151 "I am partway through parsing a record, and I was expecting to run into an expression next:"
42484152 ,
4249− D.stack
4250− [ D.fillSep $
4251− ["Try","putting","something","like"
4252− ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
4253− ]
4254− , noteForRecordIndentError
4255− ]
4153+ addNoteForRecordIndentError $
4154+ D.fillSep $
4155+ ["Try","putting","something","like"
4156+ ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
4157+ ]
42564158 )
42574159
42584160
@@ -4262,9 +4164,9 @@ noteForRecordError =
42624164 [ D.toSimpleNote
42634165 "If you are trying to define a record across multiple lines, I recommend using this format:"
42644166 , D.indent 4 $ D.vcat $
4265− [ "{ name = " <> D.dullyellow "\"Alice\""
4266− , ", age = " <> D.dullyellow "42"
4267− , ", height = " <> D.dullyellow "1.75"
4167+ [ "{ name = \"Alice\""
4168+ , ", age = 42"
4169+ , ", height = 1.75"
42684170 , "}"
42694171 ]
42704172 , D.reflow $
@@ -4273,16 +4175,18 @@ noteForRecordError =
42734175 ]
42744176
42754177
4276−noteForRecordIndentError :: D.Doc
4277−noteForRecordIndentError =
4278− D.stack
4178+addNoteForRecordIndentError :: D.Doc -> D.Doc
4179+addNoteForRecordIndentError normalRecommendation =
4180+ D.stack $
4181+ normalRecommendation
4182+ :
42794183 [ D.toSimpleNote
42804184 "I may be confused by indentation. For example, if you are trying to define\
42814185 \ a record across multiple lines, I recommend using this format:"
42824186 , D.indent 4 $ D.vcat $
4283− [ "{ name = " <> D.dullyellow "\"Alice\""
4284− , ", age = " <> D.dullyellow "42"
4285− , ", height = " <> D.dullyellow "1.75"
4187+ [ "{ name = \"Alice\""
4188+ , ", age = 42"
4189+ , ", height = 1.75"
42864190 , "}"
42874191 ]
42884192 , D.reflow $
@@ -4476,9 +4380,9 @@ toListReport source context list startRow startCol =
44764380 , D.toSimpleNote
44774381 "I recommend using the following format for lists that span multiple lines:"
44784382 , D.indent 4 $ D.vcat $
4479− [ "[ " <> D.dullyellow "\"Alice\""
4480− , ", " <> D.dullyellow "\"Bob\""
4481− , ", " <> D.dullyellow "\"Chuck\""
4383+ [ "[ \"Alice\""
4384+ , ", \"Bob\""
4385+ , ", \"Chuck\""
44824386 , "]"
44834387 ]
44844388 , D.reflow $
@@ -4536,9 +4440,9 @@ toListReport source context list startRow startCol =
45364440 "I may be confused by indentation. For example, if you are trying to define\
45374441 \ a list across multiple lines, I recommend using this format:"
45384442 , D.indent 4 $ D.vcat $
4539− [ "[ " <> D.dullyellow "\"Alice\""
4540− , ", " <> D.dullyellow "\"Bob\""
4541− , ", " <> D.dullyellow "\"Chuck\""
4443+ [ "[ \"Alice\""
4444+ , ", \"Bob\""
4445+ , ", \"Chuck\""
45424446 , "]"
45434447 ]
45444448 , D.reflow $
@@ -4567,9 +4471,9 @@ toListReport source context list startRow startCol =
45674471 "I may be confused by indentation. For example, if you are trying to define\
45684472 \ a list across multiple lines, I recommend using this format:"
45694473 , D.indent 4 $ D.vcat $
4570− [ "[ " <> D.dullyellow "\"Alice\""
4571− , ", " <> D.dullyellow "\"Bob\""
4572− , ", " <> D.dullyellow "\"Chuck\""
4474+ [ "[ \"Alice\""
4475+ , ", \"Bob\""
4476+ , ", \"Chuck\""
45734477 , "]"
45744478 ]
45754479 , D.reflow $
@@ -4595,9 +4499,9 @@ toListReport source context list startRow startCol =
45954499 , D.toSimpleNote
45964500 "I recommend using the following format for lists that span multiple lines:"
45974501 , D.indent 4 $ D.vcat $
4598− [ "[ " <> D.dullyellow "\"Alice\""
4599− , ", " <> D.dullyellow "\"Bob\""
4600− , ", " <> D.dullyellow "\"Chuck\""
4502+ [ "[ \"Alice\""
4503+ , ", \"Bob\""
4504+ , ", \"Chuck\""
46014505 , "]"
46024506 ]
46034507 , D.reflow $