use Time::HiRes qw(time);
use readline;
-use types qw(_sequential_Q _equal_Q _clone $nil $true $false
+use types qw(_sequential_Q _equal_Q $nil $true $false
_number_Q _symbol _symbol_Q _string_Q _keyword _keyword_Q _list_Q _vector_Q _sub_Q _function_Q
_hash_map _hash_map_Q _atom_Q);
use reader qw(read_str);
sub conj {
my $seq = shift;
- my $new_seq = _clone($seq);
+ my $new_seq = $seq->clone;
if (_list_Q($new_seq)) {
unshift @$new_seq, reverse @_;
} else {
# Metadata functions
sub with_meta {
- my $new_obj = _clone($_[0]);
+ my $new_obj = $_[0]->clone;
$meta{$new_obj} = $_[1];
return $new_obj;
}
use Scalar::Util qw(blessed);
use readline qw(mal_readline set_rl_mode);
-use types qw($nil $true $false _symbol_Q _list_Q _clone);
+use types qw($nil $true $false _symbol_Q _list_Q);
use reader;
use printer;
use env;
# Continue loop (TCO)
}
when ('defmacro!') {
- my $func = _clone(EVAL($a2, $env));
+ my $func = EVAL($a2, $env)->clone;
$func->{ismacro} = 1;
return $env->set($a1, $func);
}
use Scalar::Util qw(blessed);
use readline qw(mal_readline set_rl_mode);
-use types qw($nil $true $false _symbol_Q _list_Q _clone);
+use types qw($nil $true $false _symbol_Q _list_Q);
use reader;
use printer;
use env;
# Continue loop (TCO)
}
when ('defmacro!') {
- my $func = _clone(EVAL($a2, $env));
+ my $func = EVAL($a2, $env)->clone;
$func->{ismacro} = 1;
return $env->set($a1, $func);
}
use Scalar::Util qw(blessed);
use readline qw(mal_readline set_rl_mode);
-use types qw($nil $true $false _symbol_Q _list_Q _clone);
+use types qw($nil $true $false _symbol_Q _list_Q);
use reader;
use printer;
use env;
# Continue loop (TCO)
}
when ('defmacro!') {
- my $func = _clone(EVAL($a2, $env));
+ my $func = EVAL($a2, $env)->clone;
$func->{ismacro} = 1;
return $env->set($a1, $func);
}
use Data::Dumper;
use Exporter 'import';
-our @EXPORT_OK = qw(_sequential_Q _equal_Q _clone
+our @EXPORT_OK = qw(_sequential_Q _equal_Q
$nil $true $false
_number_Q _symbol _symbol_Q _string_Q _keyword _keyword_Q _list_Q _vector_Q _sub_Q _function_Q
_hash_map _hash_map_Q _atom_Q);
return 0;
}
-sub _clone {
- no overloading '%{}';
- my ($obj) = @_;
- if ($obj->isa('Mal::CoreFunction')) {
- return Mal::FunctionRef->new( $obj );
- } else {
- return bless {%{$obj}}, ref $obj;
- }
-}
# Errors/Exceptions
#sub _val { $_[0]->{val}->[$_[1]]->{val}; } # return value of nth item
sub rest { my @arr = @{$_[0]->{val}}; Mal::List->new([@arr[1..$#arr]]); }
sub slice { my @arr = @{$_[0]->{val}}; Mal::List->new([@arr[$_[1]..$_[2]]]); }
+ sub clone { my $self = shift; ref($self)->new([@$self]) }
}
# Lists
package Mal::HashMap;
use parent -norequire, 'Mal::Type';
sub new { my $class = shift; bless $_[0], $class }
+ sub clone { my $self = shift; ref($self)->new({%$self}) }
}
sub _hash_map { Mal::HashMap->new( { pairmap { $$a => $b } @_ } ) }
my $self = $_[0];
return &{ $self->{eval} }($self->{ast}, gen_env($self, $_[1]));
}
+ sub clone { my $self = shift; bless { %$self }, ref($self) }
}
sub _sub_Q { $_[0]->isa('Mal::CoreFunction') || $_[0]->isa('Mal::FunctionRef') }
my ($class, $code) = @_;
bless {'code'=>$code}, $class
}
+ sub clone { my $self = shift; ref($self)->new($self->{code}) }
}
# Core Functions
{
package Mal::CoreFunction;
+ sub clone { my $self = shift; FunctionRef->new($self) }
}
use parent -norequire, 'Mal::Type';
use overload '${}' => sub { \($_[0]->{val}) }, fallback => 1;
sub new { my $class = shift; bless {'val'=>$_[0]}, $class }
+ sub clone { my $self = shift; ref($self)->new($$self) }
}
sub _atom_Q { $_[0]->isa('Mal::Atom') }