diff --git a/src/compiler/tests/literals.test.ts b/src/compiler/tests/literals.test.ts index 3a2905f..96830cf 100644 --- a/src/compiler/tests/literals.test.ts +++ b/src/compiler/tests/literals.test.ts @@ -238,3 +238,24 @@ describe('curly strings', () => { expect(`a = 1;b = 2;c = 3;{$a$b$c}`).toEvaluateTo(`123`) }) }) + +describe('double quoted strings', () => { + test("work", () => { + expect(`"hello world"`).toEvaluateTo('hello world') + }) + + test("don't interpolate", () => { + expect(`"hello $world"`).toEvaluateTo('hello $world') + expect(`"hello $(1 + 2)"`).toEvaluateTo('hello $(1 + 2)') + }) + + test("equal regular strings", () => { + expect(`"hello world" == 'hello world'`).toEvaluateTo(true) + }) + + test("can contain newlines", () => { + expect(` + "hello + world"`).toEvaluateTo('hello\n world') + }) +}) \ No newline at end of file diff --git a/src/parser/shrimp.grammar b/src/parser/shrimp.grammar index 01d82ab..c01fd18 100644 --- a/src/parser/shrimp.grammar +++ b/src/parser/shrimp.grammar @@ -12,6 +12,7 @@ @precedence { Number Regex } StringFragment { !['\\$]+ } + DoubleQuote { '"' !["]* '"' } NamedArgPrefix { $[a-z] $[a-z0-9-]* "=" } Number { ("-" | "+")? "0x" $[0-9a-fA-F]+ | @@ -234,7 +235,7 @@ expression { } String { - "'" stringContent* "'" | CurlyString + "'" stringContent* "'" | CurlyString | DoubleQuote } } diff --git a/src/parser/shrimp.terms.ts b/src/parser/shrimp.terms.ts index fc03a61..0f49afe 100644 --- a/src/parser/shrimp.terms.ts +++ b/src/parser/shrimp.terms.ts @@ -37,7 +37,7 @@ export const Program = 35, PipeExpr = 36, WhileExpr = 38, - keyword = 80, + keyword = 81, ConditionalOp = 40, ParenExpr = 41, FunctionCallWithNewlines = 42, @@ -52,25 +52,26 @@ export const StringFragment = 51, Interpolation = 52, EscapeSeq = 53, - Boolean = 54, - Null = 55, - colon = 56, - CatchExpr = 57, - Block = 59, - FinallyExpr = 60, - Underscore = 63, - NamedArg = 64, - IfExpr = 65, - FunctionCall = 67, - ElseIfExpr = 68, - ElseExpr = 70, - FunctionCallOrIdentifier = 71, - BinOp = 72, - Regex = 73, - Dict = 74, - Array = 75, - FunctionCallWithBlock = 76, - TryExpr = 77, - Throw = 79, - CompoundAssign = 81, - Assign = 82 + DoubleQuote = 54, + Boolean = 55, + Null = 56, + colon = 57, + CatchExpr = 58, + Block = 60, + FinallyExpr = 61, + Underscore = 64, + NamedArg = 65, + IfExpr = 66, + FunctionCall = 68, + ElseIfExpr = 69, + ElseExpr = 71, + FunctionCallOrIdentifier = 72, + BinOp = 73, + Regex = 74, + Dict = 75, + Array = 76, + FunctionCallWithBlock = 77, + TryExpr = 78, + Throw = 80, + CompoundAssign = 82, + Assign = 83 diff --git a/src/parser/shrimp.ts b/src/parser/shrimp.ts index d7a0ea2..3f09fb1 100644 --- a/src/parser/shrimp.ts +++ b/src/parser/shrimp.ts @@ -4,24 +4,24 @@ import {operatorTokenizer} from "./operatorTokenizer" import {tokenizer, specializeKeyword} from "./tokenizer" import {trackScope} from "./parserScopeContext" import {highlighting} from "./highlight" -const spec_Identifier = {__proto__:null,while:78, null:110, catch:116, finally:122, end:124, if:132, else:138, try:156, throw:160} +const spec_Identifier = {__proto__:null,while:78, null:112, catch:118, finally:124, end:126, if:134, else:140, try:158, throw:162} export const parser = LRParser.deserialize({ version: 14, - states: "TQcO,5:iO?cQcO,5:iO@PQcO,5:iOOQa1G/_1G/_OOOO,59|,59|OOOO,59},59}OOOO-E8U-E8UOOQa1G/f1G/fOOQ`,5:Y,5:YOOQ`-E8X-E8XOOQa1G/|1G/|OA{QcO1G/|OBVQcO1G/|OCeQcO1G/|OCoQcO1G/|OC|QcO1G/|OOQa1G/[1G/[OE_QcO1G/[OEfQcO1G/[OEmQcO1G/[OFlQcO1G/[OEtQcO1G/[OOQ`-E8R-E8ROGSQRO1G/]OG^QQO1G/]OGcQQO1G/]OGkQQO1G/]OGvQRO1G/]OG}QRO1G/]OHUQbO,59rOH`QQO1G/]OOQa1G/]1G/]OHhQQO1G0OOOQa1G0P1G0POHsQbO1G0POOQO'#E]'#E]OHhQQO1G0OOOQa1G0O1G0OOOQ`'#E^'#E^OHsQbO1G0POH}QbO1G0WOIiQbO1G0VOJTQbO'#DiOJfQbO'#DiOJyQbO1G0QOOQ`-E8Q-E8QOOQ`,5:n,5:nOOQ`-E8S-E8SOKUQQO,59wOOQO,59x,59xOOQO-E8T-E8TOK^QbO1G/bO:SQbO1G/uO:SQbO1G/YOKeQbO1G0ROKpQQO7+$wOOQa7+$w7+$wOKxQQO1G/^OLQQQO7+%jOOQa7+%j7+%jOL]QbO7+%kOOQa7+%k7+%kOOQO-E8Z-E8ZOOQ`-E8[-E8[OOQ`'#EX'#EXOLgQQO'#EXOLoQbO'#EqOOQ`,5:T,5:TOMSQbO'#DgOMXQQO'#DjOOQ`7+%l7+%lOM^QbO7+%lOMcQbO7+%lOMkQbO7+$|OMyQbO7+$|ONZQbO7+%aONcQbO7+$tOOQ`7+%m7+%mONhQbO7+%mONmQbO7+%mOOQa<rAN>rOOQ`AN>SAN>SO!!wQbOAN>SO!!|QbOAN>SOOQ`-E8Y-E8YOOQ`AN>gAN>gO!#UQbOAN>gO2dQbO,5:^O:SQbO,5:`OOQ`AN>sAN>sPHUQbO'#ETOOQ`7+%X7+%XOOQ`G23nG23nO!#ZQbOG23nP!!ZQbO'#DrOOQ`G24RG24RO!#`QQO1G/xOOQ`1G/z1G/zOOQ`LD)YLD)YO:SQbO7+%dOOQ`<qOT!OOU!POj!QOu!qa#Z!qa#l!qa![!qa!_!qa!`!qa#h!qa!g!qa~O^yOR!jiS!jid!jie!jif!jig!jih!jii!jiu!ji#Z!ji#l!ji#h!ji![!ji!_!ji!`!ji!g!ji~OP!jiQ!ji~P@tOPzOQzO~P@tOPzOQzOd!jie!jif!jig!jih!jii!jiu!ji#Z!ji#l!ji#h!ji![!ji!_!ji!`!ji!g!ji~OR!jiS!ji~PBaOR{OS{O^yO~PBaOR{OS{O~PBaOW}OX}OY}OZ}O[}O]}OTxijxiuxi#Zxi#lxi#hxi!Yxi![xi!_xi!`xi!gxi~OU!PO~PDWOU!PO~PDjOUxi~PDWOT!OOU!POjxiuxi#Zxi#lxi#hxi!Yxi![xi!_xi!`xi!gxi~OW}OX}OY}OZ}O[}O]}O~PEtO#Z!RO#h$RO~P*[O#h$RO~O#h$ROu#VX~O!Y!dO#h$ROu#VX~O#h$RO~P.gO#h$RO~P7mOqgO!asO~P,wO#Z!RO#h$RO~O!RtO#Z#lO#k$UO~O#Z#oO#k$WO~P3[Ou!gO#Z!ti#l!ti![!ti!_!ti!`!ti#h!ti!g!ti~Ou!gO#Z!si#l!si![!si!_!si!`!si#h!si!g!si~Ou!gO![!]X!_!]X!`!]X!g!]X~O#Z$ZO![#eP!_#eP!`#eP!g#eP~P8xO![$_O!_$`O!`$aO~O!R!kO!Y!Pa~O#Z$eO~P8xO![$_O!_$`O!`$hO~O#Z!RO#h$kO~O#Z!RO#hzi~O!RtO#Z#lO#k$nO~O#Z#oO#k$oO~P3[Ou!gO#Z$pO~O#Z$ZO![#eX!_#eX!`#eX!g#eX~P8xOl$rO~O!Y$sO~O!`$tO~O!_$`O!`$tO~Ou!gO![$_O!_$`O!`$vO~O#Z$ZO![#eP!_#eP!`#eP~P8xO!`$}O!g$|O~O!`%PO~O!`%QO~O!_$`O!`%QO~OqgO!asO#hzq~P,wO#Z!RO#hzq~O!Y%VO~O!`%XO~O!`%YO~O!_$`O!`%YO~O![$_O!_$`O!`%YO~O!`%^O!g$|O~O!Y%aO!d%`O~O!`%^O~O!`%bO~OqgO!asO#hzy~P,wO!`%eO~O!_$`O!`%eO~O!`%hO~O!`%kO~O!Y%lO~O|!k~", - goto: "8g#hPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#iP$SP$i%g&u&{P(V(c)])`P)fP*m*mPPP*qP*}+gPPP+}#iP,g-QP-U-[-qP.h/l$S$SP$SP$S$S0r0x1U1x2O2Y2`2g2m2w2}3XPPP3c3g4[6QPPP7[P7lPPPPP7p7v7|raOf!b!c!d!g!v#t#|#}$O$]$e$s%V%a%lQ!XXR#b!SwaOXf!S!b!c!d!g!v#t#|#}$O$]$e$s%V%a%lr_Of!b!c!d!g!v#t#|#}$O$]$e$s%V%a%lQ![XS!ph%`Q!uiQ!ykQ#X!PQ#Z!OQ#^!QR#e!SvTOfh!b!c!d!g!v#t#|#}$O$]$e$s%V%`%a%l!W[STZiktwyz{|}!O!P!Q!T!U!^!a!o#f#k#p$V$l%T%cS!UX!SQ!zlR!{mQ!WXR#a!SrSOf!b!c!d!g!v#t#|#}$O$]$e$s%V%a%l!WxSTZiktwyz{|}!O!P!Q!T!U!^!a!o#f#k#p$V$l%T%cS!TX!ST!oh%`euSTw!T!U!o#f$l%T%craOf!b!c!d!g!v#t#|#}$O$]$e$s%V%a%ldsSTw!T!U!o#f$l%T%cQ!XXQ#PtR#b!SR!ngX!lg!j!m#y#S[OSTXZfhiktwyz{|}!O!P!Q!S!T!U!^!a!b!c!d!g!o!v#f#k#p#t#|#}$O$V$]$e$l$s%T%V%`%a%c%lR#z!kToQqQ$c#uQ$j$PQ$x$dR%[$yQ#u!dQ$P!vQ$f#}Q$g$OQ%W$sQ%d%VQ%j%aR%m%lQ$b#uQ$i$PQ$u$cQ$w$dQ%R$jS%Z$x$yR%f%[duSTw!T!U!o#f$l%T%cQ!_ZQ#i!^X#l!_#i#m$TvUOXf!S!b!c!d!g!v#t#|#}$O$]$e$s%V%a%lT!rh%`T$z$f${Q%O$fR%_${wUOXf!S!b!c!d!g!v#t#|#}$O$]$e$s%V%a%lrWOf!b!c!d!g!v#t#|#}$O$]$e$s%V%a%lQ!VXQ!xkQ#RzQ#U{Q#W|R#`!S#T[OSTXZfhiktwyz{|}!O!P!Q!S!T!U!^!a!b!c!d!g!o!v#f#k#p#t#|#}$O$V$]$e$l$s%T%V%`%a%c%l![[STZhiktwyz{|}!O!P!Q!T!U!^!a!o#f#k#p$V$l%T%`%cw]OXf!S!b!c!d!g!v#t#|#}$O$]$e$s%V%a%lQfOR!hf^!ec!]#q#r#s$[$dR#v!eQ!SXQ!^Z`#_!S!^#f#g$Q$l%T%cS#f!T!US#g!V![S$Q#`#eQ$l$SR%T$mQ!jgR#x!jQ!mgQ#y!jT#{!m#yQqQR!}qS$]#t$eR$q$]Q$m$SR%U$mYwST!T!U!oR#QwQ${$fR%]${Q#m!_Q$T#iT$X#m$TQ#p!aQ$V#kT$Y#p$VTeOfScOfS!]X!SQ#q!bQ#r!c`#s!d!v#}$O$s%V%a%lQ#w!gU$[#t$]$eR$d#|vVOXf!S!b!c!d!g!v#t#|#}$O$]$e$s%V%a%ldsSTw!T!U!o#f$l%T%cQ!aZS!qh%`Q!tiQ!wkQ#PtQ#RyQ#SzQ#T{Q#V|Q#X}Q#Y!OQ#[!PQ#]!QQ#k!^X#o!a#k#p$Vr^Of!b!c!d!g!v#t#|#}$O$]$e$s%V%a%l![xSTZhiktwyz{|}!O!P!Q!T!U!^!a!o#f#k#p$V$l%T%`%cQ!ZXR#d!S[vSTw!T!U!oQ$S#fV%S$l%T%cTpQqQ$^#tR$y$eQ!shR%i%`rbOf!b!c!d!g!v#t#|#}$O$]$e$s%V%a%lQ!YXR#c!S", - nodeNames: "⚠ Star Slash Plus Minus And Or Eq EqEq Neq Lt Lte Gt Gte Modulo PlusEq MinusEq StarEq SlashEq ModuloEq Band Bor Bxor Shl Shr Ushr NullishCoalesce NullishEq Identifier AssignableIdentifier Word IdentifierBeforeDot CurlyString Do Comment Program PipeExpr operator WhileExpr keyword ConditionalOp ParenExpr FunctionCall DotGet Number PositionalArg FunctionDef Params NamedParam NamedArgPrefix String StringFragment Interpolation EscapeSeq Boolean Null colon CatchExpr keyword Block FinallyExpr keyword keyword Underscore NamedArg IfExpr keyword FunctionCall ElseIfExpr keyword ElseExpr FunctionCallOrIdentifier BinOp Regex Dict Array FunctionCallWithBlock TryExpr keyword Throw keyword CompoundAssign Assign", - maxTerm: 120, + states: "UQQO,5:[O>ZQRO,59nO>bQRO,59nO:lQbO,5:hO>pQcO,5:jO@OQcO,5:jO@lQcO,5:jOOQa1G/_1G/_OOOO,59|,59|OOOO,59},59}OOOO-E8V-E8VOOQa1G/f1G/fOOQ`,5:Z,5:ZOOQ`-E8Y-E8YOOQa1G/}1G/}OBhQcO1G/}OBrQcO1G/}ODQQcO1G/}OD[QcO1G/}ODiQcO1G/}OOQa1G/[1G/[OEzQcO1G/[OFRQcO1G/[OFYQcO1G/[OGXQcO1G/[OFaQcO1G/[OOQ`-E8S-E8SOGoQRO1G/]OGyQQO1G/]OHOQQO1G/]OHWQQO1G/]OHcQRO1G/]OHjQRO1G/]OHqQbO,59rOH{QQO1G/]OOQa1G/]1G/]OITQQO1G0POOQa1G0Q1G0QOI`QbO1G0QOOQO'#E^'#E^OITQQO1G0POOQa1G0P1G0POOQ`'#E_'#E_OI`QbO1G0QOIjQbO1G0XOJUQbO1G0WOJpQbO'#DjOKRQbO'#DjOKfQbO1G0ROOQ`-E8R-E8ROOQ`,5:o,5:oOOQ`-E8T-E8TOKqQQO,59wOOQO,59x,59xOOQO-E8U-E8UOKyQbO1G/bO:lQbO1G/vO:lQbO1G/YOLQQbO1G0SOL]QQO7+$wOOQa7+$w7+$wOLeQQO1G/^OLmQQO7+%kOOQa7+%k7+%kOLxQbO7+%lOOQa7+%l7+%lOOQO-E8[-E8[OOQ`-E8]-E8]OOQ`'#EY'#EYOMSQQO'#EYOM[QbO'#ErOOQ`,5:U,5:UOMoQbO'#DhOMtQQO'#DkOOQ`7+%m7+%mOMyQbO7+%mONOQbO7+%mONWQbO7+$|ONfQbO7+$|ONvQbO7+%bO! OQbO7+$tOOQ`7+%n7+%nO! TQbO7+%nO! YQbO7+%nOOQa<sAN>sOOQ`AN>SAN>SO!#dQbOAN>SO!#iQbOAN>SOOQ`-E8Z-E8ZOOQ`AN>hAN>hO!#qQbOAN>hO2sQbO,5:_O:lQbO,5:aOOQ`AN>tAN>tPHqQbO'#EUOOQ`7+%Y7+%YOOQ`G23nG23nO!#vQbOG23nP!!vQbO'#DsOOQ`G24SG24SO!#{QQO1G/yOOQ`1G/{1G/{OOQ`LD)YLD)YO:lQbO7+%eOOQ`<`#Z#be_!TSOt$Ouw$Ox}$O}!Od#S#T$R#T#Y>}#Y#Z@i#Z#b>}#b#cFV#c#f>}#f#gGY#g#h>}#h#iH]#i#o>}#o#p$R#p#qJm#q;'S$R;'S;=`$j<%l~$R~O$R~~KWS$WU!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RS$mP;=`<%l$R^$wU!TS#UYOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU%bU!TS#[QOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU%yZ!TSOr%trs&lst%ttu'Vuw%twx'Vx#O%t#O#P'V#P;'S%t;'S;=`'t<%lO%tU&sU!WQ!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RQ'YTOr'Vrs'is;'S'V;'S;=`'n<%lO'VQ'nO!WQQ'qP;=`<%l'VU'wP;=`<%l%t^(RZrY!TSOY'zYZ$RZt'ztu(tuw'zwx(tx#O'z#O#P(t#P;'S'z;'S;=`)]<%lO'zY(ySrYOY(tZ;'S(t;'S;=`)V<%lO(tY)YP;=`<%l(t^)`P;=`<%l'z~)hO#a~~)mO#_~U)tU!TS#ZQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU*_U!TS#iQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU*vX!TSOt$Ruw$Rx!Q$R!Q!R+c!R![.Q![#O$R#P;'S$R;'S;=`$j<%lO$RU+j`!TS|QOt$Ruw$Rx!O$R!O!P,l!P!Q$R!Q![.Q![#O$R#P#R$R#R#S.}#S#U$R#U#V/l#V#l$R#l#m1Q#m;'S$R;'S;=`$j<%lO$RU,qW!TSOt$Ruw$Rx!Q$R!Q![-Z![#O$R#P;'S$R;'S;=`$j<%lO$RU-bY!TS|QOt$Ruw$Rx!Q$R!Q![-Z![#O$R#P#R$R#R#S,l#S;'S$R;'S;=`$j<%lO$RU.X[!TS|QOt$Ruw$Rx!O$R!O!P,l!P!Q$R!Q![.Q![#O$R#P#R$R#R#S.}#S;'S$R;'S;=`$j<%lO$RU/SW!TSOt$Ruw$Rx!Q$R!Q![.Q![#O$R#P;'S$R;'S;=`$j<%lO$RU/qX!TSOt$Ruw$Rx!Q$R!Q!R0^!R!S0^!S#O$R#P;'S$R;'S;=`$j<%lO$RU0eX!TS|QOt$Ruw$Rx!Q$R!Q!R0^!R!S0^!S#O$R#P;'S$R;'S;=`$j<%lO$RU1V[!TSOt$Ruw$Rx!Q$R!Q![1{![!c$R!c!i1{!i#O$R#P#T$R#T#Z1{#Z;'S$R;'S;=`$j<%lO$RU2S[!TS|QOt$Ruw$Rx!Q$R!Q![1{![!c$R!c!i1{!i#O$R#P#T$R#T#Z1{#Z;'S$R;'S;=`$j<%lO$RU2}W!TSOt$Ruw$Rx!P$R!P!Q3g!Q#O$R#P;'S$R;'S;=`$j<%lO$RU3l^!TSOY4hYZ$RZt4htu5kuw4hwx5kx!P4h!P!Q$R!Q!}4h!}#O:^#O#P7y#P;'S4h;'S;=`;_<%lO4hU4o^!TS!lQOY4hYZ$RZt4htu5kuw4hwx5kx!P4h!P!Q8`!Q!}4h!}#O:^#O#P7y#P;'S4h;'S;=`;_<%lO4hQ5pX!lQOY5kZ!P5k!P!Q6]!Q!}5k!}#O6z#O#P7y#P;'S5k;'S;=`8Y<%lO5kQ6`P!P!Q6cQ6hU!lQ#Z#[6c#]#^6c#a#b6c#g#h6c#i#j6c#m#n6cQ6}VOY6zZ#O6z#O#P7d#P#Q5k#Q;'S6z;'S;=`7s<%lO6zQ7gSOY6zZ;'S6z;'S;=`7s<%lO6zQ7vP;=`<%l6zQ7|SOY5kZ;'S5k;'S;=`8Y<%lO5kQ8]P;=`<%l5kU8eW!TSOt$Ruw$Rx!P$R!P!Q8}!Q#O$R#P;'S$R;'S;=`$j<%lO$RU9Ub!TS!lQOt$Ruw$Rx#O$R#P#Z$R#Z#[8}#[#]$R#]#^8}#^#a$R#a#b8}#b#g$R#g#h8}#h#i$R#i#j8}#j#m$R#m#n8}#n;'S$R;'S;=`$j<%lO$RU:c[!TSOY:^YZ$RZt:^tu6zuw:^wx6zx#O:^#O#P7d#P#Q4h#Q;'S:^;'S;=`;X<%lO:^U;[P;=`<%l:^U;bP;=`<%l4hU;lU!TS!ZQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RUQU#lQ!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU>kU!TS!bQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU?S^!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#o>}#o;'S$R;'S;=`$j<%lO$RU@VU!RQ!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU@n_!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#UAm#U#o>}#o;'S$R;'S;=`$j<%lO$RUAr`!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#`>}#`#aBt#a#o>}#o;'S$R;'S;=`$j<%lO$RUBy`!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#g>}#g#hC{#h#o>}#o;'S$R;'S;=`$j<%lO$RUDQ`!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#X>}#X#YES#Y#o>}#o;'S$R;'S;=`$j<%lO$RUEZ^!XQ!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#o>}#o;'S$R;'S;=`$j<%lO$R^F^^#cW!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#o>}#o;'S$R;'S;=`$j<%lO$R^Ga^#eW!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#o>}#o;'S$R;'S;=`$j<%lO$R^Hd`#dW!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#f>}#f#gIf#g#o>}#o;'S$R;'S;=`$j<%lO$RUIk`!TSOt$Ruw$Rx}$R}!O>}!O!Q$R!Q![>}![!_$R!_!`@O!`#O$R#P#T$R#T#i>}#i#jC{#j#o>}#o;'S$R;'S;=`$j<%lO$RUJtUuQ!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$R~K]O#m~", + tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup("[~RP!O!PU~ZO#]~~", 11)], topRules: {"Program":[0,35]}, specialized: [{term: 28, get: (value: any, stack: any) => (specializeKeyword(value, stack) << 1), external: specializeKeyword},{term: 28, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}], - tokenPrec: 2229 + tokenPrec: 2256 }) diff --git a/src/parser/tests/strings.test.ts b/src/parser/tests/strings.test.ts index 22f780b..7b4a672 100644 --- a/src/parser/tests/strings.test.ts +++ b/src/parser/tests/strings.test.ts @@ -157,4 +157,22 @@ describe('curly strings', () => { two { three } }`) }) +}) + +describe('double quoted strings', () => { + test("work", () => { + expect(`"hello world"`).toMatchTree(` + String + DoubleQuote "hello world"`) + }) + + test("don't interpolate", () => { + expect(`"hello $world"`).toMatchTree(` + String + DoubleQuote "hello $world"`) + + expect(`"hello $(1 + 2)"`).toMatchTree(` + String + DoubleQuote "hello $(1 + 2)"`) + }) }) \ No newline at end of file