Reputation: 545
I am trying to write a lisp interpreter using only lisp primitive functions. I was writing my eval but I am not sure how I can detect the ' so I don't evaluate the symbol. I understand that 'x is converted to (quote x) internally, I fired up a lisp interpreter and tried the following:
(defun my-car (x) (car x))
(my-car (quote x)) -> QUOTE
(my-car '(x)) -> QUOTE
(my-car 'x) -> Error: Attempt to take the car of A which is not listp.
I see that in the first two examples car detects the quote as being the first element and returns it, I am not sure why it doesn't do that in the last example though since essentially 'x should be converted to (quote x) then passed as an argument to my-car. I need to check for this for one of the base cases of my-eval so that if a quote precedes an atom I don't return its value. Is there a way to do that using only primitive functions?
Thanks!
Upvotes: 1
Views: 221
Reputation: 4360
Your lisp interpreter is not behaving like Common Lisp. You should get:
(defun my-car (x) (car x))
(my-car (quote x)) -> Error: Attempt to take the car of A which is not listp.
(my-car '(x)) -> X
(my-car 'x) -> Error: Attempt to take the car of A which is not listp.
(my-car (list 'QUOTE 'X)) -> QUOTE
(my-car ''x) -> QUOTE
(my-car (quote 'x)) -> QUOTE
(my-car '(quote x)) -> QUOTE
Step by step:
Source code:
(my-car ''x)
Parse:
(my-car (quote (quote x)))
Evaluate arguments
(#<Function MY-CAR> (quote x))
Call function:
X
This I because the car of the list of the symbol QUOTE
and symbol X
is QUOTE
.
Upvotes: 1
Reputation: 51501
Lisp evaluation happens in stages.
The first stage is the reader, which converts the text (sequence of characters) to forms, i. e. lists, symbols, and literal forms (characters, strings, numbers, arrays etc.).
The reader also converts '
to a wrapped quote form around the following form (which may be a list, a symbol, etc.). 'a
is read as (quote a)
, '(a)
is read as (quote (a))
.
Eval
then only needs a rule how to handle quote
as an operator. It never sees any '
.
Upvotes: 2