Skip to content

Commit c2c45b7

Browse files
aaronjanseWarry
authored andcommitted
implement char escapes (elm-in-elm#20)
1 parent 1488ea8 commit c2c45b7

File tree

4 files changed

+100
-15
lines changed

4 files changed

+100
-15
lines changed

README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ Oh God please yes! :heart: Feel free to look around the [<kbd>help wanted</kbd>]
7272
| ----------------- | -------------------- | -------------------- | ------------------ | ------------------ | -------------------- | ------------------ | ------------------ |
7373
| integers | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :warning: [[2]](#f2) | :heavy_check_mark: | :heavy_check_mark: |
7474
| floats | :x: [[3]](#f3) | :x: [[4]](#f4) | :x: [[3]](#f3) | :x: [[3]](#f3) | :x: [[5]](#f5) | :x: [[3]](#f3) | :x: [[3]](#f3) |
75-
| characters | :warning: [[6]](#f6) | :warning: [[7]](#f7) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
76-
| strings | :warning: [[8]](#f8) | :warning: [[9]](#f9) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
75+
| characters | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
76+
| strings | :warning: [[6]](#f6) | :warning: [[7]](#f7) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
7777
| booleans | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
7878
| variables | :warning: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :warning: | :heavy_check_mark: | :heavy_check_mark: |
7979
| lists | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
@@ -98,10 +98,8 @@ Oh God please yes! :heart: Feel free to look around the [<kbd>help wanted</kbd>]
9898
3. <span id="f3"></span> Not implemented; tracked in [#17](https://github.com/elm-in-elm/compiler/issues/17)
9999
4. <span id="f4"></span> Not implemented; not tracked yet
100100
5. <span id="f5"></span> To be optimized the same way Ints are; not tracked yet
101-
6. <span id="f6"></span> Comprehensive tests missing; will be fixed in [#15](https://github.com/elm-in-elm/compiler/pull/15)
102-
7. <span id="f7"></span> Escape sequences not implemented; not tracked yet
103-
8. <span id="f8"></span> Comprehensive tests missing; tracked in [#21](https://github.com/elm-in-elm/compiler/issues/21)
104-
9. <span id="f9"></span> Multiline strings (and maybe more) missing; not tracked yet
101+
6. <span id="f6"></span> Comprehensive tests missing; not tracked yet
102+
7. <span id="f7"></span> Multiline strings (and maybe more) missing; not tracked yet
105103

106104
## Prerequisites
107105

@@ -234,6 +232,12 @@ Make sure to format code before submitting a pull request!
234232
</br>
235233
<a href="https://github.com/Warry">Maxime Dantec</a>
236234
</td>
235+
<td align="center">
236+
<img width="150" height="150"
237+
src="https://avatars0.githubusercontent.com/u/16829510">
238+
</br>
239+
<a href="https://github.com/aaronjanse">Aaron Janse</a>
240+
</td>
237241
</tr>
238242
<tbody>
239243
</table>

src/compiler/Error.elm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ type ParseProblem
8080
| ExpectingInt
8181
| ExpectingSingleQuote
8282
| ExpectingChar
83+
| ExpectingEscapeBackslash
84+
| ExpectingEscapeCharacter Char
85+
| ExpectingUnicodeEscapeLeftBrace
86+
| ExpectingUnicodeEscapeRightBrace
87+
| InvalidUnicodeCodePoint
8388
| ExpectingDoubleQuote
8489
| ExpectingPlusOperator
8590
| ExpectingModuleDot -- `import Foo>.<Bar`

src/compiler/Stage/Parse/Parser.elm

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -428,22 +428,67 @@ literalInt =
428428
|> P.inContext InLiteralInt
429429

430430

431-
{-| TODO escapes
432-
TODO Unicode escapes
433-
-}
431+
432+
-- for literalChar and, in the future, literalString
433+
434+
435+
character =
436+
P.oneOf
437+
[ P.succeed identity
438+
|. P.token (P.Token "\\" ExpectingEscapeBackslash)
439+
|= P.oneOf
440+
[ P.map (\_ -> '"') (P.token (P.Token "\"" (ExpectingEscapeCharacter '"'))) -- " (elm-vscode workaround)
441+
, P.map (\_ -> '\'') (P.token (P.Token "'" (ExpectingEscapeCharacter '\'')))
442+
, P.map (\_ -> '\n') (P.token (P.Token "n" (ExpectingEscapeCharacter 'n')))
443+
, P.map (\_ -> '\t') (P.token (P.Token "t" (ExpectingEscapeCharacter 't')))
444+
, P.map (\_ -> '\u{000D}') (P.token (P.Token "r" (ExpectingEscapeCharacter 'r')))
445+
, P.succeed identity
446+
|. P.token (P.Token "u" (ExpectingEscapeCharacter 'u'))
447+
|. P.token (P.Token "{" ExpectingUnicodeEscapeLeftBrace)
448+
|= unicode
449+
|. P.token (P.Token "}" ExpectingUnicodeEscapeRightBrace)
450+
]
451+
, P.succeed identity
452+
|= P.getChompedString (P.chompIf (always True) ExpectingChar)
453+
|> P.andThen
454+
(\string ->
455+
string
456+
|> String.uncons
457+
|> Maybe.map (Tuple.first >> P.succeed)
458+
|> Maybe.withDefault (P.problem (CompilerBug "Multiple characters chomped in `character`"))
459+
)
460+
]
461+
462+
434463
literalChar : Parser_ Literal
435464
literalChar =
436465
(P.succeed identity
437466
|. P.symbol (P.Token "'" ExpectingSingleQuote)
438-
|= P.getChompedString (P.chompIf (always True) ExpectingChar)
467+
|= character
439468
|. P.symbol (P.Token "'" ExpectingSingleQuote)
440469
)
470+
|> P.map Char
471+
472+
473+
unicode : Parser_ Char
474+
unicode =
475+
P.getChompedString (P.chompWhile Char.isHexDigit)
441476
|> P.andThen
442-
(\string ->
443-
string
444-
|> String.uncons
445-
|> Maybe.map (Tuple.first >> Char >> P.succeed)
446-
|> Maybe.withDefault (P.problem (CompilerBug "Multiple characters chomped in `literalChar`"))
477+
(\str ->
478+
let
479+
len =
480+
String.length str
481+
in
482+
if len < 4 || len > 6 then
483+
P.problem InvalidUnicodeCodePoint
484+
485+
else
486+
str
487+
|> String.toLower
488+
|> Hex.fromString
489+
|> Result.map Char.fromCode
490+
|> Result.map P.succeed
491+
|> Result.withDefault (P.problem InvalidUnicodeCodePoint)
447492
)
448493

449494

tests/ParserTest.elm

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,37 @@ expr =
555555
, "'A'"
556556
, Ok (Literal (Char 'A'))
557557
)
558+
559+
-- https://github.com/elm/compiler/blob/dcbe51fa22879f83b5d94642e117440cb5249bb1/compiler/src/Parse/String.hs#L279-L285
560+
, ( "escape n"
561+
, "'\\n'"
562+
, Ok (Literal (Char '\n'))
563+
)
564+
, ( "escape r"
565+
, "'\\r'"
566+
, Ok (Literal (Char '\u{000D}'))
567+
)
568+
, ( "escape t"
569+
, "'\\t'"
570+
, Ok (Literal (Char '\t'))
571+
)
572+
, ( "double quote"
573+
, "'\\\"'"
574+
, Ok (Literal (Char '"'))
575+
-- " (for vscode-elm bug)
576+
)
577+
, ( "single quote"
578+
, "'\\''"
579+
, Ok (Literal (Char '\''))
580+
)
581+
, ( "emoji"
582+
, "'😃'"
583+
, Ok (Literal (Char '😃'))
584+
)
585+
, ( "escaped unicode code point"
586+
, "'\\u{1F648}'"
587+
, Ok (Literal (Char '🙈'))
588+
)
558589
]
559590
)
560591
, ( "literal string"

0 commit comments

Comments
 (0)