107 lines
2.6 KiB
Elixir
107 lines
2.6 KiB
Elixir
% elixir: cache
|
|
|
|
% Responsible for starting Elixir from the command line.
|
|
module Code::Init
|
|
mixin Code::Formatter
|
|
|
|
% Invoked directly from erlang boot process. It parses all argv
|
|
% options and execute them in the order they are specified.
|
|
def process_argv(options)
|
|
{ commands, argv, halt } = process_options(options, [], [], false, true)
|
|
GenServer.call('elixir_code_server, { 'argv, argv })
|
|
|
|
[process_command(c) for c in commands]
|
|
|
|
if halt
|
|
halt!(0)
|
|
else
|
|
% TODO Is there a better way to suspend the process?
|
|
Erlang.timer.sleep('infinity)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def halt!(0)
|
|
Erlang.init.stop
|
|
end
|
|
|
|
def halt!(status)
|
|
Erlang.halt(status)
|
|
end
|
|
|
|
def process_options([$"-v"|_], _, _, _, _)
|
|
IO.puts "Elixir #{Code.version}"
|
|
halt!(0)
|
|
end
|
|
|
|
def process_options([$"-e",h|t], commands, close, _files, halt)
|
|
process_options(t, [{'eval, h}|commands], close, true, halt)
|
|
end
|
|
|
|
def process_options([$"-f",h|t], commands, close, _files, halt)
|
|
process_options(t, commands, [{'eval, h}|close], true, halt)
|
|
end
|
|
|
|
def process_options([$"--no-halt"|t], commands, close, files, _)
|
|
process_options(t, commands, close, files, false)
|
|
end
|
|
|
|
def process_options([h|t], commands, close, files, halt)
|
|
{ final, extra } = if h.to_char_list[0] == $-
|
|
if files
|
|
{ commands, [h|t] }
|
|
else
|
|
IO.new('standard_error).puts "Unknown option #{h.to_bin}"
|
|
halt!(1)
|
|
end
|
|
else
|
|
{ [{'require,h}|commands], t }
|
|
end
|
|
|
|
{ final.reverse + close.reverse, extra.map(_.to_bin), halt }
|
|
end
|
|
|
|
def process_options([], commands, close, _, halt)
|
|
{ commands.reverse + close.reverse, [], halt }
|
|
end
|
|
|
|
def process_command({'eval, expr})
|
|
with_catch -> Erlang.elixir.eval(expr, [])
|
|
end
|
|
|
|
def process_command({'require, file})
|
|
with_catch -> Code.load_file(file), do (io, kind, _error)
|
|
io.puts "** #{kind} in #{file.to_bin}"
|
|
end
|
|
end
|
|
|
|
def with_catch(command, callback := nil)
|
|
command()
|
|
catch kind: error
|
|
if exiting?(kind, error)
|
|
case error.__parent_name__
|
|
match 'String
|
|
halt!(error.to_char_list)
|
|
match 'Integer
|
|
halt!(error)
|
|
end
|
|
else
|
|
io = IO.new('standard_error)
|
|
if callback
|
|
callback(io, kind, error)
|
|
end
|
|
io.puts "** #{kind} #{format_catch(kind, error)}"
|
|
print_stacktrace(io, __stacktrace__)
|
|
halt!(1)
|
|
end
|
|
end
|
|
|
|
def exiting?(kind, error)
|
|
kind == 'exit && ['String, 'Integer].include?(error.__parent_name__)
|
|
end
|
|
|
|
def print_stacktrace(io, stacktrace)
|
|
stacktrace.each -> (s) io.puts " #{self.format_stacktrace(s)}"
|
|
end
|
|
end |