7e0c96d1a497c7de9ec4427d8f35e27ee762229f
3 use warnings FATAL
=> qw(all);
4 use Time
::HiRes
qw(time);
7 use types
qw(_sequential_Q _equal_Q _clone $nil $true $false
8 _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 _atom_Q);
11 use reader qw(read_str);
12 use printer
qw(_pr_str);
19 return String
->new(join(" ", map {_pr_str
($_, 1)} @_));
23 return String
->new(join("", map {_pr_str
($_, 0)} @_));
27 print join(" ", map {_pr_str
($_, 1)} @_) . "\n";
32 print join(" ", map {_pr_str
($_, 0)} @_) . "\n";
37 my $line = readline::mal_readline
(${$_[0]});
38 return defined $line ? String
->new($line) : $nil;
43 open(my $fh, '<', $fname) or die "error opening '$fname'";
44 my $data = do { local $/; <$fh> };
52 my $new_hsh = { %$src_hsh };
53 return _assoc_BANG
($new_hsh, @_);
57 my $new_hsh = { %{shift @_} };
58 delete @
{$new_hsh}{map $$_, @_};
59 return HashMap
->new($new_hsh);
65 return $hsh->{$$key} || $nil;
70 return (exists $hsh->{$$key}) ?
$true : $false;
74 my @ks = map { String
->new($_) } keys %{$_[0]};
75 return List
->new(\
@ks);
79 my @vs = values %{$_[0]};
80 return List
->new(\
@vs);
92 List
->new([map @
$_, @_]);
97 return $seq->[$i] || die "nth: index out of bounds";
102 return $seq->[0] || $nil;
105 sub rest
{ return $_[0]->rest(); }
108 return Integer
->new(scalar(@
{$_[0]}))
114 return &$f(@_, @
$more_args);
119 my @arr = map { &$f($_) } @
{$_[0]};
120 return List
->new(\
@arr);
125 my $new_seq = _clone
($seq);
126 if (_list_Q
($new_seq)) {
127 unshift @
$new_seq, reverse @_;
138 } elsif (_list_Q
($arg)) {
139 return $nil unless @
$arg;
141 } elsif (_vector_Q
($arg)) {
142 return $nil unless @
$arg;
143 return List
->new([@
$arg]);
144 } elsif (_string_Q
($arg)) {
145 return $nil if length($$arg) == 0;
146 my @chars = map { String
->new($_) } split(//, $$arg);
147 return List
->new(\
@chars);
149 die "seq requires list or vector or string or nil";
155 no overloading
'%{}';
156 my $new_obj = _clone
($_[0]);
157 $new_obj->{meta
} = $_[1];
168 my ($atm,$f,@args) = @_;
169 unshift @args, $$atm;
170 return $$atm = &$f(@args);
176 '=' => sub { _equal_Q
($_[0], $_[1]) ?
$true : $false },
177 'throw' => sub { die $_[0] },
178 'nil?' => sub { _nil_Q
($_[0]) ?
$true : $false },
179 'true?' => sub { _true_Q
($_[0]) ?
$true : $false },
180 'false?' => sub { _false_Q
($_[0]) ?
$true : $false },
181 'number?' => sub { _number_Q
($_[0]) ?
$true : $false },
182 'symbol' => sub { Symbol
->new(${$_[0]}) },
183 'symbol?' => sub { _symbol_Q
($_[0]) ?
$true : $false },
184 'string?' => sub { _string_Q
($_[0]) ?
$true : $false },
185 'keyword' => sub { _keyword
(${$_[0]}) },
186 'keyword?' => sub { _keyword_Q
($_[0]) ?
$true : $false },
187 'fn?' => sub { (_sub_Q
($_[0]) || (_function_Q
($_[0]) && !$_[0]->{ismacro
})) ?
$true : $false },
188 'macro?' => sub { (_function_Q
($_[0]) && $_[0]->{ismacro
}) ?
$true : $false },
190 'pr-str' => \
&pr_str
,
193 'println' => \
&println
,
194 'readline' => \
&mal_readline
,
195 'read-string' => sub { read_str
(${$_[0]}) },
197 '<' => sub { ${$_[0]} < ${$_[1]} ?
$true : $false },
198 '<=' => sub { ${$_[0]} <= ${$_[1]} ?
$true : $false },
199 '>' => sub { ${$_[0]} > ${$_[1]} ?
$true : $false },
200 '>=' => sub { ${$_[0]} >= ${$_[1]} ?
$true : $false },
201 '+' => sub { Integer
->new(${$_[0]} + ${$_[1]}) },
202 '-' => sub { Integer
->new(${$_[0]} - ${$_[1]}) },
203 '*' => sub { Integer
->new(${$_[0]} * ${$_[1]}) },
204 '/' => sub { Integer
->new(${$_[0]} / ${$_[1]}) },
205 'time-ms' => sub { Integer
->new(int(time()*1000)) },
207 'list' => sub { List
->new(\
@_) },
208 'list?' => sub { _list_Q
($_[0]) ?
$true : $false },
209 'vector' => sub { Vector
->new(\
@_) },
210 'vector?' => sub { _vector_Q
($_[0]) ?
$true : $false },
211 'hash-map' => \
&_hash_map
,
212 'map?' => sub { _hash_map_Q
($_[0]) ?
$true : $false },
214 'dissoc' => \
&dissoc
,
216 'contains?' => \
&contains_Q
,
217 'keys' => \
&mal_keys
,
218 'vals' => \
&mal_vals
,
220 'sequential?' => sub { _sequential_Q
($_[0]) ?
$true : $false },
221 'nth' => sub { nth
($_[0], ${$_[1]}) },
225 'concat' => \
&concat
,
226 'empty?' => sub { @
{$_[0]} ?
$false : $true },
233 'with-meta' => \
&with_meta
,
235 'atom' => sub { Atom
->new($_[0]) },
236 'atom?' => sub { _atom_Q
($_[0]) ?
$true : $false },
237 'deref' => sub { ${$_[0]} },
238 'reset!' => sub { ${$_[0]} = $_[1] },
239 'swap!' => \
&swap_BANG
,
242 foreach my $f (values %core::ns
) {
243 bless $f, 'CoreFunction';