A simple Lisp program
Posted: Mon Dec 27, 2010 8:59 am
So i'm writing a simple LISP program to interpret statements, for example in the form: ((interpret-program '(read x) (write x) '(21))
But i can't get any meaningful output, so i can't figure out what's going wrong. I'm completely new to functional languages; Though i've done plenty of reading, and can use the statements properly on their own, writing a program has been a huge hardship. Can anyone provide some useful tips, pointers, even (another) tutorial (i've read 2 from end to end). Thanks in advance. Here's the code i've worked through so far:
But i can't get any meaningful output, so i can't figure out what's going wrong. I'm completely new to functional languages; Though i've done plenty of reading, and can use the statements properly on their own, writing a program has been a huge hardship. Can anyone provide some useful tips, pointers, even (another) tutorial (i've read 2 from end to end). Thanks in advance. Here's the code i've worked through so far:
Code: Select all
; main function creates state containing supplied input and empty
; memory and output, returns output
(defun interpret-program (program input)
(third (interpret-statement-list program (list '(()) input nil))))
; interprets a single statement if statement-list is a single statement
; recursively interprets all statements if it is a list
(defun interpret-statement-list (statement-list state)
(cond
((null statement-list) state)
((atom (first statement-list))
(interpret-statement statement-list state))
(t (interpret-statement-list (rest statement-list)
(interpret-statement (first statement-list) state)))))
; determines the type of statement based on the first word
; and calls the appropriate function to interpret it
(defun interpret-statement (statement state)
(cond
((eq (first statement) 'assign)
(interpret-assignment-statement (second statement)
(fourth statement) state))
((eq (first statement) 'write)
(interpret-write-statement (second statement) state))
((eq (first statement) 'read)
(interpret-read-statement (second statement) state)))
((eq (first statement) 'if)
(interpret-if-statement (second statement) state))
((eq (first statement) 'while)
(interpret-while-statement (second statement) state)))
; interprets the write statement by evaluating the expression
; and appending its value to the output stream
(defun interpret-write-statement (write-expression state)
(let
((memory (first state))
(input (second state))
(output (third state)))
(list memory input (append output
(list (evaluate-expression write-expression state))))))
;interprets the read statement by removing the first item from the list
; and putting it into a variable.
(defun interpret-read-statement (read-expression state)
(let
((memory (first state))
(input (second state)
(output (third state))
(set-value (memory) (input) (output))
(list (evaluate-expression read-expression state)))))
; interprets the assignment statement by evaluating the expression
; and assigning the value to the specified variable
(defun interpret-assignment-statement (variable expression state)
(let
((memory (first state))
(input (second state))
(output (third state)))
(list (set-value memory variable
(evaluate-expression expression state)) input output)))
; evaluates an expression by checking whether it is a literal, a
; variable, a binary or unary expression
(defun evaluate-expression (expression state)
(cond
((numberp expression) expression)
((atom expression) (get-value (first state) expression))
((eq (length expression) 3)
(evaluate-binary-expression expression state))))
; evaluates a binary expression by first evaluating the subexpressions
; and then applying the operator to those subexpressions
(defun evaluate-binary-expression (expression state)
(let
((left-operand (evaluate-expression (first expression) state))
(operator (second expression))
(right-operand (evaluate-expression (third expression) state)))
(apply operator (list left-operand right-operand))))
; adds the variable-value pair to the head of the association list
; that comprises the current state of the memory. Previous
; occurences of that variable are not removed.
(defun set-value (memory variable value)
(cons (list variable value) memory))
; retrieves the value of a variable from the association list
; that comprises the current state of the memory
(defun get-value (memory variable)
(second (assoc variable memory)))
;handles if statements
;if the expression is null, then its false, so skip it
;if the expression is true, then we do whatever is in state
;the final statement must evaluate to true
(defun interpret-if-statement (expression state)
(cond
((null statement-list) state)
(expression (statement-list) state)
((t first state))
;handles while statements. all it does is evaluate. If its true, we've reached the condition
;and so we stop. Otherwise, recursively evaluate itself again, until we reach a false value. Uses
;simple tail recursion.
(defun interpret-if-statement (expression state)
(cond
((null statement-list) state)
(expression state)
(interpret-if-statement(expression state))
(expression (statement-list) state)