]> git.lizzy.rs Git - metalua.git/blob - src/lib/metalua/metaloop.mlua
88fcbdc91d2311e47ea8af9772256fb0bfa79d01
[metalua.git] / src / lib / metalua / metaloop.mlua
1 require 'metalua.compiler'
2
3 module ('metaloop', package.seeall)
4
5 PRINT_AST  = true
6 LINE_WIDTH = 60
7 PROMPT     = "M> "
8 PROMPT2    = ">> "
9
10 do -- set readline() to a line reader, either editline otr a default
11    local status, _ = pcall(require, 'editline')
12    if status then
13       local rl_handle = editline.init 'metalua'
14       readline = |p| rl_handle:read(p) 
15    else
16       readline = |p| io.write(p) and io.read '*l'
17    end
18 end
19
20 function reached_eof(lx, msg)
21    return lx:peek().tag=='Eof' or msg:find "token `Eof"
22 end
23
24 printf ("Metalua, interactive REPLoop.\n"..
25         "(c) 2006-2008 <metalua@gmail.com>")
26
27 function run()
28    local lines = { }
29    while true do
30       local src, lx, ast, f, results, success
31       repeat
32          local line = readline(next(lines) and PROMPT2 or PROMPT)
33          if not line then print(); os.exit(0) end -- line==nil iff eof on stdin
34          if not next(lines) then
35             line = line:gsub('^%s*=', 'return ')
36          end
37          table.insert(lines, line)
38          src = table.concat (lines, "\n")
39       until #line>0
40       
41       lx  = mlc.lexstream_of_luastring(src) 
42       success, ast = pcall(mlc.ast_of_lexstream, lx)
43       if success then
44          success, f = pcall(mlc.function_of_ast, ast, '=stdin')
45          if success then
46             results = { pcall(f) }
47             success = table.remove (results, 1)
48             if success then
49                -- Success!
50                table.iforeach(|x| table.print(x, LINE_WIDTH), results)
51                lines = { }
52             else
53                print "Evaluation error:"
54                print (results[1])
55                lines = { }
56             end
57          else
58             print "Can't compile into bytecode:"
59             print (f)
60             lines = { }
61          end
62       else
63          -- If lx has been read entirely, try to read another
64          -- line before failing.
65          if not reached_eof(lx, ast) then
66             print "Can't compile source into AST:"
67             print (ast)
68             lines = { } 
69          end
70       end
71    end
72 end