File Coverage

blib/lib/Language/Farnsworth/Error.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package Language::Farnsworth::Error;
4              
5 1     1   5 use strict;
  1         2  
  1         33  
6 1     1   4 use warnings;
  1         3  
  1         30  
7              
8 1     1   5 use Data::Dumper;
  1         1  
  1         53  
9 1     1   6 use Carp;
  1         1  
  1         67  
10 1     1   720 use enum qw(RETURN EINTERP EPERL EPARI);
  0            
  0            
11              
12             require Exporter;
13             our @ISA = qw(Exporter);
14              
15             our @EXPORT = qw(error debug perlwrap farnsreturn RETURN EINTERP EPERL EPARI);
16              
17             use overload '""' => \&tostring,
18             'eq' => \&eq;
19              
20             our $level = 0; #debugging level, 0 means nothing, 1 means informative, 2 means all kinds of shit.
21              
22             sub error
23             {
24             my $type;
25             $type = shift if @_==2;
26             $type = EINTERP unless defined $type;
27             my $err = shift;
28            
29             #make already existing errors pass through transparently, fixes bug with return[], but i should find more direct route
30             #i had originally thought this might be a bug but now that i think about it, what is going on is...
31             # foo{x} := {return[1]; 2};
32             # Function Dispatch, evaluate the function;
33             # We then end up calling return[] which is a perl function, so it gets wrapped with perlwrap()
34             # This then causes the error to get wrapped by perlwrap()
35             #Circumventing this also allows perl code to correctly use error() to signify an error to the script rather than die
36             if (ref($err) && $err->isa("Language::Farnsworth::Error"))
37             {
38             die $err;
39             }
40            
41             my $eobj = {};
42             $eobj->{msg} = $err;
43             $eobj->{type} = $type;
44             $eobj->{caller} = [caller()];
45             bless $eobj;
46              
47             die $eobj;
48             }
49              
50             sub farnsreturn
51             {
52             my $return = shift;
53              
54             my $eobj = {};
55             $eobj->{msg} = $return;
56             $eobj->{type} = RETURN;
57             $eobj->{caller} = [caller()];
58             bless $eobj;
59              
60             die $eobj;
61             }
62              
63             sub isreturn
64             {
65             my $self = shift;
66             return 1 if ($self->{type} == RETURN);
67             return 0;
68             }
69              
70             sub getmsg
71             {
72             $_[0]->{msg};
73             }
74              
75             #wraps code and catches die() and wraps the error in our class
76             sub perlwrap(&;$)
77             {
78             # print "INPERLWRAP\n";
79             my $code=shift;
80             my $default=shift;
81             $default=EPERL unless defined $default;
82            
83             # print "WANTARRAY: ", wantarray(), "\n";
84             #preserve the context, makes things easier
85             if (wantarray) #array context
86             {
87             my @ret = eval {$code->()};
88             # print "DUMPER: ", Dumper(@ret), "\n";
89             # print "DUMP ERR: ", Dumper($@), "\n";
90             error $default, $@ if ($@);
91             return @ret;
92             }
93             else #scalar context
94             {
95             my $ret = eval {$code->()};
96             # print "DUMPER: ", Dumper($ret), "\n";
97             # print "DUMP ERR: ", Dumper($@), "\n";
98             error $default, $@ if ($@);
99             return $ret;
100             }
101             }
102              
103             sub tostring
104             {
105             my $self = shift;
106             return $self->{msg};
107             }
108              
109             sub eq
110             {
111             my ($one, $two, $rev) = @_;
112              
113             my $str = $one->tostring();
114             return $str eq $two;
115             }
116              
117             #i'd love something a little more efficient but, oh well.
118             sub debug
119             {
120             my ($mlevel, @messages) = @_;
121            
122             no warnings;
123             print @messages,"\n" if ($mlevel <= $level && @messages);
124             }
125              
126             1;
127             __END__