Commit | Line | Data |
88eac4d2 |
1 | package DX::Expander; |
2 | |
3 | use DX::Utils qw(:all); |
4 | use DX::Value::True; |
5 | use DX::Value::False; |
6 | use Tcl; |
7 | use DX::Class; |
8 | |
9 | has tcl => ( |
10 | is => 'lazy', builder => sub { Tcl->new }, |
11 | handles => { _split_list => 'SplitList' }, |
12 | ); |
13 | |
14 | sub expand_args { |
15 | my ($self, @args) = @_; |
16 | map { $self->expand_one($_) } @args; |
17 | } |
18 | |
19 | sub expand_proposition { |
20 | my ($self, $prop) = @_; |
21 | my ($name, @args) = $self->_split_list($prop); |
22 | proposition($name, $self->expand_args(@args)); |
23 | } |
24 | |
25 | my @exp_t = map { [ qr/\A(\s*)${\$_->[1]}\s*\Z/, 'expand_'.$_->[0] ] } ( |
26 | [ number => qr/([\d.]+)/ ], |
27 | [ string => qr/'(.*)'/s ], |
28 | [ bool => qr/(true|false)/ ], |
29 | [ symbol => qr/([a-zA-Z_][a-zA-Z0-9_]*)/ ], |
30 | [ dict => qr/{(.*)}/s ], |
31 | [ array => qr/\[(.*)\]/s ], |
32 | ); |
33 | |
34 | sub expand_one { |
35 | my ($self, $exp) = @_; |
36 | foreach my $try (@exp_t) { |
37 | my ($re, $meth) = @$try; |
38 | $exp =~ $re and return $self->$meth($2, $1); |
39 | } |
40 | die 'Uhhhh ... '.$exp; |
41 | } |
42 | |
43 | sub expand_number { number($_[1]) } |
44 | |
45 | sub expand_string { |
46 | my ($self, $exp, $ws) = @_; |
47 | return string($exp) unless $ws =~ s/.*\n//s; |
48 | my $wstrip = length($ws)+1; |
49 | $exp =~ s/^ {1,$wstrip}//mg; |
50 | return string($exp); |
51 | } |
52 | |
53 | sub expand_symbol { $_[1] } |
54 | |
55 | sub expand_dict { |
56 | my ($self, $val) = @_; |
57 | my @pairs = $self->_split_list($val); |
58 | die "Uneven dict" if @pairs % 2; |
59 | dict(map { |
60 | $pairs[2*$_] => $self->expand_one($pairs[(2*$_)+1]) |
61 | } 0..int($#pairs/2)) |
62 | } |
63 | |
64 | sub expand_array { die; |
65 | } |
66 | |
67 | sub expand_bool { |
68 | ('DX::Value::'.ucfirst($_[1]))->new |
69 | } |
70 | |
71 | 1; |