fork download
  1. (defun lisp-interpreter (expression)
  2. "Простейший интерпретатор Lisp."
  3. (let ((global-environment '()))
  4.  
  5. (labels (
  6. (evaluate (expr env)
  7. (cond
  8. ((numberp expr) expr)
  9. ((symbolp expr) (or (lookup expr env) expr)) ; Ищем значение переменной
  10. ((listp expr)
  11. (let ((function (car expr))
  12. (arguments (cdr expr)))
  13. (apply-function function arguments env)))
  14. (t (error "Неизвестный тип выражения: ~A" expr))))
  15.  
  16. (lookup (symbol env)
  17. (assoc symbol env))
  18.  
  19. (apply-function (function arguments env)
  20. (cond
  21. ((eql function 'quote) (car arguments))
  22. ((eql function 'car) (car (evaluate (car arguments) env)))
  23. ((eql function 'cdr) (cdr (evaluate (car arguments) env)))
  24. ((eql function 'cons) (cons (evaluate (car arguments) env) (evaluate (cadr arguments) env)))
  25. ((eql function '+) (apply '+ (mapcar #'(lambda (arg) (evaluate arg env)) arguments)))
  26. ((eql function '-) (apply '- (mapcar #'(lambda (arg) (evaluate arg env)) arguments)))
  27. ((eql function '*) (apply '* (mapcar #'(lambda (arg) (evaluate arg env)) arguments)))
  28. ((eql function '/) (apply '/ (mapcar #'(lambda (arg) (evaluate arg env)) arguments)))
  29. ((eql function '=) (= (evaluate (car arguments) env) (evaluate (cadr arguments) env)))
  30. ((eql function '<) (< (evaluate (car arguments) env) (evaluate (cadr arguments) env)))
  31. ((eql function '>) (> (evaluate (car arguments) env) (evaluate (cadr arguments) env)))
  32. ((eql function 'list) (mapcar #'(lambda (arg) (evaluate arg env)) arguments)) ; Реализация list
  33. ((eql function 'lambda) ; Лямбда-выражение
  34. (let ((params (cadr function))
  35. (body (caddr function))
  36. (evaluated-args (mapcar #'(lambda (arg) (evaluate arg env)) arguments)))
  37. (evaluate body (append (mapcar #'cons params evaluated-args) env))))
  38. ((eql function 'if)
  39. (if (evaluate (car arguments) env)
  40. (evaluate (cadr arguments) env)
  41. (evaluate (caddr arguments) env))) ; if
  42. ((eql function 'defun)
  43. (let ((name (car arguments))
  44. (params (cadr arguments))
  45. (body (caddr arguments)))
  46. (setf global-environment (acons name `(lambda ,params ,body) global-environment))
  47. name))
  48. ((eql function 'setq)
  49. (let ((symbol (car arguments))
  50. (value (evaluate (cadr arguments) env)))
  51. (setf global-environment (acons symbol value global-environment))
  52. value))
  53. (t ; Пользовательская функция (из глобального окружения)
  54. (let ((func (lookup function global-environment)))
  55. (if func
  56. (apply-function (eval (cdr func)) arguments env); eval убран
  57. (error "Неизвестная функция: ~A" function))))
  58. )))
  59.  
  60. (evaluate expression global-environment))))
  61.  
  62. ;; Примеры использования
  63. (format t "Результат: ~A~%" (lisp-interpreter '(cons (car (cdr (quote (e r t w)))) (cons (cdr (quote (g h 6))) (quote ())))))
  64. (format t "Результат: ~A~%" (lisp-interpreter '(+ 2 (* 3 4))))
  65. (format t "Результат: ~A~%" (lisp-interpreter '(- 10 (/ 6 2))))
  66. (format t "Результат: ~A~%" (lisp-interpreter '(if (> 5 3) 10 20)))
  67. (format t "Результат: ~A~%" (lisp-interpreter '(if (= 5 3) 10 20)))
  68. (format t "Результат: ~A~%" (lisp-interpreter '(car (list 1 2 3))))
Success #stdin #stdout #stderr 0.02s 9604KB
stdin
Standard input is empty
stdout
Результат: (R (H 6))
Результат: 14
Результат: 7
Результат: 10
Результат: 20
Результат: 1
stderr
Warning: reserving address range 0x80000c0000...0x1fffffffffff that contains memory mappings. clisp might crash later!
Memory dump:
  0x8000000000 - 0x80000bffff
  0x154527200000 - 0x1545274e4fff
  0x154527615000 - 0x154527639fff
  0x15452763a000 - 0x1545277acfff
  0x1545277ad000 - 0x1545277f5fff
  0x1545277f6000 - 0x1545277f8fff
  0x1545277f9000 - 0x1545277fbfff
  0x1545277fc000 - 0x1545277fffff
  0x154527800000 - 0x154527802fff
  0x154527803000 - 0x154527a01fff
  0x154527a02000 - 0x154527a02fff
  0x154527a03000 - 0x154527a03fff
  0x154527a80000 - 0x154527a8ffff
  0x154527a90000 - 0x154527ac3fff
  0x154527ac4000 - 0x154527bfafff
  0x154527bfb000 - 0x154527bfbfff
  0x154527bfc000 - 0x154527bfefff
  0x154527bff000 - 0x154527bfffff
  0x154527c00000 - 0x154527c03fff
  0x154527c04000 - 0x154527e03fff
  0x154527e04000 - 0x154527e04fff
  0x154527e05000 - 0x154527e05fff
  0x154527e66000 - 0x154527e69fff
  0x154527e6a000 - 0x154527e6afff
  0x154527e6b000 - 0x154527e6cfff
  0x154527e6d000 - 0x154527e6dfff
  0x154527e6e000 - 0x154527e6efff
  0x154527e6f000 - 0x154527e6ffff
  0x154527e70000 - 0x154527e7dfff
  0x154527e7e000 - 0x154527e8bfff
  0x154527e8c000 - 0x154527e98fff
  0x154527e99000 - 0x154527e9cfff
  0x154527e9d000 - 0x154527e9dfff
  0x154527e9e000 - 0x154527e9efff
  0x154527e9f000 - 0x154527ea4fff
  0x154527ea5000 - 0x154527ea6fff
  0x154527ea7000 - 0x154527ea7fff
  0x154527ea8000 - 0x154527ea8fff
  0x154527ea9000 - 0x154527ea9fff
  0x154527eaa000 - 0x154527ed7fff
  0x154527ed8000 - 0x154527ee6fff
  0x154527ee7000 - 0x154527f8cfff
  0x154527f8d000 - 0x154528023fff
  0x154528024000 - 0x154528024fff
  0x154528025000 - 0x154528025fff
  0x154528026000 - 0x154528039fff
  0x15452803a000 - 0x154528061fff
  0x154528062000 - 0x15452806bfff
  0x15452806c000 - 0x15452806dfff
  0x15452806e000 - 0x154528073fff
  0x154528074000 - 0x154528076fff
  0x154528079000 - 0x154528079fff
  0x15452807a000 - 0x15452807afff
  0x15452807b000 - 0x15452807bfff
  0x15452807c000 - 0x15452807cfff
  0x15452807d000 - 0x15452807dfff
  0x15452807e000 - 0x154528084fff
  0x154528085000 - 0x154528087fff
  0x154528088000 - 0x154528088fff
  0x154528089000 - 0x1545280a9fff
  0x1545280aa000 - 0x1545280b1fff
  0x1545280b2000 - 0x1545280b2fff
  0x1545280b3000 - 0x1545280b3fff
  0x1545280b4000 - 0x1545280b4fff
  0x5579d3378000 - 0x5579d3468fff
  0x5579d3469000 - 0x5579d3572fff
  0x5579d3573000 - 0x5579d35d2fff
  0x5579d35d4000 - 0x5579d3602fff
  0x5579d3603000 - 0x5579d3633fff
  0x5579d3634000 - 0x5579d3637fff
  0x5579d40ee000 - 0x5579d410efff
  0x7ffc530ac000 - 0x7ffc530ccfff
  0x7ffc530e1000 - 0x7ffc530e4fff
  0x7ffc530e5000 - 0x7ffc530e6fff