Я новичок в программировании на LISP, и это конец семестра, и наш учитель попросил нас сделать этот проект, и я пытался его сделать, но я застрял, поэтому любая помощь будет оценена по достоинству. Проект состоит в том, чтобы написать eval (expr)
функцию на Лиспе, чтобы перезаписать уже существующую функцию. вот подробности:
Описание проекта: элементы в арифметическом выражении, разделенные пробелами;
; 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))