File Coverage

blib/lib/App/RecordStream/DomainLanguage/Executor.pm
Criterion Covered Total %
statement 80 93 86.0
branch 2 4 50.0
condition 2 3 66.6
subroutine 20 22 90.9
pod 0 7 0.0
total 104 129 80.6


line stmt bran cond sub pod time code
1             package App::RecordStream::DomainLanguage::Executor;
2              
3 27     27   160 use strict;
  27         49  
  27         627  
4 27     27   114 use warnings;
  27         44  
  27         529  
5              
6 27     27   116 use App::RecordStream::DomainLanguage::Registry;
  27         50  
  27         596  
7 27     27   8022 use App::RecordStream::Executor;
  27         71  
  27         2130  
8              
9             my $next_id = 0;
10              
11             sub new
12             {
13 389     389 0 543 my $class = shift;
14              
15 389         608 my $id = $next_id++;
16              
17 389         718 my $this =
18             {
19             'ID' => $id,
20             };
21              
22 389         681 bless $this, $class;
23              
24 389         738 return $this;
25             }
26              
27             sub clear_vars
28             {
29 0     0 0 0 my $this = shift;
30              
31 0         0 my $id = $this->{'ID'};
32              
33             {
34 27     27   154 no strict;
  27         50  
  27         547  
  0         0  
35 27     27   110 no warnings;
  27         42  
  27         2174  
36              
37 0         0 %{__PACKAGE__ . "::Sandbox" . $id . "::"} = ();
  0         0  
38             }
39             }
40              
41             sub set_scalar
42             {
43 302     302 0 420 my $this = shift;
44 302         591 my $var = shift;
45 302         374 my $val = shift;
46              
47 302         441 my $id = $this->{'ID'};
48              
49             {
50 27     27   148 no strict;
  27         49  
  27         530  
  302         384  
51 27     27   123 no warnings;
  27         59  
  27         1973  
52              
53 302         441 *{__PACKAGE__ . "::Sandbox" . $id . "::" . $var} = \$val;
  302         1363  
54             }
55             }
56              
57             sub get_scalar
58             {
59 0     0 0 0 my $this = shift;
60 0         0 my $var = shift;
61              
62 0         0 my $id = $this->{'ID'};
63              
64             {
65 27     27   151 no strict;
  27         57  
  27         653  
  0         0  
66 27     27   155 no warnings;
  27         50  
  27         2347  
67              
68 0         0 return ${__PACKAGE__ . "::Sandbox" . $id . "::" . $var};
  0         0  
69             }
70             }
71              
72             sub set_ref
73             {
74 59320     59320 0 72267 my $this = shift;
75 59320         70164 my $var = shift;
76 59320         66787 my $ref = shift;
77              
78 59320         74722 my $id = $this->{'ID'};
79              
80             {
81 27     27   157 no strict;
  27         52  
  27         585  
  59320         65053  
82 27     27   116 no warnings;
  27         49  
  27         5905  
83              
84 59320         65788 *{__PACKAGE__ . "::Sandbox" . $id . "::" . $var} = $ref;
  59320         242656  
85             }
86             }
87              
88             # TODO: amling, default this?
89             sub import_registry
90             {
91 389     389 0 584 my $this = shift;
92              
93 389         844 for my $token (App::RecordStream::DomainLanguage::Registry::get_tokens())
94             {
95             my $subref = sub
96             {
97 343     343   880 my $value = App::RecordStream::DomainLanguage::Registry::evaluate($token, @_);
98              
99             # this is somewhat terrible...
100 343         755 my @pp = $value->get_possible_pairs();
101 343 50 66     828 if(!@_ && !@pp)
102             {
103             # The idea is this... if they use a field name that doesn't
104             # conflict with a nullary function then we pretend it was a
105             # barewords scalar.
106              
107             # Unfortunately this means e.g. "rec" is indistinguishable
108             # between the valuation that returns the "rec" field and the
109             # valuation that returns the current record. We allow the
110             # "rec" field possibility via the explicit "valuation" ctor.
111 0         0 $value->add_possibility('SCALAR', $token);
112             }
113              
114 343         2168 return $value;
115 29642         108397 };
116 29642         67639 $this->set_ref($token, $subref);
117 29642         62481 $this->set_ref("_$token", $subref); # for e.g. "last" which is reserved
118             }
119             }
120              
121             sub exec
122             {
123 389     389 0 531 my $__MY__this = shift;
124 389         551 my $__MY__code = shift;
125              
126 389         1101 $__MY__code = App::RecordStream::Executor->transform_code($__MY__code);
127              
128 389         588 my $__MY__id = $__MY__this->{'ID'};
129              
130 389         833 my $__MY__code_packaged = "package " . __PACKAGE__ . "::Sandbox$__MY__id; $__MY__code";
131 389         502 my $__MY__ret;
132              
133             {
134 27     27   180 no strict;
  27         55  
  27         582  
  389         466  
135 27     27   115 no warnings;
  27         56  
  27         2015  
136              
137 389         33131 $__MY__ret = eval $__MY__code_packaged;
138              
139 389 50       1652 if($@)
140             {
141 0         0 die $@;
142             }
143             }
144              
145 389         967 return $__MY__ret;
146             }
147              
148             1;