Fix hashfn and quote and unquote

This commit is contained in:
XeroOl 2024-05-12 16:45:18 -05:00
parent 34e0bce092
commit f17342b7ce
2 changed files with 37 additions and 23 deletions

View File

@ -211,24 +211,21 @@ identifiers are declared / referenced in which places."
(tset calls ast true)
(tset scopes ast scope)
;; Most calls aren't interesting, but here's the list of the ones that are:
(case (and (sym? (. ast 1)) (tostring (. ast 1)))
;; This cannot be done through the :fn feature of the compiler plugin system
;; because it needs to be called *before* the body of the function is processed.
;; TODO check if hashfn needs to be here
(where (or :fn :lambda :λ))
(define-function ast scope)
(where (or :require :include))
(tset require-calls ast true)
;; fennel expands multisym calls into the `:` special, so we need to reference the symbol while we still can
(where method-call (= (type method-call) :string) (method-call:find ":"))
(reference (. ast 1) scope :read)
;; NOTE HACK TODO this should be removed once fennel makes if statements work like normal
(where :if)
(let [len (length ast)]
(table.insert defer #(tset ast (+ len 1) nil)))
(where :hashfn)
(let [head (. ast 1)]
(table.insert defer #(set head.byteend head.bytestart)))))
(let [head (. ast 1)]
(case (and (sym? head) (tostring head))
;; This cannot be done through the :fn feature of the compiler plugin system
;; because it needs to be called *before* the body of the function is processed.
(where (or :fn :lambda :λ))
(define-function ast scope)
(where (or :require :include))
(tset require-calls ast true)
;; fennel expands multisym calls into the `:` special, so we need to reference the symbol while we still can
(where method-call (= (type method-call) :string) (method-call:find ":"))
(reference head scope :read)
;; NOTE HACK TODO this should be removed once fennel makes if statements work like normal
(where :if)
(let [len (length ast)]
(table.insert defer #(tset ast (+ len 1) nil))))))
(λ attempt-to-recover! [msg ?ast]
(or (= 1 (msg:find "unknown identifier"))
@ -343,15 +340,25 @@ identifiers are declared / referenced in which places."
ast (icollect [ok ast parser &until (not ok)] ast)]
(λ collect-everything [ast result]
(λ parsed [ast]
"runs on every ast tree that was parsed"
(if (sym? ast)
(case (values (tostring ast) (file.text:sub ast.bytestart ast.bytestart))
(where (:hashfn "#"))
(table.insert defer #(set ast.byteend ast.bytestart))
(where (or (:quote "'") (:quote "`")))
(table.insert defer #(set ast.byteend ast.bytestart))
(where (:unquote ","))
(table.insert defer #(set ast.byteend ast.bytestart))))
(when (or (table? ast) (list? ast) (sym? ast))
(tset result ast true))
(tset lexical ast true))
;; recursive call
(when (or (table? ast) (list? ast))
(each [k v (iter ast)]
(collect-everything k result)
(collect-everything v result))))
(parsed k)
(parsed v))))
(collect-everything ast lexical)
(parsed ast lexical)
;; This is bad; we mutate fennel.macro-path
(let [old-macro-path fennel.macro-path]

View File

@ -145,6 +145,13 @@ new message handler `msgh`.")
; "```fnl\n(macro foo [a b c] ...)\n```\ndocstring!")
(check "#(prin|t :hello)"
#($:find "```fnl\n(print ...)\n```" 1 true))
(check "(hash|fn (print :hello))"
#($:find "```fnl\n(hashfn ...)\n```" 1 true))
(check "#prin|t"
#($:find "```fnl\n(print ...)\n```" 1 true))
(check ";; fennel-ls: macro-file
`(,prin|t :hello)"
#($:find "```fnl\n(print ...)\n```" 1 true))
nil)
{: test-literals