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 _symbol _symbol_Q _keyword _keyword_Q _list_Q _vector_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 die "TODO: Hash map comparison\n";
55 return List->new( [ @{$obj->{val}} ] );
58 return Vector->new( [ @{$obj->{val}} ] );
61 return HashMap->new( { %{$obj->{val}} } );
64 return Function->new_from_hash( { %{$obj} } );
67 die "Clone of non-collection\n";
75 package BlankException;
76 sub new { my $class = shift; bless String->new("Blank Line") => $class }
83 sub new { my $class = shift; my $s = 'nil'; bless \$s => $class }
87 sub new { my $class = shift; my $s = 'true'; bless \$s => $class }
91 sub new { my $class = shift; my $s = 'false'; bless \$s => $class }
94 our $nil = Nil->new();
95 our $true = True->new();
96 our $false = False->new();
98 sub _nil_Q { return $_[0] eq $nil }
99 sub _true_Q { return $_[0] eq $true }
100 sub _false_Q { return $_[0] eq $false }
105 sub new { my $class = shift; bless \do { my $x=$_[0] }, $class }
111 sub new { my $class = shift; bless \do { my $x=$_[0] }, $class }
113 sub _symbol_Q { (ref $_[0]) =~ /^Symbol/ }
116 sub _keyword { return String->new(("\x{029e}".$_[0])); }
117 sub _keyword_Q { ((ref $_[0]) =~ /^String/) && ${$_[0]} =~ /^\x{029e}/; }
122 sub new { my $class = shift; bless \$_[0] => $class }
130 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
131 sub nth { $_[0]->{val}->[$_[1]]; }
132 #sub _val { $_[0]->{val}->[$_[1]]->{val}; } # return value of nth item
133 sub rest { my @arr = @{$_[0]->{val}}; List->new([@arr[1..$#arr]]); }
134 sub slice { my @arr = @{$_[0]->{val}}; List->new([@arr[$_[1]..$_[2]]]); }
137 sub _list_Q { (ref $_[0]) =~ /^List/ }
144 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
145 sub nth { $_[0]->{val}->[$_[1]]; }
146 #sub _val { $_[0]->{val}->[$_[1]]->{val}; } # return value of nth item
147 sub rest { my @arr = @{$_[0]->{val}}; List->new([@arr[1..$#arr]]); }
148 sub slice { my @arr = @{$_[0]->{val}}; List->new([@arr[$_[1]..$_[2]]]); }
151 sub _vector_Q { (ref $_[0]) =~ /^Vector/ }
158 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
159 sub get { $_[0]->{val}->{$_[1]}; }
164 return _assoc_BANG($hsh, @_);
170 for(my $i=0; $i<scalar(@lst); $i+=2) {
172 $hsh->{$$str} = $lst[$i+1];
174 return HashMap->new($hsh);
180 for(my $i=0; $i<scalar(@lst); $i++) {
182 delete $hsh->{$$str};
184 return HashMap->new($hsh);
187 sub _hash_map_Q { (ref $_[0]) =~ /^HashMap/ }
196 my ($eval, $ast, $env, $params) = @_;
202 'ismacro'=>0}, $class
204 sub new_from_hash { my $class = shift; bless $_[0], $class }
207 return Env->new($self->{env}, $self->{params}, $_[1]);
211 return &{ $self->{eval} }($self->{ast}, gen_env($self, $_[1]));
220 sub new { my $class = shift; bless {'meta'=>$nil, 'val'=>$_[0]}, $class }
223 sub _atom_Q { (ref $_[0]) =~ /^Atom/ }