Initial commit
[data-sexpression-util.git] / lib / Data / SExpression / Util.pm
CommitLineData
45be15da
MG
1package Data::SExpression::Util;
2
3use 5.014000;
4use strict;
5use warnings;
6use parent qw/Exporter/;
7
8our %EXPORT_TAGS = ( 'all' => [
9 qw/cons
10 append
11 mapcar
12 rev
13 position
14 /]);
15
16our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
17
18our $VERSION = '0.000_001';
19
20use Data::SExpression::Cons;
21
22sub cons {
23 my ($car, $cdr) = @_;
24 Data::SExpression::Cons->new($car, $cdr);
25}
26
27sub append {
28 my ($expr, $rest) = @_;
29 if (defined $expr) {
30 cons $expr->car, append($expr->cdr, $rest)
31 } else {
32 $rest
33 }
34}
35
36sub mapcar (&@);
37
38sub mapcar (&@) {
39 my ($block, $expr) = @_;
40 if (defined $expr) {
41 my $result;
42 do {
43 local $_ = $expr->car;
44 $result = $block->()
45 };
46 cons $result, mapcar { $block->($_) } $expr->cdr
47 } else {
48 undef
49 }
50}
51
52sub revacc {
53 my ($expr, $acc) = @_;
54 if (defined $expr) {
55 revacc ($expr->cdr, cons($expr->car, $acc))
56 } else {
57 $acc
58 }
59}
60
61sub rev {
62 my ($expr) = @_;
63 revacc $expr, undef;
64}
65
66sub positionacc {
67 my ($expr, $list, $acc) = @_;
68 if (!defined $list) {
69 undef
70 } elsif ($list->car eq $expr) {
71 $acc
72 } else {
73 positionacc($expr, $list->cdr, $acc + 1)
74 }
75}
76
77sub position {
78 my ($expr, $list) = @_;
79 positionacc $expr, $list, 0
80}
81
821;
83__END__
84
85=encoding utf-8
86
87=head1 NAME
88
89Data::SExpression::Util - routines for processing linked lists
90
91=head1 SYNOPSIS
92
93 use Data::SExpression::Util qw/:all/;
94 my $list = cons 1, cons 2, cons 3, undef; # (1 2 3)
95 my $other_list = cons 4, cons 5, undef; # (4 5)
96
97 $list = append $list, $other_list; # $list is now (1 2 3 4 5)
98
99 say position 1, $list; # 0
100 say position 4, $list; # 3
101 say 'undef' unless defined position 0, $list; # undef
102
103 $list = rev $list; # (5 4 3 2 1)
104 $list = mapcar { $_ + 1 } $list; # (6 5 4 3 2)
105
106 say position 2, $list; # 4
107
108=head1 DESCRIPTION
109
110Data::SExpression::Util contains several routines for processing
111linked lists (represented L<Data::SExpression::Cons> objects). These
112are analogous to Lisp functions with the same names.
113
114Right now very few functions are implemented, more will come in the
115next version.
116
117The list of functions is:
118
119=over
120
121=item B<append>(I<$list>, I<$other_list>)
122
123Appends the list I<$other_list> at the end of the list I<$list>.
124
125=item B<mapcar> { I<block> } I<$list>
126
127Analogous to Perl's map function. Runs I<block> with each element of
128the list I<$list> as $_, and then returns a containing all of the
129result.
130
131=item B<rev>(I<$list>)
132
133Reverses a list
134
135=item B<position>(I<$elt>, I<$list>)
136
137Searches for I<$elt> in I<$list> and returns the first matching
138element (comparison is done via eq).
139
140=back
141
142=head1 AUTHOR
143
144Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
145
146=head1 COPYRIGHT AND LICENSE
147
148Copyright (C) 2018 by Marius Gavrilescu
149
150This library is free software; you can redistribute it and/or modify
151it under the same terms as Perl itself, either Perl version 5.24.1 or,
152at your option, any later version of Perl 5 you may have available.
153
154
155=cut
This page took 0.020019 seconds and 4 git commands to generate.