4eba2b3e225ce50f861f0786e0e4a2036a2d7c86
3 use warnings FATAL
=> qw(all);
4 no if $] >= 5.018, warnings
=> "experimental::smartmatch";
5 use feature
qw(switch);
7 our @EXPORT_OK = qw(_sequential_Q _equal_Q _clone
8 $nil $true $false _nil_Q _true_Q _false_Q
9 _number_Q _symbol _symbol_Q _string_Q _keyword _keyword_Q _list_Q _vector_Q _sub_Q _function_Q
10 _hash_map _hash_map_Q _assoc_BANG _dissoc_BANG _atom_Q);
17 return _list_Q($_[0]) || _vector_Q($_[0])
22 my ($ota, $otb) = (ref $a, ref $b);
23 if (!(($ota eq $otb) || (_sequential_Q($a) && _sequential_Q($b)))) {
30 when (/^List/ || /^Vector/) {
31 if (! (scalar(@{$a->{val}}) == scalar(@{$b->{val}}))) {
34 for (my $i=0; $i<scalar(@{$a->{val}}); $i++) {
35 if (! _equal_Q($a->nth($i), $b->nth($i))) {
42 if (! (scalar(keys %{ $a->{val} }) == scalar(keys %{ $b->{val} }))) {
45 foreach my $k (keys %{ $a->{val} }) {
46 if (!_equal_Q($a->{val}->{$k}, $b->{val}->{$k})) {
63 return FunctionRef->new( $obj );
66 return bless {%{$obj}}, ref $obj;
74 package BlankException;
75 sub new { my $class = shift; bless String->new("Blank Line") => $class }
82 sub new { my $class = shift; my $s = 'nil'; bless \$s => $class }
86 sub new { my $class = shift; my $s = 'true'; bless \$s => $class }
90 sub new { my $class = shift; my $s = 'false'; bless \$s => $class }
93 our $nil = Nil->new();
94 our $true = True->new();
95 our $false = False->new();
97 sub _nil_Q { return $_[0] eq $nil }
98 sub _true_Q { return $_[0] eq $true }
99 sub _false_Q { return $_[0] eq $false }
104 sub new { my $class = shift; bless \do { my $x=$_[0] }, $class }
106 sub _number_Q { (ref $_[0]) =~ /^Integer/ }
111 sub new { my $class = shift; bless \do { my $x=$_[0] }, $class }
113 sub _symbol_Q { (ref $_[0]) =~ /^Symbol/ }
116 sub _string_Q { ((ref $_[0]) =~ /^String/) && ${$_[0]} !~ /^\x{029e}/; }
119 sub _keyword { return String->new(("\x{029e}".$_[0])); }
120 sub _keyword_Q { ((ref $_[0]) =~ /^String/) && ${$_[0]} =~ /^\x{029e}/; }
125 sub new { my $class = shift; bless \$_[0] => $class }
133 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
134 sub nth { $_[0]->{val}->[$_[1]]; }
135 #sub _val { $_[0]->{val}->[$_[1]]->{val}; } # return value of nth item
136 sub rest { my @arr = @{$_[0]->{val}}; List->new([@arr[1..$#arr]]); }
137 sub slice { my @arr = @{$_[0]->{val}}; List->new([@arr[$_[1]..$_[2]]]); }
140 sub _list_Q { (ref $_[0]) =~ /^List/ }
147 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
148 sub nth { $_[0]->{val}->[$_[1]]; }
149 #sub _val { $_[0]->{val}->[$_[1]]->{val}; } # return value of nth item
150 sub rest { my @arr = @{$_[0]->{val}}; List->new([@arr[1..$#arr]]); }
151 sub slice { my @arr = @{$_[0]->{val}}; List->new([@arr[$_[1]..$_[2]]]); }
154 sub _vector_Q { (ref $_[0]) =~ /^Vector/ }
161 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
162 sub get { $_[0]->{val}->{$_[1]}; }
167 return _assoc_BANG($hsh, @_);
173 for(my $i=0; $i<scalar(@lst); $i+=2) {
175 $hsh->{$$str} = $lst[$i+1];
177 return HashMap->new($hsh);
183 for(my $i=0; $i<scalar(@lst); $i++) {
185 delete $hsh->{$$str};
187 return HashMap->new($hsh);
190 sub _hash_map_Q { (ref $_[0]) =~ /^HashMap/ }
199 my ($eval, $ast, $env, $params) = @_;
205 'ismacro'=>0}, $class
209 return Env->new($self->{env}, $self->{params}, $_[1]);
213 return &{ $self->{eval} }($self->{ast}, gen_env($self, $_[1]));
217 sub _sub_Q { (ref $_[0]) =~ /^CODE/ }
218 sub _function_Q { (ref $_[0]) =~ /^Function/ }
226 my ($class, $code) = @_;
228 'code'=>$code}, $class
232 return &{ $self->{code} }($_[1]);
241 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
244 sub _atom_Q { (ref $_[0]) =~ /^Atom/ }