This repository was archived by the owner on Jun 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
Add support for tagged template strings #471
Closed
kevinbarabash
wants to merge
9
commits into
rescript-lang:master
from
kevinbarabash:tagged-template-strings
Closed
Changes from 1 commit
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
2efb5b0
Add support for tagged template strings [WIP]
kevinbarabash 2985c6c
move location of printTaggedTemplateLiteral, inline some helper funct…
kevinbarabash e1cd14d
Add parsing test for tagged template with interpolations, add locatio…
kevinbarabash 6a8dc57
make helper functions taill-recursive
kevinbarabash 7e97d58
remove commented out code
kevinbarabash b2a4607
replace if-else at the end of parseTemplateExpr with match
kevinbarabash 1bcd144
reorganize the code in parseTemplateExpr a bit more
kevinbarabash b9e490b
remove extra new line when printing tagged template literals
kevinbarabash 6e489d1
convert ocamlString.ml test to .res
kevinbarabash File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,12 @@ let mkLoc startLoc endLoc = Location.{ | |
loc_ghost = false; | ||
} | ||
|
||
let rec filter_map xs (f : 'a -> 'b option) = | ||
match xs with | ||
| [] -> [] | ||
| y :: ys -> ( | ||
match f y with None -> filter_map ys f | Some z -> z :: filter_map ys f) | ||
|
||
module Recover = struct | ||
let defaultExpr () = | ||
let id = Location.mknoloc "rescript.exprhole" in | ||
|
@@ -137,6 +143,7 @@ let ifLetAttr = (Location.mknoloc "ns.iflet", Parsetree.PStr []) | |
let suppressFragileMatchWarningAttr = (Location.mknoloc "warning", Parsetree.PStr [Ast_helper.Str.eval (Ast_helper.Exp.constant (Pconst_string ("-4", None)))]) | ||
let makeBracesAttr loc = (Location.mkloc "ns.braces" loc, Parsetree.PStr []) | ||
let templateLiteralAttr = (Location.mknoloc "res.template", Parsetree.PStr []) | ||
let taggedTemplateLiteralAttr = (Location.mknoloc "res.taggedTemplate", Parsetree.PStr []) | ||
|
||
type stringLiteralState = | ||
| Start | ||
|
@@ -2217,6 +2224,85 @@ and parseBinaryExpr ?(context=OrdinaryExpr) ?a p prec = | |
(* ) *) | ||
|
||
and parseTemplateExpr ?(prefix="js") p = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's best to review the changes to this function using the split view and ignore the left side completely as if its contents have been completely replaced. |
||
(* TODO: include the location in the parts *) | ||
let partPrefix = if prefix = "js" || prefix = "j" then Some(prefix) else None in | ||
kevinbarabash marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
let rec parseParts p = | ||
let startPos = p.Parser.startPos in | ||
Parser.nextTemplateLiteralToken p; | ||
match p.token with | ||
| TemplateTail txt -> | ||
Parser.next p; | ||
let loc = mkLoc startPos p.prevEndPos in | ||
let txt = if p.mode = ParseForTypeChecker then parseTemplateStringLiteral txt else txt in | ||
let str = Ast_helper.Exp.constant ~attrs:[templateLiteralAttr] ~loc (Pconst_string(txt, partPrefix)) in | ||
(* Ast_helper.Exp.apply ~attrs:[templateLiteralAttr] ~loc hiddenOperator *) | ||
[(str, None)] | ||
| TemplatePart txt -> | ||
Parser.next p; | ||
let loc = mkLoc startPos p.prevEndPos in | ||
let expr = parseExprBlock p in | ||
(* let fullLoc = mkLoc startPos p.prevEndPos in *) | ||
let txt = if p.mode = ParseForTypeChecker then parseTemplateStringLiteral txt else txt in | ||
let str = Ast_helper.Exp.constant ~attrs:[templateLiteralAttr] ~loc (Pconst_string(txt, partPrefix)) in | ||
(* let next = | ||
let a = Ast_helper.Exp.apply ~attrs:[templateLiteralAttr] ~loc:fullLoc hiddenOperator [Nolabel, acc; Nolabel, str] in | ||
Ast_helper.Exp.apply ~loc:fullLoc hiddenOperator | ||
[Nolabel, a; Nolabel, expr] | ||
in *) | ||
let next = parseParts p in | ||
(str, Some(expr)) :: next | ||
| token -> | ||
Parser.err p (Diagnostics.unexpected token p.breadcrumbs); | ||
(* Ast_helper.Exp.constant (Pconst_string("", None)) *) | ||
[] | ||
in | ||
let parts = parseParts p in | ||
let strings = List.map fst parts in | ||
let values = filter_map parts snd in | ||
kevinbarabash marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
let genTaggedTemplateCall () = | ||
let lident = Longident.Lident prefix in | ||
let ident = Ast_helper.Exp.ident ~attrs:[] ~loc:Location.none (Location.mknoloc lident) in | ||
let strings_array = Ast_helper.Exp.array ~attrs:[] ~loc:Location.none strings in | ||
let values_array = Ast_helper.Exp.array ~attrs:[] ~loc:Location.none values in | ||
Ast_helper.Exp.apply | ||
~attrs:[taggedTemplateLiteralAttr] | ||
~loc:Location.none ident | ||
[(Nolabel, strings_array); (Nolabel, values_array)] | ||
in | ||
|
||
let hiddenOperator = | ||
let op = Location.mknoloc (Longident.Lident "^") in | ||
Ast_helper.Exp.ident op | ||
in | ||
let genInterpolatedString () = | ||
let fn acc part = | ||
let (str, value) = part in | ||
let loc = Location.none in | ||
let next = match acc with | ||
| Some(expr) -> Ast_helper.Exp.apply ~attrs:[templateLiteralAttr] ~loc hiddenOperator | ||
[Nolabel, expr; Nolabel, str] | ||
| None -> str | ||
in | ||
let result = match value with | ||
| Some(expr) -> Ast_helper.Exp.apply ~attrs:[templateLiteralAttr] ~loc hiddenOperator | ||
[Nolabel, next; Nolabel, expr] | ||
| None -> next | ||
in | ||
Some(result) | ||
in | ||
List.fold_left fn None parts | ||
in | ||
|
||
if prefix = "js" || prefix = "j" then | ||
match genInterpolatedString () with | ||
| Some(expr) -> expr | ||
| None -> Ast_helper.Exp.constant (Pconst_string("", None)) | ||
else | ||
genTaggedTemplateCall (); | ||
|
||
(* and parseTemplateExpr ?(prefix="js") p = | ||
let hiddenOperator = | ||
let op = Location.mknoloc (Longident.Lident "^") in | ||
Ast_helper.Exp.ident op | ||
|
@@ -2269,7 +2355,7 @@ and parseTemplateExpr ?(prefix="js") p = | |
parseParts next | ||
| token -> | ||
Parser.err p (Diagnostics.unexpected token p.breadcrumbs); | ||
Ast_helper.Exp.constant (Pconst_string("", None)) | ||
Ast_helper.Exp.constant (Pconst_string("", None)) *) | ||
|
||
(* Overparse: let f = a : int => a + 1, is it (a : int) => or (a): int => | ||
* Also overparse constraints: | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.