Пакет с общим языком и инфиксом - PullRequest
0 голосов
/ 06 мая 2018

Существует инфиксный пакет для общего lisp (см. http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/infix/infix.cl),, который преобразует инфиксную форму в префикс.

Например:

(string->prefix "1+2") ;; => (+ 1 2)

Он также предоставляет макрос для чтения #I, который может оценивать инфиксную форму, например,

#I(1+2) ;; => 3

Но я не хочу использовать этот макрос для чтения.

Я написал простую функцию, которая использует cl-ppcre, чтобы заменить строку числом, т. Е.

(prepare-form "1+x*x" "x" 3) ;; => "1+3*3"

Наконец, у меня есть функция, которая оценивает инфиксную форму

(defun eval-infix (form &rest args)
  (eval (string->prefix (apply #'prepare-form form args))))

Может ли функция eval-infix быть реализована без использования функции eval? Моя конечная цель - вызвать eval-infix так:

(eval-infix "1+x*x" "x" (+ 1 2))

1 Ответ

0 голосов
/ 09 мая 2018

Ну, я думаю, что вы хотите использовать string->prefix. Это будет интернировать символы, поэтому, чтобы избежать загрязнения вашего собственного пакета, давайте определим его. Наконец, вы можете избежать проблем безопасности eval, определив свой собственный eval. Есть еще проблема, где символы из других пакетов могут быть написаны, и это меня огорчает. Существует также проблема, заключающаяся в том, что читатель инфикса может перейти к считывателю Lisp, который может выполнить произвольную оценку. Вот эскиз частей решения. Возможно, я получил аргументы для некоторых функций в неправильном порядке.

(defpackage infix-vars)
(defun read-infix-string (s) (let ((*package* (find-package "INFIX-VARS"))) (string->prefix s)))
(defun substitute-var (expr v val)
   (let ((v (etypecase v (symbol v) (string (intern v (find-package "INFIX-VARS"))))))
    (subst expr v val)))
(defun eval-expr (e)
  (etypecase e
    (number e)
    (list
      (ecase (car e)
        (+ (apply #'+ (mapcar #'eval-expr (cdr e))))))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...