From b316404b2bba864524dc202de8353391438217a5 Mon Sep 17 00:00:00 2001 From: MadMaurice Date: Sat, 3 Apr 2021 18:05:59 +0200 Subject: [PATCH] Add cons, car, cdr --- lib/Minilisp.pm | 15 ++++++++++++++- t/lists.t | 12 ++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/Minilisp.pm b/lib/Minilisp.pm index 52c5da8..9c29af1 100644 --- a/lib/Minilisp.pm +++ b/lib/Minilisp.pm @@ -285,7 +285,20 @@ my %stdctx = ( $v = $cb->($v,$_) foreach (@copy); return $v; }, - # TODO: this is tricky as it needs to recurse into sub lists + 'cons' => sub { + my ($v, $list) = @_; + return [ $v, @$list ]; + }, + 'car' => sub { + my ($list) = @_; + return $list->[0]; + }, + 'cdr' => sub { + my ($list) = @_; + my @newlist = @$list; + shift @newlist; # drop first element + return \@newlist; + }, # Constants 't' => 1, diff --git a/t/lists.t b/t/lists.t index 6835252..806115d 100644 --- a/t/lists.t +++ b/t/lists.t @@ -16,3 +16,15 @@ (expect "equal tests recursively 2" (not (equal (list (list 1) (list 2)) (list (list 1) (list 3))))) + +(expect "Length of empty list is 0" + (zerop (length (list)))) + +(expect "cons adds elements to the front" + (equal (list 1 2) (cons 1 (list 2)))) + +(let ((lst (list 5 1 2))) + (expect "car gives first element" + (= 5 (car lst))) + (expect "cdr gives rest of list" + (equal (list 1 2) (cdr lst))))