~technomancy/fennel

Changelog updates and setup guide tweaks.
Don't double-uniquify gensyms.

Gensyms already have uniqueness checks, so they can skip the extra
uniqueness checks from declare-local.

This should fix https://todo.sr.ht/~technomancy/fennel/54
compiler: allow strings at call position

Strings can possibly have a __call metamethod, and it's actually
possible to call strings in Lua with the following notation:
`("str")(...)`.  This patch adds a check if AST element at call
position is a string, and if it is, it is wrapped in parentheses to
ensure correct Lua syntax.

I wonder if we can wrap every literal into parentheses, as
something like this is valid lua:

local function foo(bar) return bar end
(foo)(42)

Also if __call metamethod for strings is not restored in the test, the
test-empty-values test breaks:

    ./test/luaunit.lua:2893: Expected an error when calling function
    but no error generated
Merge remote-tracking branch 'eko/patch-1' into main

# Conflicts:
#	src/fennel/compiler.fnl
Merge pull request #346 from mrichards42/match-where-nil

Test that pattern matches before destructuring
Merge pull request #347 from mrichards42/match-where-values

Fix match multi-value destructuring with guards
Don't perform globals checking on _ENV.
Further improvements to the "from clojure" guide.
Return to using do/end to disambiguate method parens.

The semicolon thing was just too error-prone.
Fix macro example in from-clojure guide.
Flesh out the rest of the from-clojure guide.
Add draft of "Learning Fennel from Clojure" guide.
test: add some edge case tests for ?.

Also removed some of the redundant test cases
?. macro: further improve the emitted lua

The `(-?> t (. a) (. b) (. c))` version was an improvement over the one
before it, since instsead of deep-nesting a closure for each key, it
instead nested if-else-done blocks, but since each parent is only
accessed once, it can be further improved upon by reassigning to a
single symbol.

This, ironically, goes against the general code philosophy seen in
fennel, but results in the cleanest output, and macro hygiene will
prevent the downsides we'd otherwise be concerned with.

Compare the two outputs for the following:

```fennel
(?. {:a {:b {:c {:d :HEY}}}}
    :a :b :c :d)
```

```lua
-- new impl
local t_0_0 = {a = {b = {c = {d = "HEY"}}}}
if (nil ~= t_0_0) then
  t_0_0 = (t_0_0).a
end
if (nil ~= t_0_0) then
  t_0_0 = (t_0_0).b
end
if (nil ~= t_0_0) then
  t_0_0 = (t_0_0).c
end
if (nil ~= t_0_0) then
  t_0_0 = (t_0_0).d
end
return t_0_0

-- previous version that expands to (-?> t (. a) (. b) (. c))
local _0_0 = {a = {b = {c = {d = "HEY"}}}}
if _0_0 then
  local _1_0 = (_0_0).a
  if _1_0 then
    local _2_0 = (_1_0).b
    if _2_0 then
      local _3_0 = (_2_0).c
      if _3_0 then
        return (_3_0).d
      else
        return _3_0
      end
    else
      return _2_0
    end
  else
    return _1_0
  end
else
  return _0_0
end
```
fix ?. implementation to allow a nil tbl

* allow `(?. nil :a :b :c)` to work without error
* compiling `(?. t :a :b :c)` to `(-?> t (. a) (. b) (. c))` also avoids
emitting a nested function for every key

TODO before merging: update changelog and tweak test cases to cover a
wide variety of behaviors
bugfix: add propagation of .useBitLib opt to repl
bugfix: add missing -v alias for --version
Fix correlation being broken with macros

Before, a program like (when true 4) would input sixty-odd lines of
space when compiled with --correlate. This is because the invocation
of the when macro caused the AST to include a node with a line number
of the code *in macro.fnl*. The compiler already checked for the file
name of the syntax tree and the currently-compiled file being equal,
but both checks were broken and always returned nil (without an error),
so the correlation always happened.

This patch might break something, since it messes with some code that
has been silently failing for a bit.
ea27b100 — Mike Richards 5 months ago
Fix match multi-value destructuring with guards
Next