From 956b0c3fa701cf825a6eefab0260e5a0ea344d8b Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 4 Oct 2020 13:05:43 +0200 Subject: [PATCH] added \xHH escape character to strings, allow strings of length zero. --- compiler/src/prog8/ast/antlr/Antr2Kotlin.kt | 18 ++++++++++++++++-- .../ast/processing/AstIdentifiersChecker.kt | 4 ++-- docs/source/syntaxreference.rst | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt b/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt index 620f850d6..88c750cc5 100644 --- a/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt +++ b/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt @@ -647,7 +647,21 @@ private fun prog8Parser.VardeclContext.toAst(): VarDecl { ) } -internal fun escape(str: String) = str.replace("\t", "\\t").replace("\n", "\\n").replace("\r", "\\r") +internal fun escape(str: String): String { + val es2 = str.replace("\t", "\\t").replace("\n", "\\n").replace("\r", "\\r") + val es = str.map { + when(it) { + '\t' -> "\\t" + '\n' -> "\\n" + '\r' -> "\\r" + '"' -> "\\\"" + in '\u8000'..'\u80ff' -> "\\x" + (it.toInt() - 0x8000).toString(16).padStart(2, '0') + in '\u0000'..'\u00ff' -> it.toString() + else -> "\\u" + it.toInt().toString(16).padStart(4, '0') + } + } + return es.joinToString("") +} internal fun unescape(str: String, position: Position): String { val result = mutableListOf() @@ -664,7 +678,7 @@ internal fun unescape(str: String, position: Position): String { 'u' -> { "${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}${iter.nextChar()}".toInt(16).toChar() } - '$' -> { + 'x' -> { // special hack 0x8000..0x80ff will be outputted verbatim without encoding val hex = ("" + iter.nextChar() + iter.nextChar()).toInt(16) (0x8000 + hex).toChar() diff --git a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt index eb0936f82..390625afc 100644 --- a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt @@ -143,8 +143,8 @@ internal class AstIdentifiersChecker(private val program: Program, private val e } override fun visit(string: StringLiteralValue) { - if (string.value.length !in 1..255) - errors.err("string literal length must be between 1 and 255", string.position) + if (string.value.length > 255) + errors.err("string literal length max is 255", string.position) super.visit(string) } diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index fabba7db6..28fdc6237 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -416,7 +416,7 @@ There are several escape sequences available to put special characters into your - ``\r`` - carriage return character (more or less the same as newline if printing to the screen) - ``\"`` - quote character (otherwise it would terminate the string) - ``\uHHHH`` - a unicode codepoint \u0000 - \uffff (16-bit hexadecimal) -- ``\$HH`` - 8-bit hex value that will be copied verbatim *without encoding* +- ``\xHH`` - 8-bit hex value that will be copied verbatim *without encoding* Operators