Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hooks interface? #37

Open
rktjmp opened this issue Sep 14, 2021 · 0 comments
Open

Hooks interface? #37

rktjmp opened this issue Sep 14, 2021 · 0 comments

Comments

@rktjmp
Copy link
Owner

rktjmp commented Sep 14, 2021

RE: #33

To avoid the cost of requiring fennel if you want to do "low level" stuff, a/some hooks would be nice.

There is probably only one real place to hook which is just after we require Fennel. Adding other hooks for will-load-module|macro or will-compile-module|macro could exist but are probably not that useful?

(fn compile-string [string options]
  (local fennel (require-fennel))

  ;; -------------
  ;; hook interface?
  ;; -------------
  (each [_ hook (ipairs config.hooks)] ; config.when_fennel? config.with_fennel? 
    (hook fennel))

  (when (not has-injected-macro-searcher)
    (table.insert fennel.macro-searchers 1 macro-searcher)
    (set has-injected-macro-searcher true))

  (local options (doto (or options {})
                       (tset :filename (or options.filename :hotpot-compile-string))))
  (fn compile []
    (pick-values 1 (fennel.compile-string string options)))
  (xpcall compile fennel.traceback))

and a hook would just be a function that accepts fennel and returns ... true|nil,error? Probably the hook should just raise if they have an error.

-- users responsibility to avoid repeats?
local once = false
local add_cloader = function(fennel)
  if once then return end
  table.insert(fennel["macro-searchers"], function(module_name)
     local filename = fennel["search-module"](module_name, package.cpath)
     if filename then
        local func = "luaopen_" .. module_name
        return function() return package.loadlib(filename, func) end, filename
     end
  end)
  once = true
end

require("hotpot").setup({
  provide_require_fennel = true,
  hook = {add_cloader}
})

Mostly this is just a question of names:

will_compile = {}
configure_fennel = {}
on|for|with|when|has_fennel = {}
when_load_fennel = {}

required_fennel = {} -- might cause confusion around regular "require fennel"
                     -- not popping the hook, though that could be made to work easily.

-- allows for future hooks in namespace
hook = {
  will_compile = {}
}

on = {
  require(d?)_fennel = {} -- requireD because we call *after* require, not intercepting require.
}

And also a question of once or many times. Do you want to configure fennel (once) or run a hook on every compile (many), why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant