refactor string reader for reuse
This commit is contained in:
@@ -35,7 +35,7 @@ class Reader {
|
|||||||
// and also handles string interpolation cases like "${exp}moreString"
|
// and also handles string interpolation cases like "${exp}moreString"
|
||||||
readTable["{"] = (stream:Stream, k) -> CallExp(Symbol("begin").withPos(stream.position()), readExpArray(stream, "}", k));
|
readTable["{"] = (stream:Stream, k) -> CallExp(Symbol("begin").withPos(stream.position()), readExpArray(stream, "}", k));
|
||||||
|
|
||||||
readTable['"'] = readString;
|
readTable['"'] = readString.bind(_, _, false);
|
||||||
readTable["#"] = readRawString;
|
readTable["#"] = readRawString;
|
||||||
|
|
||||||
// Special symbols that wouldn't read as symbols, but should:
|
// Special symbols that wouldn't read as symbols, but should:
|
||||||
@@ -339,8 +339,8 @@ class Reader {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a string literal
|
// Read a string literal OR a shell section which supports interpolation
|
||||||
static function readString(stream:Stream, k:KissState) {
|
static function readString(stream:Stream, k:KissState, shell = false) {
|
||||||
var pos = stream.position();
|
var pos = stream.position();
|
||||||
var stringParts:Array<ReaderExp> = [];
|
var stringParts:Array<ReaderExp> = [];
|
||||||
var currentStringPart = "";
|
var currentStringPart = "";
|
||||||
@@ -350,6 +350,16 @@ class Reader {
|
|||||||
currentStringPart = "";
|
currentStringPart = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var terminator = if (shell) "```" else '"';
|
||||||
|
var escapes = ["$" => "$"];
|
||||||
|
if (!shell) {
|
||||||
|
escapes['\\'] = '\\';
|
||||||
|
escapes['t'] = '\t';
|
||||||
|
escapes['n'] = '\n';
|
||||||
|
escapes['r'] = '\r';
|
||||||
|
escapes['"'] = '"';
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
var next = switch (stream.takeChars(1)) {
|
var next = switch (stream.takeChars(1)) {
|
||||||
case Some(c): c;
|
case Some(c): c;
|
||||||
@@ -374,24 +384,13 @@ class Reader {
|
|||||||
stringParts.push(interpExpression);
|
stringParts.push(interpExpression);
|
||||||
case '\\':
|
case '\\':
|
||||||
var escapeSequence = stream.expect('valid escape sequence', () -> stream.takeChars(1));
|
var escapeSequence = stream.expect('valid escape sequence', () -> stream.takeChars(1));
|
||||||
switch (escapeSequence) {
|
if (escapes.exists(escapeSequence)) {
|
||||||
case '\\':
|
currentStringPart += escapes[escapeSequence];
|
||||||
currentStringPart += "\\";
|
} else {
|
||||||
case 't':
|
stream.error('unsupported escape sequence \\$escapeSequence');
|
||||||
currentStringPart += "\t";
|
return null;
|
||||||
case 'n':
|
|
||||||
currentStringPart += "\n";
|
|
||||||
case 'r':
|
|
||||||
currentStringPart += "\r";
|
|
||||||
case '"':
|
|
||||||
currentStringPart += '"';
|
|
||||||
case '$':
|
|
||||||
currentStringPart += '$';
|
|
||||||
default:
|
|
||||||
stream.error('unsupported escape sequence \\$escapeSequence');
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
case '"':
|
case t if (t == terminator):
|
||||||
endCurrentStringPart();
|
endCurrentStringPart();
|
||||||
return if (stringParts.length == 1) {
|
return if (stringParts.length == 1) {
|
||||||
stringParts[0].def;
|
stringParts[0].def;
|
||||||
|
Reference in New Issue
Block a user