[luatex] REPL

Robert Krug destiny6 at mac.com
Mon Jan 11 23:32:49 CET 2021


Greetings


Here is a simple REPL for use with LuaTeX. I started with work by Rob Hoelz <rob at hoelz.ro> and cut out all the bells and whistles. To use it, save this to a lua file and load it. The REPL can be started by invoking repl(). I find this very handy to explore what is going on with LuaTeX.



Robert



P.S. I use this within Emacs. I assume it will work anywhere with a terminal type interface.



==========



-- Copyright (c) 2011-2015 Rob Hoelz <rob at hoelz.ro>
--
-- Further hacked by others.
--
-- Permission is hereby granted, free of charge, to any person
-- obtaining a copy of this software and associated documentation
-- files (the "Software"), to deal in the Software without
-- restriction, including without limitation the rights to use, copy,
-- modify, merge, publish, distribute, sublicense, and/or sell copies
-- of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be
-- included in all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.

-- @class repl

--- This module implements the core functionality of a REPL.


repl           = {VERSION = 0.9 }
repl_buffer    = ''
local error    = error

local function gather_results(success, ...)
  local n = select('#', ...)
  return success, { n = n, ... }
end

--- Uses the compilation error to determine whether or not further input
--- is pending after the last line. That is, is this a fraction of a
--- statement.
--- Rather crude, but this seems to work.
local function detectcontinue(err)
  return string.match(err, "'<eof>'$") or string.match(err, "<eof>$")
end

local function compilechunk(chunk)
  -- If this is an expression, rather than a statement, we should
  -- get a function, in f, to return the value of that expression.
  local f, err = load('return ' .. chunk, 'REPL')

  -- for statements (or fractions thereof).
  if not f then
    f, err = load(chunk, 'REPL')
  end

  return f, err
end

-- @param results The results to display. The results are a table,
-- with the integer keys containing the results, and the 'n' key
-- containing the highest integer key.
local function displayresults(results)
  if results.n == 0 then return end
  print(table.unpack(results, 1, results.n))
end

local function displayerror(err)
  print(err)
end

--- Evaluates a line of input, and displays return value(s).
local function handleline(line)
  local chunk  = repl_buffer .. line
  local f, err = compilechunk(chunk)

  if f then
    -- We have a (presumed) function. Try to call it, and display the
    -- results, or error.
    repl_buffer = ''
    local success, results = gather_results(xpcall(f, function(...) return debug.traceback(...) end))
    if success then
      displayresults(results)
    else
      displayerror(results[1])
    end
  else
    -- Is this a (presumed) fraction of a statement, or an error?
    if detectcontinue(err) then
      -- Presumably, a fraction of a statement.
      repl_buffer = chunk .. '\n'
      return 2
    else
      -- An error. Clear the buffer, so this does not keep happening.
      repl_buffer = ''
      displayerror(err)
    end
  end

  return 1
end

local function prompt(level)
  local prompt
  if level == 1 then prompt=">" else prompt=">>" end
  io.write(prompt)
end

--- Run a REPL loop in a synchronous fashion.
function repl()
  print()
  prompt(1)
  for line in io.stdin:lines() do
    local level = handleline(line)
    prompt(level)
  end
end


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://tug.org/pipermail/luatex/attachments/20210111/8c4c25a7/attachment.html>


More information about the luatex mailing list.