Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No multiline string without newline #232

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/src/Parse/String.hs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
-- MULTI STRINGS

multiString :: Ptr Word8 -> Ptr Word8 -> Row -> Col -> Ptr Word8 -> Row -> Col -> StringResult
multiString pos end row col initialPos sr sc =

Check failure on line 173 in compiler/src/Parse/String.hs

View workflow job for this annotation

GitHub Actions / windows

Defined but not used: ‘col’

Check failure on line 173 in compiler/src/Parse/String.hs

View workflow job for this annotation

GitHub Actions / windows

Defined but not used: ‘initialPos’

Check failure on line 173 in compiler/src/Parse/String.hs

View workflow job for this annotation

GitHub Actions / windows

Defined but not used: ‘col’

Check failure on line 173 in compiler/src/Parse/String.hs

View workflow job for this annotation

GitHub Actions / windows

Defined but not used: ‘initialPos’

Check failure on line 173 in compiler/src/Parse/String.hs

View workflow job for this annotation

GitHub Actions / mac

Defined but not used: ‘col’

Check failure on line 173 in compiler/src/Parse/String.hs

View workflow job for this annotation

GitHub Actions / mac

Defined but not used: ‘initialPos’

Check failure on line 173 in compiler/src/Parse/String.hs

View workflow job for this annotation

GitHub Actions / mac

Defined but not used: ‘col’

Check failure on line 173 in compiler/src/Parse/String.hs

View workflow job for this annotation

GitHub Actions / mac

Defined but not used: ‘initialPos’
if pos >= end
then Err sr sc E.StringEndless_Multi
else
Expand All @@ -179,7 +179,7 @@
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 =
Expand Down
59 changes: 34 additions & 25 deletions compiler/src/Reporting/Error/Syntax.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -440,6 +441,7 @@ data String
= StringEndless_Single
| StringEndless_Multi
| StringEscape Escape
| StringMultilineWithoutLeadingNewline
deriving (Show)

data Escape
Expand Down Expand Up @@ -2597,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 ->
Expand Down Expand Up @@ -2948,18 +2952,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 ->
Expand All @@ -2975,22 +2968,38 @@ 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 ->
toEscapeReport source escape row col
StringMultilineWithoutLeadingNewline ->
let region = toRegion row col
in Report.Report "MULTILINE STRING WITHOUT NEWLINE" region [] $
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without LEADING newline, perhaps? 🤔

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 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

Expand Down
14 changes: 12 additions & 2 deletions tests/Parse/MultilineStringSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,27 @@ 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
describe "Multiline String" $ 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
Expand All @@ -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
Expand Down
Loading