Implementing your own Lisp
Implementing your own Lisp dialect is a cool exercise! And it's fun to see many deep recursion warnings in the "run-a-lisp-that-is-written-in-lisp-that-runs-itself" test.
Some examples from the PerLisp shell
(bind to-ten '(1 2 3 4 5 6 7 8 9 10))
(1 2 3 4 5 6 7 8 9 10)
(define (add-1 x) (+ x 1))
Function: (x) -> (+ x 1)
(map add-1 to-ten)
(2 3 4 5 6 7 8 9 10 11)
(filter (lambda (n) (= (% n 2) 0)) to-ten)
(2 4 6 8 10)
(define (sum l) (reduce + l 0))
Function: (l) -> (reduce + l 0)
(sum '(1 -1))
0
(sum to-ten)
55
(define (product l) (reduce * l 1))
Function: (l) -> (reduce * l 1)
(product '(6 7))
42
(product to-ten)
3628800
Code snippets
The eval
method of my PerLisp class. I think it's pretty straightforward: it transforms an input string to a stream of tokens which will be parsed into a list of expressions. All expressions have to implement an eval
method that could depend on the surrounding context. The method's return value is the resulting list of values or (in scalar context) the first value:
sub eval {
my ($self, $string) = @_;
# lex
my $token_stream = $self->lexer->lex($string);
# parse
my @exprs = $self->parser->parse($token_stream);
# eval
my @values = map { $_->eval($self->context) } @exprs;
# return
return wantarray ? @values : shift @values;
}
A symbol expression for example looks itself up in the given context:
sub eval {
my ($self, $context) = @_;
return $context->get($self->name);
}
Written by Mirko Westermeier
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Perl
Authors
janosgyerik
25.11K
Jean-Remy Duboc
12.22K
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#