~andreyorst

Moscow

https://andreyorst.gitlab.io/

I love Lisp and text editors!


#182 Option to retain comments when compiling/decompiling Fennel/Lua 4 days ago

Comment by ~andreyorst on ~technomancy/fennel

will check soon. Is it deployed to /see by chance?

#182 Option to retain comments when compiling/decompiling Fennel/Lua 2 months ago

Ticket created by ~andreyorst on ~technomancy/fennel

While working on a game in TIC I had to decompile bump.lua to Fennel with antifennel in order to include it in the Fennel version of the cart, and I had to restore comments manually, to make the code more readable and sectioned as the original.

Additionally to that, later I had to compile the Fennel cart to Lua because the current TIC-80 player on the tic-80.com doesn't support some features I used like fcollect and case which are already in the development version of TIC, and thus I had to restore all of the comments, containing sprites, waveforms, etc.

An option to keep the comments when compiling/decompiling would be very helpful.

#178 REPL locals-saving does not work correctly with var 3 months ago

Ticket created by ~andreyorst on ~technomancy/fennel

This file:

(macro incf [var-name] `(do (set ,var-name (+ ,var-name 1)) ,var-name))
(var x 10)
(print (incf x))
(print x)
(incf x)
(print x)

if ran expr by expr in REPL on 1118d8e:

Welcome to Fennel 1.3.1-dev on PUC Lua 5.4!
Use ,help to see available commands.
Try installing readline via luarocks for a better repl experience.
>> (macro incf [var-name] `(do (set ,var-name (+ ,var-name 1)) ,var-name))
nil
>> (var x 10)
nil
>> (print (incf x))
11

>> (print x)
10

>> (incf x)
11
>> (print x)
11

produces 11, 10, 11 messages.

If ran from file it produces 11, 11, 12:

$ fennel ~/bug.fnl
11
11
12

The compiled output looks legit, must be something with REPL-locals?

local x = 10
local function _1_(...)
  x = (x + 1)
  return x
end
print(_1_(...))
print(x)
do
  x = (x + 1)
end
return print(x)

#177 attempt to index a nil value (local 'source') 3 months ago

Comment by ~andreyorst on ~technomancy/fennel

While it does it's not a duplicate, probably, because the problem with its evaluation resulting with an odd error. As I've described, it can be manually macroexpanded first, then the result can be evaluated without errors, but not fully automatically as it supposed to, unless the newindex metamethod is present.

#177 attempt to index a nil value (local 'source') 3 months ago

Comment by ~andreyorst on ~technomancy/fennel

redacted

#177 attempt to index a nil value (local 'source') 3 months ago

Ticket created by ~andreyorst on ~technomancy/fennel

While trying to workaround the #176 I've stumped on a kinda weird bug. I've defined the following macro:

(macro defrecord [name ...]
  "Create a constructor and accessor functions for a new record type."
  {:fnl/arglist [name field1 field2 & fields]}
  (let [name (tostring name)
        fields (faccumulate [fields {}
                             i 1 (select :# ...)]
                 (doto fields
                   (tset (tostring (select i ...)) i)))
        metatable {:__newindex
                   (list 'fn [(sym :record#) (sym :f#) (sym :v#)]
                         (list 'rawset (sym :record#) (list '. fields (sym :f#)) (sym :v#)))}
        constructor `(fn [...]
                       `(setmetatable [(,'unquote ...)] ,metatable))
        accessors (collect [f (pairs fields)
                            :into {name constructor}]
                    (.. name :- f)
                    `(fn [,(sym :record#)]
                       `(. (,'unquote ,(sym :record#)) ,(. fields f))))]
    `(macros ,accessors)))

It expands to a bunch of other macros that act as inlined functions:

>> (macrodebug (defrecord foo a b c))
(macros {:foo (fn [...]
                (quote (setmetatable
                        [(unquote ...)]
                        {:__newindex (fn [record# f# v#]
                                       (rawset record# (. {:a 1 :b 2 :c 3} f#) v#))})))
         :foo-a (fn [record#] (quote (. (unquote record#) 1)))
         :foo-b (fn [record#] (quote (. (unquote record#) 2)))
         :foo-c (fn [record#] (quote (. (unquote record#) 3)))})

The weird part is that if I copy the output - it works. But if I just execute the macro above as (defrecord foo a b c) it fails with the error:

Compile error: /data/data/com.termux/files/usr/bin/fennel:3562: attempt to index a nil value (local 'source')

The even weirder part is that removing the setmetatable call from the code that is generated by the defrecord macro makes the error go away.

#176 nested quoting doesn't work as expected 3 months ago

Ticket created by ~andreyorst on ~technomancy/fennel

For the context, I've been trying to write a macro that generates another macro, e.g. like this Common Lisp macro:

(defmacro maker (name id)
  `(defmacro ,(intern (format nil "MAKE-~s" name)
                      (package-name (symbol-package name)))
     (a b c)
     `(list :id ,,id :a ,a :b ,b :c ,c)))

It can be used like this (maker foo 42) which produces a macro make-foo which in turn creates an object with baked-in ID from the parent macro, and supplied args:

* (macroexpand-1 '(maker foo 42))
(DEFMACRO MAKE-FOO (A B C) (LIST 'LIST :ID 42 :A A :B B :C C))
* (maker foo 42)
MAKE-FOO
* (make foo 3 7 11)
(:ID 42 :A 3 :B 7 :C 11)

However, when I try the same thing in Fennel, this happens:

>> (macro a [name id]
     `(macro ,(sym (.. :make- (tostring name)))
        [a b c]
        `{:id ,,id :a ,a :b ,b :c ,c}))
unknown:5:12 Compile error: tried to use unquote outside quote

     `{:id ,,id :a ,a :b ,b :c ,c}))
* Try moving the form to inside a quoted form.
* Try removing the comma.

It seems that nested quoting and multi-unquoting aren't supported, and all quoting operates on a single level. This isn't how quoting works in other lisps, such as Clojure, Racket, CL, and various Schemes.

#173 Warning should be generated when expressions are passed to require with --require-as-include 3 months ago

Comment by ~andreyorst on ~technomancy/fennel

I think there should be a warning for both the variable and the literal, as they are both cases where the module can't be included.

note that require-as-include allows for expressions that can be evaluated at compile-time, e.g. (require (.. ... ".foo")) so the fix should account for that

-- Andrey Listopadov

#171 case and match doesn't use __fennelrest when destructuring patterns 4 months ago

Comment by ~andreyorst on ~technomancy/fennel

There's a patch pending to fix this:

https://lists.sr.ht/~technomancy/fennel/patches/41255

#171 case and match doesn't use __fennelrest when destructuring patterns 4 months ago

Comment by ~andreyorst on ~technomancy/fennel

It also doesn't support kv-table & destructuring, like let:

(let [{: a : b & rest} {:a 1 :b 2 :c 3 :d 4}] rest) ;=> {:c 3 :d 4}