~technomancy/fennel-lang.org

e7a3443511c929af9bef12408b032189679650ca — Phil Hagelberg 14 days ago 3b5fa2d
Experiment with loading See Fennel in the background with web workers.
4 files changed, 67 insertions(+), 19 deletions(-)

R antifennel => antifennel.lua
M fennel.css
A see-worker.js
M see.lua
R antifennel => antifennel.lua +0 -1
@@ 1,4 1,3 @@
#!/usr/bin/env luajit
package.preload["fnlfmt"] = package.preload["fnlfmt"] or function(...)
  local view = require("fennelview")
  local function identify_line(line, pos, stack)

M fennel.css => fennel.css +0 -1
@@ 121,7 121,6 @@ tt, pre, code, kbd { font-family: "Fira Mono", Inconsolata, monospace; }
hr { margin-top: 2em; clear: both; }

#see-fennel #out {
    color: #dd1111;
    clear: both;
    font-size: 80%;
    padding: 1em;

A see-worker.js => see-worker.js +6 -0
@@ 0,0 1,6 @@
const window = this;
importScripts('/fengari-web.js');

var shims = "package.loaded.ffi = {typeof=function() end} os = {getenv=function() end} io = {open=function() end} bit = {band = function(a,b) return a & b end, rshift=function(a,b) return a >> b end} unpack = table.unpack";

window.done(window.fengari.load(shims + ' dofile("antifennel.lua")')());

M see.lua => see.lua +61 -17
@@ 5,15 5,12 @@ local js = require("js")
package.loaded.ffi = {typeof=function() end}
os = {getenv=function() end}
io = {open=function() end}
bit = {band = function() end, rshift=function() end}
bit = {band = function(a,b) return a & b end,
       rshift=function(a,b) return a >> b end}
unpack = table.unpack

function print(...) js.global.console.log(...) end

-- TODO: load asynchronously
local antifennel = dofile("antifennel")
local fennel = require("fennel")

local document = js.global.document
local compile_fennel = document:getElementById("compile-fennel")
local compile_lua = document:getElementById("compile-lua")


@@ 22,23 19,70 @@ local out = document:getElementById("out")
local fennel_source = document:getElementById("fennel-source")
local lua_source = document:getElementById("lua-source")

compile_fennel.onclick = function()
   local ok, code = pcall(fennel.compileString, fennel_source.value)
   if ok then lua_source.value = code
   else out.innerHTML = "Fennel: " .. code end
local status = function(msg, success)
   out.innerHTML = msg
   out.style.color = success and "black" or "#dd1111"
end

local done = function(antifennel)
   local fennel = require("fennel")

   compile_fennel.onclick = function()
      local ok, code = pcall(fennel.compileString, fennel_source.value)
      if ok then
         lua_source.value = code
         status("Compiled Fennel to Lua.", true)
      else
         status("Fennel: " .. code, false)
      end
   end

   compile_lua.onclick = function()
      -- for Lua that doesn't parse, antifennel gives crummy error messages
      local ok, msg = load(lua_source.value)
      if not ok then return status("Lua: " .. msg, false) end

      local ok, code = pcall(antifennel, lua_source.value)
      if ok then
         fennel_source.value = code
         status("Compiled Lua to Fennel.\n\n"..
                   "Note that compiling Lua to Fennel can result in some" ..
                   " strange-looking code when\nusing constructs that Fennel" ..
                   " does not support natively, like early returns.", true)
      else
         status("Lua: " .. code, false)
      end
   end

   out.innerHTML = "Loaded Fennel " .. fennel.version .. " in " .. _VERSION
end

local started = false

local init_worker = function()
   local worker = js.new(js.global.Worker, "/see-worker.js")
   -- TODO: the done function here appears to never get called
   js.global.window.done = done
end

compile_lua.onclick = function()
   -- for Lua that doesn't parse, antifennel gives crummy error messages
   local ok, msg = load(lua_source.value)
   if not ok then out.innerHTML = "Lua: " .. msg return end
local init = function()
   if started then return end
   started = true
   out.innerHTML = "Loading..."

   local ok, code = pcall(antifennel, lua_source.value)
   if ok then fennel_source.value = code
   else out.innerHTML = "Lua: " .. code end
   if false and js.global.Worker then
      init_worker()
   elseif js.global.setTimeout then
      js.global:setTimeout(function() return done(dofile("antifennel.lua")) end)
   else
      done(dofile("antifennel.lua"))
   end
end

out.innerHTML = "Loaded Fennel " .. fennel.version .. " in " .. _VERSION
compile_fennel.onclick = init
compile_lua.onclick = init
fennel_source.onfocus = init
lua_source.onfocus = init

-- TODO: keyboard shortcuts
-- TODO: multiple Fennel versions?