From 51daca31618ea63ff08ecb4014a27c071cfd24c9 Mon Sep 17 00:00:00 2001 From: Gaute Berge Date: Wed, 25 Oct 2023 14:18:08 +0200 Subject: [PATCH 1/6] disallow multiline strings that do not start with newline --- compiler/src/Parse/String.hs | 2 +- compiler/src/Reporting/Error/Syntax.hs | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/compiler/src/Parse/String.hs b/compiler/src/Parse/String.hs index efdc1d532..7da724bd7 100644 --- a/compiler/src/Parse/String.hs +++ b/compiler/src/Parse/String.hs @@ -179,7 +179,7 @@ multiString pos end row col initialPos sr sc = then let !pos1 = plusPtr pos 1 in countLeadingWhiteSpaceThenMultiString 0 pos1 end (row + 1) 1 pos1 sr sc - else countLeadingWhiteSpaceThenMultiString 0 pos end row col initialPos sr sc + else Err sr sc E.StringMultilineWithoutLeadingNewline countLeadingWhiteSpaceThenMultiString :: Int -> Ptr Word8 -> Ptr Word8 -> Row -> Col -> Ptr Word8 -> Row -> Col -> StringResult countLeadingWhiteSpaceThenMultiString count pos end row col initialPos sr sc = diff --git a/compiler/src/Reporting/Error/Syntax.hs b/compiler/src/Reporting/Error/Syntax.hs index e403f9fbf..b0eb52d00 100644 --- a/compiler/src/Reporting/Error/Syntax.hs +++ b/compiler/src/Reporting/Error/Syntax.hs @@ -440,6 +440,7 @@ data String = StringEndless_Single | StringEndless_Multi | StringEscape Escape + | StringMultilineWithoutLeadingNewline deriving (Show) data Escape @@ -2991,6 +2992,31 @@ toStringReport source string row col = ) StringEscape escape -> toEscapeReport source escape row col + StringMultilineWithoutLeadingNewline -> + let region = toRegion row col + in Report.Report "MULTILINE STRING WITHOUT NEWLINE" region [] $ + Code.toSnippet + source + region + Nothing + ( D.reflow "The contents of a multiline sting must start on a new line", + D.stack + [ D.reflow "Add a \"\"\" a new line right after the opening quotes.", + D.toSimpleNote "Here is a valid multi-line string for reference:", + D.dullyellow $ + D.indent 4 $ + D.vcat + [ "\"\"\"", + "# Multi-line Strings", + "", + "- start with triple double quotes", + "- write whatever you want", + "- no need to escape newlines or double quotes", + "- end with triple double quotes", + "\"\"\"" + ] + ] + ) -- ESCAPES From a8514bd7d79aac1f0f4adb854a20dc716dea6a68 Mon Sep 17 00:00:00 2001 From: Gaute Berge Date: Wed, 25 Oct 2023 14:29:32 +0200 Subject: [PATCH 2/6] reuse valid multiline string example --- compiler/src/Reporting/Error/Syntax.hs | 52 ++++++++------------------ 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/compiler/src/Reporting/Error/Syntax.hs b/compiler/src/Reporting/Error/Syntax.hs index b0eb52d00..bcc334fb5 100644 --- a/compiler/src/Reporting/Error/Syntax.hs +++ b/compiler/src/Reporting/Error/Syntax.hs @@ -2949,18 +2949,7 @@ toStringReport source string row col = D.toSimpleNote $ "For a string that spans multiple lines, you can use the multi-line string\ \ syntax like this:", - D.dullyellow $ - D.indent 4 $ - D.vcat $ - [ "\"\"\"", - "# Multi-line Strings", - "", - "- start with triple double quotes", - "- write whatever you want", - "- no need to escape newlines or double quotes", - "- end with triple double quotes", - "\"\"\"" - ] + D.dullyellow $ D.indent 3 validMultilineStringExample ] ) StringEndless_Multi -> @@ -2976,18 +2965,7 @@ toStringReport source string row col = [ D.reflow "Add a \"\"\" somewhere after this to end the string.", D.toSimpleNote $ "Here is a valid multi-line string for reference:", - D.dullyellow $ - D.indent 4 $ - D.vcat $ - [ "\"\"\"", - "# Multi-line Strings", - "", - "- start with triple double quotes", - "- write whatever you want", - "- no need to escape newlines or double quotes", - "- end with triple double quotes", - "\"\"\"" - ] + D.dullyellow $ D.indent 4 validMultilineStringExample ] ) StringEscape escape -> @@ -3003,21 +2981,23 @@ toStringReport source string row col = D.stack [ D.reflow "Add a \"\"\" a new line right after the opening quotes.", D.toSimpleNote "Here is a valid multi-line string for reference:", - D.dullyellow $ - D.indent 4 $ - D.vcat - [ "\"\"\"", - "# Multi-line Strings", - "", - "- start with triple double quotes", - "- write whatever you want", - "- no need to escape newlines or double quotes", - "- end with triple double quotes", - "\"\"\"" - ] + D.dullyellow $ D.indent 4 validMultilineStringExample ] ) +validMultilineStringExample :: D.Doc +validMultilineStringExample = + D.vcat + [ "\"\"\"", + "# Multi-line Strings", + "", + "- start with triple double quotes", + "- write whatever you want", + "- no need to escape newlines or double quotes", + "- end with triple double quotes", + "\"\"\"" + ] + -- ESCAPES toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report From dda71684bb4e5542151c0953003666385ed16a2c Mon Sep 17 00:00:00 2001 From: Gaute Berge Date: Wed, 25 Oct 2023 15:41:53 +0200 Subject: [PATCH 3/6] test for dissalow multiline string without newline --- compiler/src/Reporting/Error/Syntax.hs | 5 ++++- tests/Parse/MultilineStringSpec.hs | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/compiler/src/Reporting/Error/Syntax.hs b/compiler/src/Reporting/Error/Syntax.hs index bcc334fb5..1ed2cf5c2 100644 --- a/compiler/src/Reporting/Error/Syntax.hs +++ b/compiler/src/Reporting/Error/Syntax.hs @@ -196,7 +196,8 @@ data CustomType -- EXPRESSIONS data Expr - = Let Let Row Col + = ExpressionBadEnd Row Col + | Let Let Row Col | Case Case Row Col | If If Row Col | Parenthesized Parenthesized Row Col @@ -2598,6 +2599,8 @@ isWithin desiredNode context = toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report toExprReport source context expr startRow startCol = case expr of + ExpressionBadEnd row col -> + toWeirdEndReport source row col Let let_ row col -> toLetReport source context let_ row col Case case_ row col -> diff --git a/tests/Parse/MultilineStringSpec.hs b/tests/Parse/MultilineStringSpec.hs index f1b30ba10..64887504b 100644 --- a/tests/Parse/MultilineStringSpec.hs +++ b/tests/Parse/MultilineStringSpec.hs @@ -7,9 +7,14 @@ import Data.ByteString qualified as BS import Data.Utf8 qualified as Utf8 import Helpers.Instances () import Helpers.Parse qualified as Helpers +import Parse.Expression qualified as Expression import Parse.Pattern qualified as Pattern +import Parse.Primitives qualified as P +import Repl (Input (Help)) +import Reporting.Error.Syntax (Expr (ExpressionBadEnd)) import Reporting.Error.Syntax qualified as Error.Syntax import Test.Hspec (Spec, describe, it) +import Test.Hspec qualified as Hspec spec :: Spec spec = do @@ -17,12 +22,12 @@ spec = do it "regression test" $ parse "normal string" - "\"\"\"normal string\"\"\"" + "\"\"\"\nnormal string\"\"\"" it "mixing quotes work" $ do parse "string with \" in it" - "\"\"\"string with \" in it\"\"\"" + "\"\"\"\nstring with \" in it\"\"\"" it "first newline, and leading whitespace, is dropped" $ do parse @@ -39,6 +44,11 @@ spec = do "this is\\na test" "\"\"\"\n this is\n a test\n\"\"\"" + it "does not allow non-newline characters on the first line" $ do + let isCorrectError ((Error.Syntax.String Error.Syntax.StringMultilineWithoutLeadingNewline _ _)) = True + isCorrectError _ = False + Helpers.checkParseError Expression.expression ExpressionBadEnd isCorrectError "\"\"\"this is not allowed\"\"\"" + parse :: String -> BS.ByteString -> IO () parse expectedStr = let isExpectedString :: Src.Pattern_ -> Bool From 68fd3f1f39efbc569dbbce11c09fbd2e277318ab Mon Sep 17 00:00:00 2001 From: Gaute Berge Date: Thu, 26 Oct 2023 09:21:49 +0200 Subject: [PATCH 4/6] typo: *LEADING* NEWLINE --- compiler/src/Reporting/Error/Syntax.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/Reporting/Error/Syntax.hs b/compiler/src/Reporting/Error/Syntax.hs index 1ed2cf5c2..5db10e526 100644 --- a/compiler/src/Reporting/Error/Syntax.hs +++ b/compiler/src/Reporting/Error/Syntax.hs @@ -2975,7 +2975,7 @@ toStringReport source string row col = toEscapeReport source escape row col StringMultilineWithoutLeadingNewline -> let region = toRegion row col - in Report.Report "MULTILINE STRING WITHOUT NEWLINE" region [] $ + in Report.Report "MULTILINE STRING WITHOUT LEADING NEWLINE" region [] $ Code.toSnippet source region From 9ba7e7c9d46fc424a7885ef9568b8c13ab47d6b9 Mon Sep 17 00:00:00 2001 From: Gaute Berge Date: Thu, 26 Oct 2023 10:03:42 +0200 Subject: [PATCH 5/6] fix unused arguments --- compiler/src/Parse/String.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/Parse/String.hs b/compiler/src/Parse/String.hs index 7da724bd7..84d601505 100644 --- a/compiler/src/Parse/String.hs +++ b/compiler/src/Parse/String.hs @@ -170,7 +170,7 @@ singleString pos end row col initialPos revChunks = -- MULTI STRINGS multiString :: Ptr Word8 -> Ptr Word8 -> Row -> Col -> Ptr Word8 -> Row -> Col -> StringResult -multiString pos end row col initialPos sr sc = +multiString pos end row _ _ sr sc = if pos >= end then Err sr sc E.StringEndless_Multi else From acb93f0bf4430c5eed8e9f50402a90bb4d09df6b Mon Sep 17 00:00:00 2001 From: Gaute Berge Date: Thu, 26 Oct 2023 10:06:01 +0200 Subject: [PATCH 6/6] remove unused imports --- tests/Parse/MultilineStringSpec.hs | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Parse/MultilineStringSpec.hs b/tests/Parse/MultilineStringSpec.hs index 64887504b..a4daef731 100644 --- a/tests/Parse/MultilineStringSpec.hs +++ b/tests/Parse/MultilineStringSpec.hs @@ -9,12 +9,9 @@ import Helpers.Instances () import Helpers.Parse qualified as Helpers import Parse.Expression qualified as Expression import Parse.Pattern qualified as Pattern -import Parse.Primitives qualified as P -import Repl (Input (Help)) import Reporting.Error.Syntax (Expr (ExpressionBadEnd)) import Reporting.Error.Syntax qualified as Error.Syntax import Test.Hspec (Spec, describe, it) -import Test.Hspec qualified as Hspec spec :: Spec spec = do