~technomancy/fennel

Make hashfn arguments work when beginning multisyms v1 PROPOSED

Benaiah Mischenko: 1
 Make hashfn arguments work when beginning multisyms

 2 files changed, 17 insertions(+), 3 deletions(-)
Phil Hagelberg <phil@hagelb.org> writes:
Next
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~technomancy/fennel/patches/7830/mbox | git am -3
Learn more about email & git

[PATCH] Make hashfn arguments work when beginning multisyms Export this patch

Converts $ arguments to $1 when they begin a multisym (matches the
behavior of a lone $).

Sets used-local metadata correctly for symbols which begin
multisyms. This was previously incorrect for all symbols which started
multisyms, but the hashfn argument bug fixed in this commit is the
only known effect.

Added test cases for multisyms and immediately-returned arguments to
ensure neither regress.

Enables a getter function shorthand: #$symbol.property
---
 fennel.lua | 15 ++++++++++++---
 test.lua   |  5 +++++
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/fennel.lua b/fennel.lua
index f68a38e..3f1a5d0 100644
--- a/fennel.lua
+++ b/fennel.lua
@@ -638,11 +638,20 @@ end
-- if they have already been declared via declareLocal
local function symbolToExpression(symbol, scope, isReference)
    local name = symbol[1]
    if scope.hashfn and name == '$' then name = '$1' end
    local parts = isMultiSym(name) or {name}
    local multiSymParts = isMultiSym(name)
    if scope.hashfn then
       if name == '$' then name = '$1' end
       if multiSymParts then
          if multiSymParts[1] == "$" then
             multiSymParts[1] = "$1"
             name = table.concat(multiSymParts, ".")
          end
       end
    end
    local parts = multiSymParts or {name}
    local etype = (#parts > 1) and "expression" or "sym"
    local isLocal = scope.manglings[parts[1]]
    if isLocal and scope.symmeta[name] then scope.symmeta[name].used = true end
    if isLocal and scope.symmeta[parts[1]] then scope.symmeta[parts[1]].used = true end
    -- if it's a reference and not a symbol which introduces a new binding
    -- then we need to check for allowed globals
    assertCompile(not isReference or isLocal or globalAllowed(parts[1]),
diff --git a/test.lua b/test.lua
index 2c627c3..78d96b1 100644
--- a/test.lua
+++ b/test.lua
@@ -295,6 +295,8 @@ local cases = {
        ["(#(+ $3 $4) 1 1 3 4)"]=7,
        -- One argument
        ["(#(+ $1 45) 1)"]=46,
        -- Immediately returned argument
        ["(+ (#$ 1) (#$2 2 3))"]=4,
        -- With let
        ["(let [f #(+ $1 45)] (f 1))"]=46,
        -- Complex body
@@ -303,6 +305,9 @@ local cases = {
        ["(#(+ $ 2) 3)"]=5,
        -- Mixed $ types
        ["(let [f #(+ $ $1 $2)] (f 1 2))"]=4,
        -- Multisyms containing $ arguments
        ["(#$.foo {:foo :bar})"]="bar",
        ["(#$2.foo.bar.baz nil {:foo {:bar {:baz :quux}}})"]="quux",
    },
    match = {
        -- basic literal
-- 
2.23.0.rc1
Benaiah Mischenko <benaiah@mischenko.com> writes:
View this thread in the archives