From 9db9ced2e28c0ed41f0410f5075f329af20ea553 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Fri, 20 May 2022 19:51:55 +0000 Subject: [PATCH] refactor string reader for reuse --- kiss/src/kiss/Reader.hx | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/kiss/src/kiss/Reader.hx b/kiss/src/kiss/Reader.hx index 80e85fcd..f408b08c 100644 --- a/kiss/src/kiss/Reader.hx +++ b/kiss/src/kiss/Reader.hx @@ -35,7 +35,7 @@ class Reader { // and also handles string interpolation cases like "${exp}moreString" readTable["{"] = (stream:Stream, k) -> CallExp(Symbol("begin").withPos(stream.position()), readExpArray(stream, "}", k)); - readTable['"'] = readString; + readTable['"'] = readString.bind(_, _, false); readTable["#"] = readRawString; // Special symbols that wouldn't read as symbols, but should: @@ -339,8 +339,8 @@ class Reader { }; } - // Read a string literal - static function readString(stream:Stream, k:KissState) { + // Read a string literal OR a shell section which supports interpolation + static function readString(stream:Stream, k:KissState, shell = false) { var pos = stream.position(); var stringParts:Array = []; var currentStringPart = ""; @@ -350,6 +350,16 @@ class Reader { currentStringPart = ""; } + var terminator = if (shell) "```" else '"'; + var escapes = ["$" => "$"]; + if (!shell) { + escapes['\\'] = '\\'; + escapes['t'] = '\t'; + escapes['n'] = '\n'; + escapes['r'] = '\r'; + escapes['"'] = '"'; + } + do { var next = switch (stream.takeChars(1)) { case Some(c): c; @@ -374,24 +384,13 @@ class Reader { stringParts.push(interpExpression); case '\\': var escapeSequence = stream.expect('valid escape sequence', () -> stream.takeChars(1)); - switch (escapeSequence) { - case '\\': - currentStringPart += "\\"; - case 't': - currentStringPart += "\t"; - case 'n': - currentStringPart += "\n"; - case 'r': - currentStringPart += "\r"; - case '"': - currentStringPart += '"'; - case '$': - currentStringPart += '$'; - default: - stream.error('unsupported escape sequence \\$escapeSequence'); - return null; + if (escapes.exists(escapeSequence)) { + currentStringPart += escapes[escapeSequence]; + } else { + stream.error('unsupported escape sequence \\$escapeSequence'); + return null; } - case '"': + case t if (t == terminator): endCurrentStringPart(); return if (stringParts.length == 1) { stringParts[0].def;