]> git.lizzy.rs Git - metalua.git/blob - metalua/repl.mlua
ast_to_src: format function calls and unary operators without space
[metalua.git] / metalua / repl.mlua
1 -------------------------------------------------------------------------------
2 -- Copyright (c) 2006-2013 Fabien Fleutot and others.
3 --
4 -- All rights reserved.
5 --
6 -- This program and the accompanying materials are made available
7 -- under the terms of the Eclipse Public License v1.0 which
8 -- accompanies this distribution, and is available at
9 -- http://www.eclipse.org/legal/epl-v10.html
10 --
11 -- This program and the accompanying materials are also made available
12 -- under the terms of the MIT public license which accompanies this
13 -- distribution, and is available at http://www.lua.org/license.html
14 --
15 -- Contributors:
16 --     Fabien Fleutot - API and implementation
17 --
18 -------------------------------------------------------------------------------
19
20 -- Keep these global:
21 PRINT_AST  = true
22 LINE_WIDTH = 60
23 PROMPT     = "M> "
24 PROMPT2    = ">> "
25
26 local pp=require 'metalua.pprint'
27 local M = { }
28
29 mlc = require 'metalua.compiler'.new()
30
31 local readline
32
33 do -- set readline() to a line reader, either editline otr a default
34    local status, _ = pcall(require, 'editline')
35    if status then
36       local rl_handle = editline.init 'metalua'
37       readline = |p| rl_handle:read(p)
38    else
39       local status, rl = pcall(require, 'readline')
40       if status then
41          rl.set_options{histfile='~/.metalua_history', keeplines=100, completion=false }
42          readline = rl.readline
43       else -- neither editline nor readline available
44          function readline (p)
45             io.write (p)
46             io.flush ()
47             return io.read '*l'
48          end
49       end
50    end
51 end
52
53 local function reached_eof(lx, msg)
54    return lx:peek().tag=='Eof' or msg:find "token `Eof"
55 end
56
57
58 function M.run()
59     pp.printf ("Metalua, interactive REPLoop.\n"..
60             "(c) 2006-2013 <metalua@gmail.com>")
61    local lines = { }
62    while true do
63       local src, lx, ast, f, results, success
64       repeat
65          local line = readline(next(lines) and PROMPT2 or PROMPT)
66          if not line then print(); os.exit(0) end -- line==nil iff eof on stdin
67          if not next(lines) then
68             line = line:gsub('^%s*=', 'return ')
69          end
70          table.insert(lines, line)
71          src = table.concat (lines, "\n")
72       until #line>0
73       lx  = mlc :src_to_lexstream(src)
74       success, ast = pcall(mlc.lexstream_to_ast, mlc, lx)
75       if success then
76           success, f = pcall(mlc.ast_to_function, mlc, ast, '=stdin')
77           if success then
78               results = { xpcall(f, debug.traceback) }
79               success = table.remove (results, 1)
80               if success then
81                   -- Success!
82                   for _, x in ipairs(results) do
83                       pp.print(x, {line_max=LINE_WIDTH, metalua_tag=true})
84                   end
85                   lines = { }
86               else
87                   print "Evaluation error:"
88                   print (results[1])
89                   lines = { }
90               end
91           else
92               print "Can't compile into bytecode:"
93               print (f)
94               lines = { }
95           end
96       else
97          -- If lx has been read entirely, try to read
98          --  another line before failing.
99          if not reached_eof(lx, ast) then
100             print "Can't compile source into AST:"
101             print (ast)
102             lines = { }
103          end
104       end
105    end
106 end
107
108 return M