Skip to content

Commit 05902ea

Browse files
committed
Started implementing multi-line strings
1 parent a6e8428 commit 05902ea

File tree

2 files changed

+49
-8
lines changed

2 files changed

+49
-8
lines changed

src/Parse/String.gren

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type Error
1616
| ExpectedUnicodeOpening
1717
| ExpectedValidUnicode
1818
| ExpectedUnicodeClosing
19+
| ExpectedNewline
1920

2021

2122
char : Parser c Error Char
@@ -86,30 +87,53 @@ charQuote =
8687
Parser.Token { str = "\'", expecting = ExpectedQuote }
8788

8889

89-
strQuote : Parser.Token Error
90-
strQuote =
90+
singleLineStrQuote : Parser.Token Error
91+
singleLineStrQuote =
9192
Parser.Token { str = "\"", expecting = ExpectedQuote }
9293

9394

95+
multiLineStrQuote : Parser.Token Error
96+
multiLineStrQuote =
97+
Parser.Token { str = "\"\"\"", expecting = ExpectedQuote }
98+
99+
94100
unicodeOpening : Parser.Token Error
95101
unicodeOpening =
96102
Parser.Token { str = "u{", expecting = ExpectedUnicodeOpening }
97103

98104

105+
crlf : Parser.Token Error
106+
crlf =
107+
Parser.Token { str = "\r\n", expecting = ExpectedNewline }
108+
99109

100110
string : Parser c Error String
101111
string =
102-
Parser.succeed identity
103-
|> Parser.skip (Parser.symbol strQuote)
104-
|> Parser.keep (Parser.loop "" stringHelp)
112+
Parser.oneOf
113+
[ Parser.succeed identity
114+
|> Parser.skip (Parser.symbol multiLineStrQuote)
115+
|> Parser.skip
116+
(Parser.oneOf
117+
[ Parser.chompIf (\c -> c == '\n') ExpectedNewline
118+
, Parser.symbol crlf
119+
]
120+
)
121+
|> Parser.keep (Parser.loop "" (innerSingleLineString multiLineStrQuote))
122+
|> Parser.map String.trimRight
123+
, Parser.succeed identity
124+
|> Parser.skip (Parser.symbol singleLineStrQuote)
125+
|> Parser.keep (Parser.loop "" (innerSingleLineString singleLineStrQuote))
126+
]
105127

106128

107-
stringHelp : String -> Parser c Error (Parser.Step String String)
108-
stringHelp str =
129+
innerSingleLineString : Parser.Token Error -> String -> Parser c Error (Parser.Step String String)
130+
innerSingleLineString endToken str =
109131
Parser.oneOf
110132
[ Parser.succeed {}
111-
|> Parser.skip (Parser.symbol strQuote)
133+
|> Parser.skip (Parser.symbol endToken)
112134
|> Parser.map (\_ -> Parser.Done str)
135+
, Parser.succeed (\_ -> Parser.Loop (String.pushLast '\n' str))
136+
|> Parser.keep (Parser.symbol crlf)
113137
, Parser.succeed (\chr -> Parser.Loop (String.pushLast chr str))
114138
|> Parser.keep coreParser
115139
]

tests/src/Test/Parse/String.gren

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,23 @@ tests =
6363
, test "Example with surrogate pair" <| \_ ->
6464
Parser.run PS.string "\"this is a \\\" Test 𤭢 -String_\""
6565
|> Expect.equal (Ok "this is a \" Test 𤭢 -String_")
66+
, test "crlf is normalized to lf" <| \_ ->
67+
Parser.run PS.string "\"\r\n\""
68+
|> Expect.equal (Ok "\n")
69+
]
70+
, describe "Multi-line Strings"
71+
[ test "Simple case" <| \_ ->
72+
Parser.run PS.string "\"\"\"\nnormal string\"\"\""
73+
|> Expect.equal (Ok "normal string")
74+
, test "Simple case with crlf" <| \_ ->
75+
Parser.run PS.string "\"\"\"\r\nnormal string\"\"\""
76+
|> Expect.equal (Ok "normal string")
77+
, test "crlf works in general" <| \_ ->
78+
Parser.run PS.string "\"\"\"\r\nstring \r\n with crlf\"\"\""
79+
|> Expect.equal (Ok "string \n with crlf")
80+
, test "Final newline is dropped" <| \_ ->
81+
Parser.run PS.string "\"\"\"\nnormal string\n\"\"\""
82+
|> Expect.equal (Ok "normal string")
6683
]
6784
]
6885

0 commit comments

Comments
 (0)