From d363700a39c3c494faaeca02750cff4f4059ca4a Mon Sep 17 00:00:00 2001 From: Pekka Laiho Date: Wed, 16 Dec 2020 22:01:50 +0700 Subject: [PATCH] add shortcut ~@ for unquote-splice --- src/Reader.php | 2 ++ src/Tokenizer.php | 8 ++++++++ test/ReaderTest.php | 1 + test/TokenizerTest.php | 3 +++ 4 files changed, 14 insertions(+) diff --git a/src/Reader.php b/src/Reader.php index 1471d3c..3ef2bd1 100644 --- a/src/Reader.php +++ b/src/Reader.php @@ -27,6 +27,8 @@ class Reader return $this->readSpecialForm($tokens, $index, 'quasiquote'); } elseif ($tokens[$index] == "~") { return $this->readSpecialForm($tokens, $index, 'unquote'); + } elseif ($tokens[$index] == "~@") { + return $this->readSpecialForm($tokens, $index, 'unquote-splice'); } elseif ($tokens[$index] == '(') { return $this->readList($tokens, $index); } elseif ($tokens[$index] == '[') { diff --git a/src/Tokenizer.php b/src/Tokenizer.php index 98d0d36..020ba59 100644 --- a/src/Tokenizer.php +++ b/src/Tokenizer.php @@ -101,6 +101,14 @@ class Tokenizer // Other special characters $addCurrent(); $tokens[] = $c; + } elseif ($c == '@') { + // If the last token was ~ then add @ to it + if (count($tokens) > 0 && $tokens[count($tokens) - 1] == '~') { + $tokens[count($tokens) - 1] .= $c; + } else { + // Otherwise treat it like normal character + $current .= $c; + } } else { // All other characters $current .= $c; diff --git a/test/ReaderTest.php b/test/ReaderTest.php index c62ddfc..160770d 100644 --- a/test/ReaderTest.php +++ b/test/ReaderTest.php @@ -28,6 +28,7 @@ class ReaderTest extends TestCase ["'", 'quote'], ['`', 'quasiquote'], ['~', 'unquote'], + ['~@', 'unquote-splice'], ]; } diff --git a/test/TokenizerTest.php b/test/TokenizerTest.php index 583a675..b71e2aa 100644 --- a/test/TokenizerTest.php +++ b/test/TokenizerTest.php @@ -76,6 +76,9 @@ class TokenizerTest extends TestCase // Other non-alphabet characters are symbols ["(aa!@#$%^&*-_=+bb<>,./?\\|cc)", ['(', "aa!@#$%^&*-_=+bb<>,./?\\|cc", ')']], + // @ after ~ is single token, @ anywhere else is normal character + ['aa@~@@bb', ['aa@', '~@', '@bb']], + // Strings ['"abc"', ['"abc"']], ['aa"bb"cc', ['aa', '"bb"', 'cc']],