add types to Proposition and PropositionSequence
[scpubgit/DX.git] / lib / DX / ShellFrontend.pm
1 package DX::ShellFrontend;
2
3 use IO::Handle;
4 use Caroline;
5 use DX::Class;
6
7 has session => (
8   is => 'ro', required => 1,
9   handles => [ qw(is_complete_command_string eval_command_string) ]
10 );
11
12 has session_mode => (is => 'rwp', required => 1);
13
14 has readline => (is => 'lazy', builder => sub { Caroline->new });
15
16 sub BUILD { STDOUT->autoflush(1) }
17
18 sub repl {
19   my ($self) = @_;
20   while (1) {
21     last unless $self->rep
22   }
23 }
24
25 sub rep {
26   my ($self) = @_;
27   return unless defined(my $command = $self->read_command);
28   my @result = $self->eval_command_string($command);
29   $self->process_result(@result);
30   return 1;
31 }
32
33 sub read_command {
34   my ($self) = @_;
35   my $base_prompt = $self->session_mode eq 'shell' ? '$ ' : '? ';
36   my $rl = $self->readline;
37   return unless defined(my $command = $rl->readline($base_prompt));
38   while (not $self->is_complete_command_string($command)) {
39     $command .= $rl->readline('> ');
40   }
41   $rl->history_add($command);
42   return $command;
43 }
44
45 sub process_result {
46   my ($self, @result) = @_;
47   foreach my $res (@result) {
48     my ($type, $payload) = @$res;
49     $self->${\($self->can("process_${type}_result")||die)}($payload);
50   }
51 }
52
53 sub process_mode_result {
54   my ($self, $mode) = @_;
55   $self->_set_session_mode($mode);
56 }
57
58 sub process_output_result {
59   my ($self, $output) = @_;
60   $output .= "\n" unless $output =~ /\n$/;
61   print $output;
62 }
63
64 1;