slightly less incomplete deparse output
[scpubgit/DX.git] / lib / DX / Deparse.pm
CommitLineData
381e8dad 1package DX::Deparse;
2
3use DX::Class;
4
5sub indent_by { ' ' }
6
7sub max_width { 78 }
8
9sub _inner_meta {
10 my ($self, $ometa) = @_;
11 +{ %$ometa, width_left => $ometa->{width_left} - length $self->indent_by };
12}
13
14sub _indent_one {
15 my ($self, $to_indent) = @_;
16 $to_indent =~ s/^/${\$self->indent_by}/mg;
17 $to_indent;
18}
19
20sub fmt {
21 my ($self, $thing) = @_;
22 $self->_fmt($thing, { width_left => $self->max_width })."\n";
23}
24
25sub _fmt {
26 my ($self, $thing, $meta) = @_;
27 return $thing unless ref($thing);
1e812b19 28 my $type = join'_', split '::', lc +(ref($thing) =~ /^(?:DX::)?(.*)/)[0];
381e8dad 29 $self->${\"_fmt_${type}"}($thing, $meta);
30}
31
32sub _fmt_value_dict {
1e812b19 33 my ($self, $dict, $meta) = @_;
34 my $chunks = $self->_fmt_pairs([
35 map [ $_, $dict->get_member_at($_) ], $dict->index_list
36 ], $meta);
37 return '{{ }}' unless $chunks =~ /\S/;
381e8dad 38 "{{\n${chunks}\n}}";
39}
40
1e812b19 41sub _fmt_pairs {
42 my ($self, $pairs, $ometa) = @_;
43 my $imeta = $self->_inner_meta($ometa);
44 $self->_indent_one(join "\n", map {
45 join ' ', map $self->_fmt($_, $imeta), @$_
46 } @$pairs);
47}
48
381e8dad 49sub _fmt_value_string {
50 my ($self, $string) = @_;
1e812b19 51 # TODO: multiline handling
381e8dad 52 my $val = $string->string_value;
53 if ($val =~ /^\w+$/) {
54 qq{'${val}'}
55 } else {
56 qq{{'${val}'}}
57 }
58}
59
60sub _fmt_value_number { $_[1]->number_value }
61
62sub _fmt_value_true { 'true' }
63
64sub _fmt_value_false { 'false' }
65
1e812b19 66sub _fmt_value_unset { 'unset' }
67
68sub _fmt_object {
69 my ($self, $pairs, $meta) = @_;
70 my $chunks = $self->_fmt_pairs($pairs, $meta);
71 return '{ }' unless $chunks =~ /\S/;
72 "{\n${chunks}\n}"
73}
74
75sub _fmt_hypothesis {
76 my ($self, $hyp, $meta) = @_;
77 $self->_fmt_object([
78 map [ $_ => $hyp->$_ ],
79 qw(actions outstanding_propositions resolved_propositions scope)
80 ], $meta);
81}
82
83sub _fmt_array {
84 my ($self, $ary, $ometa) = @_;
85 my $imeta = $self->_inner_meta($ometa);
86 my $chunks = $self->_indent_one(
87 join "\n", map $self->_fmt($_, $imeta), @$ary
88 );
89 return '{ }' unless $chunks =~ /\S/;
90 "{\n${chunks}\n}";
91}
92
39351e10 93sub _fmt_glob {
94 my ($self, $glob, $meta) = @_;
95 return ((''.*$glob) =~ /::([A-Z_]+)$/)[0];
96}
97
1e812b19 98sub _fmt_action_setvalue {
99 my ($self, $action, $meta) = @_;
100 $self->_fmt_action_generic(SetValue => $action, $meta);
101}
102
103sub _fmt_action_addvalue {
104 my ($self, $action, $meta) = @_;
105 $self->_fmt_action_generic(AddValue => $action, $meta);
106}
107
108sub _fmt_action_generic {
109 my ($self, $name, $action, $meta) = @_;
110 my $path = join '.', map $self->_fmt($_, $meta), @{$action->target_path};
111 join ' ', $name, $path, $self->_fmt($action->new_value, $meta);
112}
113
693f2d6d 114sub _fmt_resolvedpropositionset {
115 my ($self, $rps, $meta) = @_;
39351e10 116 $self->_fmt_object([
117 map {
118 [ $_, $rps->dependencies_for($_) ]
119 } @{$rps->propositions},
120 ], $meta);
693f2d6d 121}
122
123sub _fmt_proposition {
124 my ($self, $prop, $meta) = @_;
125 join ' ',
126 $prop->predicate,
127 map $self->_fmt($_, $meta), @{$prop->args};
128}
1e812b19 129
130sub _fmt_scope {
131 my ($self, $scope, $meta) = @_;
132 $self->_fmt_object([
133 [ W => $scope->globals ],
134 map [ $_ => $scope->locals->[$_] ], 0..$#{$scope->locals}
135 ], $meta);
136}
137
138sub _fmt_searchstate {
139 my ($self, $ss, $meta) = @_;
140 $self->_fmt_object([
141 [ alternatives => '{...}' ],
142 [ current_hypothesis => $ss->current_hypothesis ],
143 ], $meta);
144}
381e8dad 145
1461;