From 8ec3cfe07d0614747f6b05eb82ed4f6d7354aac8 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Fri, 22 Jan 2021 08:38:36 +0900 Subject: [PATCH] Optimizations for f-strings --- src/compiler.c | 15 ++++++++++----- test/testFStrings.krk | 6 ++++++ test/testFStrings.krk.expect | 6 ++++++ 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 test/testFStrings.krk create mode 100644 test/testFStrings.krk.expect diff --git a/src/compiler.c b/src/compiler.c index 87863c9..a35b4db 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -1770,8 +1770,11 @@ static void string(int type) { } c += 2; } else if (isFormat && *c == '{') { - emitConstant(OBJECT_VAL(krk_copyString(stringBytes,stringLength))); - if (atLeastOne) emitByte(OP_ADD); + if (!atLeastOne || stringLength) { /* Make sure there's a string for coersion reasons */ + emitConstant(OBJECT_VAL(krk_copyString(stringBytes,stringLength))); + if (atLeastOne) emitByte(OP_ADD); + atLeastOne = 1; + } stringLength = 0; KrkScanner beforeExpression = krk_tellScanner(); Parser parserBefore = parser; @@ -1814,7 +1817,7 @@ static void string(int type) { error("Expected closing } after expression in f-string"); goto _cleanupError; } - emitByte(OP_ADD); + if (atLeastOne) emitByte(OP_ADD); atLeastOne = 1; c++; } else { @@ -1839,9 +1842,11 @@ static void string(int type) { emitConstant(OBJECT_VAL(bytes)); return; } - emitConstant(OBJECT_VAL(krk_copyString(stringBytes,stringLength))); + if (!isFormat || stringLength || !atLeastOne) { + emitConstant(OBJECT_VAL(krk_copyString(stringBytes,stringLength))); + if (atLeastOne) emitByte(OP_ADD); + } FREE_ARRAY(char,stringBytes,stringCapacity); - if (isFormat && atLeastOne) emitByte(OP_ADD); #undef PUSH_CHAR return; _cleanupError: diff --git a/test/testFStrings.krk b/test/testFStrings.krk new file mode 100644 index 0000000..5e9bb5e --- /dev/null +++ b/test/testFStrings.krk @@ -0,0 +1,6 @@ +print(f"Regular string") +print(f"{1 + 2}") +print(f"{1 + 2} with a string after") +print(f"with a string before {1 + 2}") +print(f"with {1+2}{object} nothing in between") +print(f"{1 + 2}{3 + 4}{[]}{{}} with some fun expressions") diff --git a/test/testFStrings.krk.expect b/test/testFStrings.krk.expect new file mode 100644 index 0000000..60c7e9c --- /dev/null +++ b/test/testFStrings.krk.expect @@ -0,0 +1,6 @@ +Regular string +3 +3 with a string after +with a string before 3 +with 3 nothing in between +37[]{} with some fun expressions