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   169 use strict;
  27         59  
  27         668  
4 27     27   130 use warnings;
  27         59  
  27         607  
5              
6 27     27   144 use App::RecordStream::DomainLanguage::Registry;
  27         62  
  27         612  
7 27     27   7715 use App::RecordStream::Executor;
  27         83  
  27         2045  
8              
9             my $next_id = 0;
10              
11             sub new
12             {
13 389     389 0 702 my $class = shift;
14              
15 389         745 my $id = $next_id++;
16              
17 389         937 my $this =
18             {
19             'ID' => $id,
20             };
21              
22 389         846 bless $this, $class;
23              
24 389         986 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   284 no strict;
  27         91  
  27         528  
  0         0  
35 27     27   155 no warnings;
  27         57  
  27         2059  
36              
37 0         0 %{__PACKAGE__ . "::Sandbox" . $id . "::"} = ();
  0         0  
38             }
39             }
40              
41             sub set_scalar
42             {
43 302     302 0 520 my $this = shift;
44 302         808 my $var = shift;
45 302         525 my $val = shift;
46              
47 302         563 my $id = $this->{'ID'};
48              
49             {
50 27     27   154 no strict;
  27         55  
  27         529  
  302         510  
51 27     27   121 no warnings;
  27         61  
  27         1892  
52              
53 302         530 *{__PACKAGE__ . "::Sandbox" . $id . "::" . $var} = \$val;
  302         1810  
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   152 no strict;
  27         63  
  27         519  
  0         0  
66 27     27   117 no warnings;
  27         55  
  27         2134  
67              
68 0         0 return ${__PACKAGE__ . "::Sandbox" . $id . "::" . $var};
  0         0  
69             }
70             }
71              
72             sub set_ref
73             {
74 59320     59320 0 90752 my $this = shift;
75 59320         96284 my $var = shift;
76 59320         86515 my $ref = shift;
77              
78 59320         93721 my $id = $this->{'ID'};
79              
80             {
81 27     27   156 no strict;
  27         60  
  27         499  
  59320         88100  
82 27     27   125 no warnings;
  27         56  
  27         5494  
83              
84 59320         85601 *{__PACKAGE__ . "::Sandbox" . $id . "::" . $var} = $ref;
  59320         269299  
85             }
86             }
87              
88             # TODO: amling, default this?
89             sub import_registry
90             {
91 389     389 0 677 my $this = shift;
92              
93 389         1140 for my $token (App::RecordStream::DomainLanguage::Registry::get_tokens())
94             {
95             my $subref = sub
96             {
97 343     343   1201 my $value = App::RecordStream::DomainLanguage::Registry::evaluate($token, @_);
98              
99             # this is somewhat terrible...
100 343         1016 my @pp = $value->get_possible_pairs();
101 343 50 66     1039 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         2246 return $value;
115 29642         105505 };
116 29642         79019 $this->set_ref($token, $subref);
117 29642         77908 $this->set_ref("_$token", $subref); # for e.g. "last" which is reserved
118             }
119             }
120              
121             sub exec
122             {
123 389     389 0 745 my $__MY__this = shift;
124 389         696 my $__MY__code = shift;
125              
126 389         1452 $__MY__code = App::RecordStream::Executor->transform_code($__MY__code);
127              
128 389         801 my $__MY__id = $__MY__this->{'ID'};
129              
130 389         1086 my $__MY__code_packaged = "package " . __PACKAGE__ . "::Sandbox$__MY__id; $__MY__code";
131 389         617 my $__MY__ret;
132              
133             {
134 27     27   181 no strict;
  27         63  
  27         561  
  389         611  
135 27     27   128 no warnings;
  27         56  
  27         1816  
136              
137 389         31620 $__MY__ret = eval $__MY__code_packaged;
138              
139 389 50       1791 if($@)
140             {
141 0         0 die $@;
142             }
143             }
144              
145 389         1180 return $__MY__ret;
146             }
147              
148             1;