我是 LISP 编程的新手,现在是学期末,我们的老师要求我们做这个项目,我一直在努力完成它,但我被卡住了,所以任何帮助都将不胜感激。项目是eval (expr)
在 Lisp 中编写一个函数来覆盖已经存在的函数。这是详细信息:
项目描述:以空格分隔的算术表达式中的项目;
; Input:
; 1. The form of arithmetic expression given in prefix notation like LISP
; Assumptions:
; 1. binary operations for +, -, *, and /
; 2. integer division, no reals
; 3. an arithmetic expression occupies only one line
; 4. nested arithmetic expressions permitted
; 5. all given inputs are syntax correct
; 6. no need for error handling
我写了一个可以对简单算术表达式进行评估的代码,它可以工作!!但我不能让它在嵌套算术运算上工作。我想我的递归部分有问题,我做错了什么,但它到底是什么 idk :(
这是我的代码:
; Assign a character string to a global variable input-prompt
; treat input-prompt as a constant global variable
(setf input-prompt "Please input an arithmetic expression: ")
(setf output-prompt "The value is: ")
(defun prompt-for-input (msg)
(format t msg)
(format t "~%")) ; ~% new line
(defun prompt-for-output (msg)
(format t msg))
(defun output-msg (result)
(format t "~S" result) ; ~S takes the result into the print message
(format t "~%"))
(defun eval (expr)
(print "My EVAL Function is Working *_*")
(if (numberp expr) expr)
(cond
((eq (car expr) '+)
(if (and (numberp (cadr expr))
(numberp (caddr expr))) ;to check if we have simple expression
(+ (cadr expr) (caddr expr)) ;in case both are numbers we add normally
(if (not (numberp (cadr expr)))
;in case the second argument is not number
;we need to call eval again to check the expression
((eval (cadr exp)))
(if (not (numberp (caddr expr)))
;in case the third argument is not a number
;we need to call eval again to check the expression
((eval (caddr exp)))
(0)))))
((eq (car expr) '-)
(if (and (numberp (cadr expr))
(numberp (caddr expr))) ;to check if we have simple expression
(- (cadr expr) (caddr expr)) ;in case both are numbers we add normally
(if (not (numberp (cadr expr)))
;in case the second argument is not number
;we need to call eval again to check the expression
((eval (cadr exp)))
(if (not (numberp (caddr expr)))
;in case the third argument is not a number
;we need to call eval again to check the expression
((eval (caddr exp)))
(0)))))
((eq (car expr) '*)
(if (and (numberp (cadr expr))
(numberp (caddr expr))) ;to check if we have simple expression
(* (cadr expr) (caddr expr)) ;in case both are numbers we add normally
(if (not (numberp (cadr expr)))
;in case the second argument is not number
;we need to call eval again to check the expression
((eval (cadr exp)))
(if (not (numberp (caddr expr)))
;in case the third argument is not a number
;we need to call eval again to check the expression
((eval (caddr exp)))
(0)))))
((eq (car expr) '/)
(if (and (numberp (cadr expr))
(numberp (caddr expr))) ;to check if we have simple expression
(/ (cadr expr) (caddr expr)) ;in case both are numbers we add normally
(if (not (numberp (cadr expr)))
;in case the second argument is not number
;we need to call eval again to check the expression
((eval (cadr exp)))
(if (not (numberp (caddr expr)))
;in case the third argument is not a number
;we need to call eval again to check the expression
((eval (caddr exp)))
(0)))))))
; it should have eval(expr) function which returns the value of the
; arithmetic expression
; for instance,
; (+ 2 3) outputs 5
; (+ (* 3 2) (/ 4 2))) outputs 8
; (* (- 2 3) 5) outputs -5
; driver accepts the input arithmetic expression
; evaluate the arithmetic expression
; output the reulst of the evaluation of the arithmetic expression
; execution is in the loop; to exit the loop; type cntrl-c
(defun driver ()
(prompt-for-input input-prompt)
;to print "Please input an arithmetic expression
(let ((expression (read)))
(output-msg expression)
(let ((result (eval expression)))
(prompt-for-output output-prompt)
(output-msg result)))
(driver))