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]]]); }
144 use parent -norequire, 'Sequence';
147 sub _list_Q { (ref $_[0]) =~ /^List/ }
154 use parent -norequire, 'Sequence';
157 sub _vector_Q { (ref $_[0]) =~ /^Vector/ }
164 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
165 sub get { $_[0]->{val}->{$_[1]}; }
170 return _assoc_BANG($hsh, @_);
176 for(my $i=0; $i<scalar(@lst); $i+=2) {
178 $hsh->{$$str} = $lst[$i+1];
180 return HashMap->new($hsh);
186 for(my $i=0; $i<scalar(@lst); $i++) {
188 delete $hsh->{$$str};
190 return HashMap->new($hsh);
193 sub _hash_map_Q { (ref $_[0]) =~ /^HashMap/ }
202 my ($eval, $ast, $env, $params) = @_;
208 'ismacro'=>0}, $class
212 return Env->new($self->{env}, $self->{params}, $_[1]);
216 return &{ $self->{eval} }($self->{ast}, gen_env($self, $_[1]));
220 sub _sub_Q { (ref $_[0]) =~ /^CODE/ }
221 sub _function_Q { (ref $_[0]) =~ /^Function/ }
229 my ($class, $code) = @_;
231 'code'=>$code}, $class
235 return &{ $self->{code} }($_[1]);
244 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
247 sub _atom_Q { (ref $_[0]) =~ /^Atom/ }