-- lua.lua - Lua 5.1 interpreter (lua.c) reimplemented in Lua. -- -- (c) David Manura, 2008-08 -- Licensed under the same terms as Lua itself. -- Based on lua.c from Lua 5.1.3. -- Improvements by Shmuel Zeigerman. -- -- Modified and improved by Jim Bauwens for use in LuaTerm do local LUA_PROMPT = "> " local LUA_PROMPT2 = ">> " local function LUA_QL(x) return "'" .. x .. "'" end local LUA_RELEASE = _VERSION local LUA_COPYRIGHT = "LuaTerm v2.0beta\n(C) 2013 Jim Bauwens" local _G = _G local assert = assert local collectgarbage = collectgarbage local loadstring = loadstring local pcall = pcall local rawget = rawget local select = select local tostring = tostring local type = type local unpack = unpack local xpcall = xpcall local string_format = string.format local string_sub = string.sub local mySession, execSession, result local moveHistory local function l_message (pname, msg) if pname then mySession:write(string_format("%s: ", pname)) end mySession:write(string_format("%s\n", msg)) end local function report(status, msg) if not status and msg ~= nil then l_message(progname, tostring(msg)); end return status end local function subThreadCallBack(s, resultC) result = resultC Session.removeSession(s) mySession:triggerResume() end local function docall(f, ...) local tp = {...} -- no need in tuple (string arguments only) local F = function() return f(unpack(tp)) end -- Create a new session to run the user code (and link it to the same console we are in) execSession = Session(mySession.console, F, subThreadCallBack, true) Session.addSession(execSession) execSession:start(true) -- Suspend the current session mySession:suspend() -- return the execSession results return unpack(result, 1, result.n) end local function dostring(s, name) local f, msg = loadstring(s, name) if f then f, msg = docall(f) end return report(f, msg) end local function print_version() l_message(nil, LUA_RELEASE .. " - " .. LUA_COPYRIGHT) end local history = {} local function saveline(s) if #s > 0 then history[#history+1] = s end end local function get_prompt (firstline) return firstline and LUA_PROMPT or LUA_PROMPT2 end local function incomplete (msg) if msg then local ender = LUA_QL("") if string_sub(msg, -#ender) == ender then return true end end return false end local function pushline (firstline) -- print the promt character and read user input mySession:write(get_prompt(firstline)) local totalHistory = #history local historyPos = totalHistory + 1 local tempHistory = {} repeat moveHistory = 0 tempHistory[historyPos] = mySession:readLine(tempHistory[historyPos] or history[historyPos]) if moveHistory ~= 0 then historyPos = math.min(math.max(historyPos + moveHistory, 1), totalHistory + 1) end until moveHistory == 0 local b = tempHistory[historyPos] -- no input if not b then return end -- change '=' to `return' if firstline and string_sub(b, 1, 1) == '=' then return "return " .. string_sub(b, 2) else return b end end local function loadline () local b = pushline(true) -- no input if not b then return -1 end local f, msg -- repeat until gets a complete line while true do f, msg = loadstring(b, "=stdin") if not incomplete(msg) then -- the user enter a complete statement break end local b2 = pushline(false) if not b2 then return -1 end b = b .. "\n" .. b2 -- join them end saveline(b) return f, msg end function luaTerm (session) mySession = session print_version() while true do local result local status, msg = loadline() if status == -1 then break end if status then result = tuple(docall(status)) status, msg = result[1], result[2] end report(status, msg) -- Print any results if status and result.n > 1 then for i=2, result.n do result[i] = tostring(result[i]) end mySession:print(unpack(result, 2, result.n)) end end mySession:write("\n") end luaTermCommandTable = { history = function (ind) if ind then mySession.console:dataIn("^KILLINP^") moveHistory = ind mySession:tick(true) end end } --include "termfunctions.lua" end