--- /dev/null
+-------------------------------------------------------------------------------
+-- Copyright (c) 2006-2013 Fabien Fleutot and others.
+--
+-- All rights reserved.
+--
+-- This program and the accompanying materials are made available
+-- under the terms of the Eclipse Public License v1.0 which
+-- accompanies this distribution, and is available at
+-- http://www.eclipse.org/legal/epl-v10.html
+--
+-- This program and the accompanying materials are also made available
+-- under the terms of the MIT public license which accompanies this
+-- distribution, and is available at http://www.lua.org/license.html
+--
+-- Contributors:
+-- Fabien Fleutot - API and implementation
+--
+-------------------------------------------------------------------------------
+
+-- Keep these global:
+PRINT_AST = true
+LINE_WIDTH = 60
+PROMPT = "M> "
+PROMPT2 = ">> "
+
+local pp=require 'metalua.pprint'
+local M = { }
+
+mlc = require 'metalua.compiler'.new()
+
+local readline
+
+do -- set readline() to a line reader, either editline otr a default
+ local status, _ = pcall(require, 'editline')
+ if status then
+ local rl_handle = editline.init 'metalua'
+ readline = |p| rl_handle:read(p)
+ else
+ local status, rl = pcall(require, 'readline')
+ if status then
+ rl.set_options{histfile='~/.metalua_history', keeplines=100, completion=false }
+ readline = rl.readline
+ else -- neither editline nor readline available
+ function readline (p)
+ io.write (p)
+ io.flush ()
+ return io.read '*l'
+ end
+ end
+ end
+end
+
+local function reached_eof(lx, msg)
+ return lx:peek().tag=='Eof' or msg:find "token `Eof"
+end
+
+
+function M.run()
+ pp.printf ("Metalua, interactive REPLoop.\n"..
+ "(c) 2006-2013 <metalua@gmail.com>")
+ local lines = { }
+ while true do
+ local src, lx, ast, f, results, success
+ repeat
+ local line = readline(next(lines) and PROMPT2 or PROMPT)
+ if not line then print(); os.exit(0) end -- line==nil iff eof on stdin
+ if not next(lines) then
+ line = line:gsub('^%s*=', 'return ')
+ end
+ table.insert(lines, line)
+ src = table.concat (lines, "\n")
+ until #line>0
+ lx = mlc :src_to_lexstream(src)
+ success, ast = pcall(mlc.lexstream_to_ast, mlc, lx)
+ if success then
+ success, f = pcall(mlc.ast_to_function, mlc, ast, '=stdin')
+ if success then
+ results = { xpcall(f, debug.traceback) }
+ success = table.remove (results, 1)
+ if success then
+ -- Success!
+ for _, x in ipairs(results) do
+ pp.print(x, {line_max=LINE_WIDTH, metalua_tag=true})
+ end
+ lines = { }
+ else
+ print "Evaluation error:"
+ print (results[1])
+ lines = { }
+ end
+ else
+ print "Can't compile into bytecode:"
+ print (f)
+ lines = { }
+ end
+ else
+ -- If lx has been read entirely, try to read
+ -- another line before failing.
+ if not reached_eof(lx, ast) then
+ print "Can't compile source into AST:"
+ print (ast)
+ lines = { }
+ end
+ end
+ end
+end
+
+return M
\ No newline at end of file