add rule and exists built-ins to shell
[scpubgit/DKit.git] / bin / dx-shell
CommitLineData
eed368c9 1#!/usr/bin/env perl
2
3use strictures 1;
4use curry;
5use DX::Solver;
6use DX::Lib::FS;
7use Term::ReadLine;
a26f6378 8use Devel::Dwarn;
eed368c9 9
10my $solver = DX::Solver->new(observation_policy => sub { 1 });
11
12DX::Lib::FS->new->load_into($solver);
13
14#::Dwarn(
15# [ $solver->query([ 'D' ], [ directory_at => 'D' => \'t' ])->results ]
16# ->[0]->value_for('D')
17#);
18
19use Tcl;
20
21my $tcl = Tcl->new;
22
23my $split = $tcl->curry::weak::SplitList;
24
25my (@res, @last_q);
26
27sub do_query {
28 @res = $solver->query(@last_q)->results;
29 Dwarn([ map {
30 my @act = $_->actions;
31 ((@act ? \@act : ()), $_->all_values);
32 } @res ]);
33}
34
a26f6378 35sub expand_def {
36 my ($vars, $body) = @_;
eed368c9 37 my @varnames = $split->($vars);
38 local our @Body_Parts;
39 $tcl->Eval($body);
a26f6378 40 return (\@varnames, @Body_Parts);
41}
42
43$tcl->CreateCommand(query => sub {
44 my (undef, undef, undef, $vars, $body) = @_;
45 @last_q = expand_def($vars, $body);
eed368c9 46 do_query();
47 return;
48});
49
50$tcl->CreateCommand(run => sub {
51 foreach my $ind ($res[0]->independent_actions) {
52 my $cl = ref($ind);
53 warn +(split('::', $cl))[-1]."\n";
54 $solver->run_action($ind);
55 }
56 do_query();
57 return;
58});
59
60sub mangle_args {
61 my @args = @_;
62 map { $_ =~ /^'(.*)'$/ ? \do { my $x = $1 } : $_ } @args;
63}
64
65my $rule_sub = sub {
66 my (undef, undef, $name, @args) = @_;
67 push our @Body_Parts, [ $name => mangle_args(@args) ];
68 return;
69};
70
a26f6378 71$tcl->CreateCommand(rule => sub {
72 my (undef, undef, undef, $rule, $vars, $body) = @_;
73 $solver->add_rule($rule => expand_def($vars, $body));
74 $tcl->CreateCommand($rule => $rule_sub);
75 return;
76});
77
eed368c9 78foreach my $rule (keys %{$solver->rule_set->rules}) {
79 $rule =~ s/\/\d+$//;
80 $tcl->CreateCommand($rule => $rule_sub);
81}
a26f6378 82
83$tcl->CreateCommand(exists => sub {
84 my (undef, undef, undef, $vars, $body) = @_;
85 push our @Body_Parts, [ exists => expand_def($vars, $body) ];
86 return;
87});
eed368c9 88
89#$tcl->Eval(q{query D {directory_at D 't'; mode D '0755'; }});
90
a26f6378 91if ($ARGV[0]) {
92 $tcl->EvalFile($ARGV[0]);
93}
94
eed368c9 95my $rl = Term::ReadLine->new;
96
97my $cmd;
98
2e60bb64 99while (defined(my $line = $rl->readline(length($cmd)?'> ':'$ '))) {
100 $cmd .= "${line}\n";
eed368c9 101 if ($tcl->call(info => complete => $cmd)) {
102 $tcl->Eval($cmd);
103 $cmd = '';
104 }
105}