Add short notation for lists: '(1 2) == (list 1 2)
This commit is contained in:
parent
b316404b2b
commit
c575115f92
2 changed files with 36 additions and 0 deletions
|
@ -11,6 +11,7 @@ use constant {
|
|||
STRING => 4,
|
||||
NUMBER => 5,
|
||||
KEYWORD => 6,
|
||||
LIST => 7,
|
||||
};
|
||||
|
||||
sub tokenize {
|
||||
|
@ -34,6 +35,10 @@ sub tokenize {
|
|||
{
|
||||
push @tokens, { type => RPAREN };
|
||||
}
|
||||
elsif($str =~ s/^'\(//) # short notation for lists
|
||||
{
|
||||
push @tokens, { type => LIST }, { type => LPAREN };
|
||||
}
|
||||
elsif($str =~ s/^'([^\s()"]+)//)
|
||||
{
|
||||
push @tokens, {
|
||||
|
@ -346,6 +351,10 @@ sub parser_expr {
|
|||
{
|
||||
return parser_call($ts);
|
||||
}
|
||||
elsif($tok->{type} == LIST)
|
||||
{
|
||||
return parser_list($ts);
|
||||
}
|
||||
elsif($tok->{type} == IDENT)
|
||||
{
|
||||
return sub {
|
||||
|
@ -373,6 +382,27 @@ sub parser_expr {
|
|||
}
|
||||
}
|
||||
|
||||
sub parser_list {
|
||||
my $ts = shift;
|
||||
|
||||
my $tok = shift @$ts;
|
||||
die "Missing ( after ' for list" unless $tok->{type} == LPAREN;
|
||||
|
||||
my @elements;
|
||||
while ($ts->[0]->{type} != RPAREN)
|
||||
{
|
||||
push @elements, parser_expr($ts);
|
||||
}
|
||||
|
||||
shift @$ts; # Drop RPAREN
|
||||
|
||||
return sub {
|
||||
my $ctx = shift;
|
||||
|
||||
return [ map { $_->($ctx) } @elements ];
|
||||
}
|
||||
}
|
||||
|
||||
my %macros;
|
||||
|
||||
sub parser_call {
|
||||
|
|
|
@ -28,3 +28,9 @@
|
|||
(= 5 (car lst)))
|
||||
(expect "cdr gives rest of list"
|
||||
(equal (list 1 2) (cdr lst))))
|
||||
|
||||
(expect "short notation equals list created with list function"
|
||||
(equal '(1 2) (list 1 2)))
|
||||
|
||||
(expect "short notation can create empty lists"
|
||||
(zerop (length '())))
|
||||
|
|
Loading…
Reference in a new issue